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

Marco Vitale via cfe-commits cfe-commits at lists.llvm.org
Sun Jul 6 02:09:47 PDT 2025


mrcvtl wrote:

Forgot that the revert wouldn't include the `lifetimebound` attribute. I restructured the switch case like that, in order to catch both:
```
    case LK_Extended: {
      if (!MTE) {
        // The initialized entity has lifetime beyond the full-expression,
        // and the local entity does too, so don't warn.
        //
        // FIXME: We should consider warning if a static / thread storage
        // duration variable retains an automatic storage duration local.
        return false;
      }
      
      switch (shouldLifetimeExtendThroughPath(Path)) {
      case PathLifetimeKind::Extend:
        assert(!IsGslPtrValueFromGslTempOwner); // Just a test, to be sure that we aren't losing something here.
                                                // can be removed safely I guess.
           
        // Update the storage duration of the materialized temporary.
        // FIXME: Rebuild the expression instead of mutating it.
        MTE->setExtendingDecl(ExtendingEntity->getDecl(),
                              ExtendingEntity->allocateManglingNumber());
        // Also visit the temporaries lifetime-extended by this initializer.
        return true;
      
    case PathLifetimeKind::NoExtend:
      if (SemaRef.getLangOpts().CPlusPlus23 && InitEntity) {
        if (const VarDecl *VD =
            dyn_cast_if_present<VarDecl>(InitEntity->getDecl());
            VD && VD->isCXXForRangeImplicitVar())
          return false;
      }
          
          
      if (IsGslPtrValueFromGslTempOwner && DiagLoc.isValid()) {
        SemaRef.Diag(DiagLoc, diag::warn_dangling_lifetime_pointer)
            << DiagRange;
        return false;
      }

        // If the path goes through the initialization of a variable or field,
        // it can't possibly reach a temporary created in this full-expression.
        // We will have already diagnosed any problems with the initializer.
        if (pathContainsInit(Path))
          return false;

        SemaRef.Diag(DiagLoc, diag::warn_dangling_variable)
            << RK << !InitEntity->getParent()
            << ExtendingEntity->getDecl()->isImplicit()
            << ExtendingEntity->getDecl() << Init->isGLValue() << DiagRange;
        break;
      }
      break;
    }
```

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


More information about the cfe-commits mailing list