[clang] [Sema] Fix lifetime extension for temporaries in range-based for loops in C++23 (PR #145164)

via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 4 08:05:40 PDT 2025


yronglin wrote:

I have debug the issue, seems we cannot move the `__range` variable check to the start of `checkExprLifetimeImpl`, we may missing extending lifetime of temporaries. 
Eg.
```cpp
template <typename T>
struct ListWrapper {
  ListWrapper() {}
  ~ListWrapper() {}
  const T *begin() const;
  const T *end() const;
  ListWrapper& r();
  ListWrapper g();
};

using A = ListWrapper<int>;

A g() { return A(); }
const A &f1(const A &t) { return t; }

void member_call() {
  // CHECK-CXX23: void @_ZN7P2718R011member_call11member_callEv()
  // CHECK-CXX23-LABEL: for.cond.cleanup:
  // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev(
  // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev(
  // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev(
  // CHECK-CXX23-NEXT: call void @_ZN7P2718R011member_call11ListWrapperIiED1Ev(
  for (auto e : g().r().g().r().g().r().g()) {}
}
```
I think we should revert to the previous approach, what do you think?
```cpp
      if (IsGslPtrValueFromGslTempOwner && DiagLoc.isValid()) {
        if (const auto *VD =
                dyn_cast_if_present<VarDecl>(ExtendingEntity->getDecl());
            SemaRef.getLangOpts().CPlusPlus23 && VD &&
            VD->isCXXForRangeImplicitVar())
          return true;
        SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer)
            << DiagRange;
        return false;
      }
```

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


More information about the cfe-commits mailing list