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