yronglin wrote:

> I’ve taken some time to better understand the code and think through the 
> solution.
> 
> I tried using `isInLifetimeExtendingContext()`, but it still returns false, 
> and I believe I now understand why. In your PR, the flag is set here:
> 
> https://github.com/llvm/llvm-project/blob/b581f9d056babadf55098b9d5d100271621b90db/clang/lib/Parse/ParseDecl.cpp#L2314-L2318
> 
> However, the warning is actually triggered starting from this location:
> 
> https://github.com/llvm/llvm-project/blob/b581f9d056babadf55098b9d5d100271621b90db/clang/lib/Parse/ParseDecl.cpp#L2266
> 
> An alternative approach would be to apply your logic and set again the flag 
> in here:
> 
> https://github.com/llvm/llvm-project/blob/43d042b350af8ee8c7401d6b102df68d6c176b5a/clang/lib/Parse/ParseStmt.cpp#L2174-L2179
> 
> Maybe we could act on `ForRangeInfo.LifetimeExtendTemps.back()`, or even 
> directly on `Actions.currentEvaluationContext();`. If that works, we might be 
> able to rely solely on `isInLifetimeExtendingContext()` and remove the need 
> for `isRangeBasedForLoopVariable` altogether.
> 
> What do you think? I'm absolutely open to every approach (the cleaner, the 
> better!).

IMO, we have 2 options:
1. Add a flag variable into `ExpressionEvaluationContextRecord`. Represent that 
we are initializing the for-range __range variable. 
Eg.
```diff
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 9397546c8fc5..c639a4b4af58 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -6786,6 +6786,9 @@ public:
     /// Whether we should rebuild CXXDefaultArgExpr and CXXDefaultInitExpr.
     bool RebuildDefaultArgOrDefaultInit = false;
 
+    /// Whether we are initializing a C++ for-range implicit variable 
'__range'.
+    bool InitCXXForRangeVar = false;
+
     // When evaluating immediate functions in the initializer of a default
     // argument or default member initializer, this is the declaration whose
     // default initializer is being evaluated and the location of the call
diff --git a/clang/lib/Sema/CheckExprLifetime.cpp 
b/clang/lib/Sema/CheckExprLifetime.cpp
index 060ba3166055..150e27f8acf7 100644
--- a/clang/lib/Sema/CheckExprLifetime.cpp
+++ b/clang/lib/Sema/CheckExprLifetime.cpp
@@ -1341,6 +1341,8 @@ checkExprLifetimeImpl(Sema &SemaRef, const 
InitializedEntity *InitEntity,
       }
 
       if (IsGslPtrValueFromGslTempOwner && DiagLoc.isValid()) {
+        if (SemaRef.currentEvaluationContext().InitCXXForRangeVar)
+          return false;
         SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer)
             << DiagRange;
         return false;
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 923a9e81fbd6..da97d34854ac 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -2374,6 +2374,13 @@ static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl 
*Decl, Expr *Init,
       SemaRef.ObjC().inferObjCARCLifetime(Decl))
     Decl->setInvalidDecl();
 
+  // EnterExpressionEvaluationContext ForRangeInitContext(
+  //     SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
+  //     /*LambdaContextDecl=*/nullptr,
+  //     Sema::ExpressionEvaluationContextRecord::EK_Other,
+  //     SemaRef.getLangOpts().CPlusPlus23);
+  if (SemaRef.getLangOpts().CPlusPlus23)
+    SemaRef.currentEvaluationContext().InitCXXForRangeVar = true;
   SemaRef.AddInitializerToDecl(Decl, Init, /*DirectInit=*/false);
   SemaRef.FinalizeDeclaration(Decl);
   SemaRef.CurContext->addHiddenDecl(Decl);
```
2. Introduce a bitfields into `clang::VarDecl::NonParmVarDeclBitfields`, like 
`CXXForRangeDecl`(Eg. `CXXForRangeImplicitVar`)

CC @cor3ntin 

https://github.com/llvm/llvm-project/pull/145164
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to