[llvm-branch-commits] [clang] [Clang] Extend lifetime bound analysis to support assignments (PR #96475)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jun 26 05:42:30 PDT 2024


github-actions[bot] wrote:

<!--LLVM CODE FORMAT COMMENT: {clang-format}-->


:warning: C/C++ code formatter, clang-format found issues in your code. :warning:

<details>
<summary>
You can test this locally with the following command:
</summary>

``````````bash
git-clang-format --diff 2b5d1fb889fca7287858db0791bfecc1465f23e1 43ffbc27fe7d128586b54dbd33fd676532233032 --extensions 'c,cpp,h' -- clang/lib/Sema/CheckExprLifetime.cpp clang/lib/Sema/CheckExprLifetime.h clang/lib/Sema/SemaExpr.cpp clang/lib/Sema/SemaInit.cpp clang/test/Parser/compound_literal.c clang/test/SemaCXX/attr-lifetimebound.cpp clang/test/SemaCXX/warn-dangling-local.cpp
``````````

</details>

<details>
<summary>
View the diff from clang-format here.
</summary>

``````````diff
diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp
index 73b3fd2d3a..bbca1b209f 100644
--- a/clang/lib/Sema/CheckExprLifetime.cpp
+++ b/clang/lib/Sema/CheckExprLifetime.cpp
@@ -42,21 +42,20 @@ enum LifetimeKind {
 };
 using LifetimeResult =
     llvm::PointerIntPair<const InitializedEntity *, 3, LifetimeKind>;
-}
+} // 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) {
+static LifetimeResult
+getEntityLifetime(const InitializedEntity *Entity,
+                  const InitializedEntity *InitField = nullptr) {
   // C++11 [class.temporary]p5:
   switch (Entity->getKind()) {
   case InitializedEntity::EK_Variable:
     //   The temporary [...] persists for the lifetime of the reference
     return {Entity, LK_Extended};
 
-
   case InitializedEntity::EK_Member:
     // For subobjects, we look at the complete object.
     if (Entity->getParent())
@@ -90,7 +89,8 @@ static LifetimeResult getEntityLifetime(
     return {nullptr, LK_FullExpression};
 
   case InitializedEntity::EK_TemplateParameter:
-    // FIXME: This will always be ill-formed; should we eagerly diagnose it here?
+    // FIXME: This will always be ill-formed; should we eagerly diagnose it
+    // here?
     return {nullptr, LK_FullExpression};
 
   case InitializedEntity::EK_Result:
@@ -171,7 +171,7 @@ enum ReferenceKind {
 ///  * A DeclRefExpr whose declaration is a local.
 ///  * An AddrLabelExpr.
 ///  * A BlockExpr for a block with captures.
-using Local = Expr*;
+using Local = Expr *;
 
 /// Expressions we stepped over when looking for the local state. Any steps
 /// that would inhibit lifetime extension or take us out of subexpressions of
@@ -359,9 +359,9 @@ static void handleGslAnnotatedTypes(IndirectLocalPath &Path, Expr *Call,
   } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(Call)) {
     FunctionDecl *Callee = OCE->getDirectCallee();
     if (Callee && Callee->isCXXInstanceMember() &&
-        shouldTrackImplicitObjectArg(cast<CXXMethodDecl>(Callee))) 
+        shouldTrackImplicitObjectArg(cast<CXXMethodDecl>(Callee)))
       VisitPointerArg(Callee, OCE->getArg(0),
-                      !Callee->getReturnType()->isReferenceType()); 
+                      !Callee->getReturnType()->isReferenceType());
     return;
   } else if (auto *CE = dyn_cast<CallExpr>(Call)) {
     FunctionDecl *Callee = CE->getDirectCallee();
@@ -419,7 +419,7 @@ static bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) {
 static void visitLifetimeBoundArguments(IndirectLocalPath &Path, Expr *Call,
                                         LocalVisitor Visit) {
   const FunctionDecl *Callee;
-  ArrayRef<Expr*> Args;
+  ArrayRef<Expr *> Args;
 
   if (auto *CE = dyn_cast<CallExpr>(Call)) {
     Callee = CE->getDirectCallee();
@@ -610,7 +610,7 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path,
     break;
   }
 
-  // FIXME: Visit the left-hand side of an -> or ->*.
+    // FIXME: Visit the left-hand side of an -> or ->*.
 
   default:
     break;
@@ -632,7 +632,8 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
     // Step into CXXDefaultInitExprs so we can diagnose cases where a
     // constructor inherits one as an implicit mem-initializer.
     if (auto *DIE = dyn_cast<CXXDefaultInitExpr>(Init)) {
-      Path.push_back({IndirectLocalPathEntry::DefaultInit, DIE, DIE->getField()});
+      Path.push_back(
+          {IndirectLocalPathEntry::DefaultInit, DIE, DIE->getField()});
       Init = DIE->getExpr();
     }
 
@@ -657,21 +658,23 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
         return visitLocalsRetainedByReferenceBinding(
             Path, Init, RK_ReferenceBinding,
             [&](IndirectLocalPath &Path, Local L, ReferenceKind RK) -> bool {
-          if (auto *DRE = dyn_cast<DeclRefExpr>(L)) {
-            auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
-            if (VD && VD->getType().isConstQualified() && VD->getInit() &&
-                !isVarOnPath(Path, VD)) {
-              Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD});
-              visitLocalsRetainedByInitializer(Path, VD->getInit(), Visit, true,
-                                               EnableLifetimeWarnings);
-            }
-          } else if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L)) {
-            if (MTE->getType().isConstQualified())
-              visitLocalsRetainedByInitializer(Path, MTE->getSubExpr(), Visit,
-                                               true, EnableLifetimeWarnings);
-          }
-          return false;
-        }, EnableLifetimeWarnings);
+              if (auto *DRE = dyn_cast<DeclRefExpr>(L)) {
+                auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
+                if (VD && VD->getType().isConstQualified() && VD->getInit() &&
+                    !isVarOnPath(Path, VD)) {
+                  Path.push_back({IndirectLocalPathEntry::VarInit, DRE, VD});
+                  visitLocalsRetainedByInitializer(
+                      Path, VD->getInit(), Visit, true, EnableLifetimeWarnings);
+                }
+              } else if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L)) {
+                if (MTE->getType().isConstQualified())
+                  visitLocalsRetainedByInitializer(Path, MTE->getSubExpr(),
+                                                   Visit, true,
+                                                   EnableLifetimeWarnings);
+              }
+              return false;
+            },
+            EnableLifetimeWarnings);
 
         // We assume that objects can be retained by pointers cast to integers,
         // but not if the integer is cast to floating-point type or to _Complex.
@@ -771,9 +774,8 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
             // This might be either aggregate-initialization of a member or
             // initialization of a std::initializer_list object. Regardless,
             // we should recursively lifetime-extend that initializer.
-            visitLocalsRetainedByInitializer(Path, SubInit, Visit,
-                                             RevisitSubinits,
-                                             EnableLifetimeWarnings);
+            visitLocalsRetainedByInitializer(
+                Path, SubInit, Visit, RevisitSubinits, EnableLifetimeWarnings);
           ++Index;
         }
       }
@@ -813,7 +815,7 @@ static void visitLocalsRetainedByInitializer(IndirectLocalPath &Path,
         Path.push_back({IndirectLocalPathEntry::TemporaryCopy, Arg,
                         CCE->getConstructor()});
         visitLocalsRetainedByInitializer(Path, Arg, Visit, true,
-                                         /*EnableLifetimeWarnings*/false);
+                                         /*EnableLifetimeWarnings*/ false);
         Path.pop_back();
       }
     }
@@ -1002,8 +1004,8 @@ void checkExprLifetime(Sema &SemaRef, const CheckingEntity &CEntity,
     bool IsLocalGslOwner = false;
     if (pathOnlyInitializesGslPointer(Path)) {
       if (isa<DeclRefExpr>(L)) {
-        // We do not want to follow the references when returning a pointer originating
-        // from a local owner to avoid the following false positive:
+        // We do not want to follow the references when returning a pointer
+        // originating from a local owner to avoid the following false positive:
         //   int &p = *localUniquePtr;
         //   someContainer.add(std::move(localUniquePtr));
         //   return p;
@@ -1011,8 +1013,9 @@ void checkExprLifetime(Sema &SemaRef, const CheckingEntity &CEntity,
         if (pathContainsInit(Path) || !IsLocalGslOwner)
           return false;
       } else {
-        IsGslPtrInitWithGslTempOwner = MTE && !MTE->getExtendingDecl() &&
-                            isRecordWithAttr<OwnerAttr>(MTE->getType());
+        IsGslPtrInitWithGslTempOwner =
+            MTE && !MTE->getExtendingDecl() &&
+            isRecordWithAttr<OwnerAttr>(MTE->getType());
         // Skipping a chain of initializing gsl::Pointer annotated objects.
         // We are looking only for the final source to find out if it was
         // a local or temporary owner or the address of a local variable/param.
@@ -1097,15 +1100,15 @@ void checkExprLifetime(Sema &SemaRef, const CheckingEntity &CEntity,
             SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer_member)
                 << ExtendingDecl << DiagRange;
             SemaRef.Diag(ExtendingDecl->getLocation(),
-                 diag::note_ref_or_ptr_member_declared_here)
+                         diag::note_ref_or_ptr_member_declared_here)
                 << true;
             return false;
           }
           bool IsSubobjectMember = ExtendingEntity != InitEntity;
           SemaRef.Diag(DiagLoc, shouldLifetimeExtendThroughPath(Path) !=
-                                PathLifetimeKind::NoExtend
-                            ? diag::err_dangling_member
-                            : diag::warn_dangling_member)
+                                        PathLifetimeKind::NoExtend
+                                    ? diag::err_dangling_member
+                                    : diag::warn_dangling_member)
               << ExtendingDecl << IsSubobjectMember << RK << DiagRange;
           // Don't bother adding a note pointing to the field if we're inside
           // its default member initializer; our primary diagnostic points to
@@ -1113,7 +1116,7 @@ void checkExprLifetime(Sema &SemaRef, const CheckingEntity &CEntity,
           if (Path.empty() ||
               Path.back().Kind != IndirectLocalPathEntry::DefaultInit) {
             SemaRef.Diag(ExtendingDecl->getLocation(),
-                 diag::note_lifetime_extending_member_declared_here)
+                         diag::note_lifetime_extending_member_declared_here)
                 << RK << IsSubobjectMember;
           }
         } else {
@@ -1153,7 +1156,7 @@ void checkExprLifetime(Sema &SemaRef, const CheckingEntity &CEntity,
                                  : diag::warn_bind_ref_member_to_parameter)
               << Member << VD << isa<ParmVarDecl>(VD) << DiagRange;
           SemaRef.Diag(Member->getLocation(),
-               diag::note_ref_or_ptr_member_declared_here)
+                       diag::note_ref_or_ptr_member_declared_here)
               << (unsigned)IsPointer;
         }
       }
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 0cf974dc56..3a6bf0f0b9 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -13778,7 +13778,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
     return QualType();
 
   CheckForNullPointerDereference(*this, LHSExpr);
-  
+
   AssignedEntity AE{LHSExpr};
   checkExprLifetime(*this, &AE, RHS.get());
 
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 065d078eab..ff28c420a3 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7285,7 +7285,6 @@ PerformConstructorInitialization(Sema &S,
   return CurInit;
 }
 
-
 void Sema::checkInitializerLifetime(const InitializedEntity &Entity,
                                     Expr *Init) {
   sema::CheckingEntity CEntity(&Entity);

``````````

</details>


https://github.com/llvm/llvm-project/pull/96475


More information about the llvm-branch-commits mailing list