Skip to content

[clang] Refactor: Introduce a new LifetimeKind for the assignment case, NFC #99005

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 16, 2024

Conversation

hokein
Copy link
Collaborator

@hokein hokein commented Jul 16, 2024

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.

The current implementation for 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 assignment cases,
simplifying the implementation and improving clarity.
@hokein hokein requested review from Xazax-hun and usx95 July 16, 2024 08:34
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Jul 16, 2024
@llvmbot
Copy link
Member

llvmbot commented Jul 16, 2024

@llvm/pr-subscribers-clang

Author: Haojian Wu (hokein)

Changes

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 --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

Copy link
Collaborator

@Xazax-hun Xazax-hun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@hokein
Copy link
Collaborator Author

hokein commented Jul 16, 2024

Thanks!

@hokein hokein merged commit c30ce8b into llvm:main Jul 16, 2024
8 of 9 checks passed
@hokein hokein deleted the LK_assignment branch July 16, 2024 09:23
yuxuanchen1997 pushed a commit that referenced this pull request Jul 25, 2024
…e, NFC (#99005)

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.

Test Plan: 

Reviewers: 

Subscribers: 

Tasks: 

Tags: 


Differential Revision: https://phabricator.intern.facebook.com/D60251682
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants