llvm/clang/lib/Sema/CheckExprLifetime.cpp

//===--- CheckExprLifetime.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "CheckExprLifetime.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Sema.h"
#include "llvm/ADT/PointerIntPair.h"

namespace clang::sema {
namespace {
enum LifetimeKind {};
LifetimeResult;
} // namespace

/// Determine the declaration which an initialized entity ultimately refers to,
/// for the purpose of lifetime-extending a temporary bound to a reference in
/// the initialization of \p Entity.
static LifetimeResult
getEntityLifetime(const InitializedEntity *Entity,
                  const InitializedEntity *InitField = nullptr) {}

namespace {
enum ReferenceKind {};

/// A temporary or local variable. This will be one of:
///  * A MaterializeTemporaryExpr.
///  * A DeclRefExpr whose declaration is a local.
///  * An AddrLabelExpr.
///  * A BlockExpr for a block with captures.
Local;

/// Expressions we stepped over when looking for the local state. Any steps
/// that would inhibit lifetime extension or take us out of subexpressions of
/// the initializer are included.
struct IndirectLocalPathEntry {};

IndirectLocalPath;

struct RevertToOldSizeRAII {};

LocalVisitor;
} // namespace

static bool isVarOnPath(IndirectLocalPath &Path, VarDecl *VD) {}

static bool pathContainsInit(IndirectLocalPath &Path) {}

static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
                                             Expr *Init, LocalVisitor Visit,
                                             bool RevisitSubinits);

static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
                                                  Expr *Init, ReferenceKind RK,
                                                  LocalVisitor Visit);

template <typename T> static bool isRecordWithAttr(QualType Type) {}

// Decl::isInStdNamespace will return false for iterators in some STL
// implementations due to them being defined in a namespace outside of the std
// namespace.
static bool isInStlNamespace(const Decl *D) {}

static bool isPointerLikeType(QualType Type) {}

// Returns true if the given Record decl is a form of `GSLOwner<Pointer>`
// type, e.g. std::vector<string_view>, std::optional<string_view>.
static bool isContainerOfPointer(const RecordDecl *Container) {}
static bool isContainerOfOwner(const RecordDecl *Container) {}

// Returns true if the given Record is `std::initializer_list<pointer>`.
static bool isStdInitializerListOfPointer(const RecordDecl *RD) {}

static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {}

static bool shouldTrackFirstArgument(const FunctionDecl *FD) {}

// Returns true if the given constructor is a copy-like constructor, such as
// `Ctor(Owner<U>&&)` or `Ctor(const Owner<U>&)`.
static bool isCopyLikeConstructor(const CXXConstructorDecl *Ctor) {}

// Returns true if we should perform the GSL analysis on the first argument for
// the given constructor.
static bool
shouldTrackFirstArgumentForConstructor(const CXXConstructExpr *Ctor) {}

// Return true if this is an "normal" assignment operator.
// We assuments that a normal assingment operator always returns *this, that is,
// an lvalue reference that is the same type as the implicit object parameter
// (or the LHS for a non-member operator$=).
static bool isNormalAssignmentOperator(const FunctionDecl *FD) {}

static bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) {}

// Visit lifetimebound or gsl-pointer arguments.
static void visitFunctionCallArguments(IndirectLocalPath &Path, Expr *Call,
                                       LocalVisitor Visit) {}

/// Visit the locals that would be reachable through a reference bound to the
/// glvalue expression \c Init.
static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
                                                  Expr *Init, ReferenceKind RK,
                                                  LocalVisitor Visit) {}

/// Visit the locals that would be reachable through an object initialized by
/// the prvalue expression \c Init.
static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
                                             Expr *Init, LocalVisitor Visit,
                                             bool RevisitSubinits) {}

/// Whether a path to an object supports lifetime extension.
enum PathLifetimeKind {};

/// Determine whether this is an indirect path to a temporary that we are
/// supposed to lifetime-extend along.
static PathLifetimeKind
shouldLifetimeExtendThroughPath(const IndirectLocalPath &Path) {}

/// Find the range for the first interesting entry in the path at or after I.
static SourceRange nextPathEntryRange(const IndirectLocalPath &Path, unsigned I,
                                      Expr *E) {}

static bool pathOnlyHandlesGslPointer(IndirectLocalPath &Path) {}

static bool isAssignmentOperatorLifetimeBound(CXXMethodDecl *CMD) {}

static bool shouldRunGSLAssignmentAnalysis(const Sema &SemaRef,
                                           const AssignedEntity &Entity) {}

static void checkExprLifetimeImpl(Sema &SemaRef,
                                  const InitializedEntity *InitEntity,
                                  const InitializedEntity *ExtendingEntity,
                                  LifetimeKind LK,
                                  const AssignedEntity *AEntity, Expr *Init) {}

void checkExprLifetime(Sema &SemaRef, const InitializedEntity &Entity,
                       Expr *Init) {}

void checkExprLifetimeMustTailArg(Sema &SemaRef,
                                  const InitializedEntity &Entity, Expr *Init) {}

void checkExprLifetime(Sema &SemaRef, const AssignedEntity &Entity,
                       Expr *Init) {}

} // namespace clang::sema