llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Haojian Wu (hokein) <details> <summary>Changes</summary> The current implementation for the assignment case uses a combination of the `LK_Extended` lifetime kind and the validity of `AEntity`, which is somewhat messy and doesn't align well with the intended mental model. This patch introduces a dedicated lifetime kind to handle the assignment case, simplifying the implementation and improving clarity. --- Full diff: https://github.com/llvm/llvm-project/pull/99005.diff 1 Files Affected: - (modified) clang/lib/Sema/CheckExprLifetime.cpp (+23-16) ``````````diff diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index 2f9ef28da2c3e..995e4cbadacfe 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -39,6 +39,11 @@ enum LifetimeKind { /// This is a mem-initializer: if it would extend a temporary (other than via /// a default member initializer), the program is ill-formed. LK_MemInitializer, + + /// The lifetime of a temporary bound to this entity probably ends too soon, + /// because the entity is a pointer and we assign the address of a temporary + /// object to it. + LK_Assignment, }; using LifetimeResult = llvm::PointerIntPair<const InitializedEntity *, 3, LifetimeKind>; @@ -971,6 +976,8 @@ static void checkExprLifetimeImpl(Sema &SemaRef, const InitializedEntity *ExtendingEntity, LifetimeKind LK, const AssignedEntity *AEntity, Expr *Init) { + assert((AEntity && LK == LK_Assignment) || + (InitEntity && LK != LK_Assignment)); // If this entity doesn't have an interesting lifetime, don't bother looking // for temporaries within its initializer. if (LK == LK_FullExpression) @@ -1008,19 +1015,7 @@ static void checkExprLifetimeImpl(Sema &SemaRef, return true; } } - if (AEntity) { - if (!MTE) - return false; - assert(shouldLifetimeExtendThroughPath(Path) == - PathLifetimeKind::NoExtend && - "No lifetime extension for assignments"); - if (!pathContainsInit(Path)) - SemaRef.Diag(DiagLoc, diag::warn_dangling_pointer_assignment) - << AEntity->LHS << DiagRange; - return false; - } - assert(InitEntity && "only for initialization"); switch (LK) { case LK_FullExpression: llvm_unreachable("already handled this"); @@ -1077,6 +1072,17 @@ static void checkExprLifetimeImpl(Sema &SemaRef, break; } + case LK_Assignment: { + if (!MTE) + return false; + assert(shouldLifetimeExtendThroughPath(Path) == + PathLifetimeKind::NoExtend && + "No lifetime extension for assignments"); + if (!pathContainsInit(Path)) + SemaRef.Diag(DiagLoc, diag::warn_dangling_pointer_assignment) + << AEntity->LHS << DiagRange; + return false; + } case LK_MemInitializer: { if (MTE) { // Under C++ DR1696, if a mem-initializer (or a default member @@ -1283,10 +1289,11 @@ void checkExprLifetime(Sema &SemaRef, const InitializedEntity &Entity, void checkExprLifetime(Sema &SemaRef, const AssignedEntity &Entity, Expr *Init) { - LifetimeKind LK = LK_FullExpression; - if (Entity.LHS->getType()->isPointerType()) // builtin pointer type - LK = LK_Extended; - checkExprLifetimeImpl(SemaRef, nullptr, nullptr, LK, &Entity, Init); + if (!Entity.LHS->getType()->isPointerType()) // builtin pointer type + return; + checkExprLifetimeImpl(SemaRef, /*InitEntity=*/nullptr, + /*ExtendingEntity=*/nullptr, LK_Assignment, &Entity, + Init); } } // namespace clang::sema `````````` </details> https://github.com/llvm/llvm-project/pull/99005 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits