llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Utkarsh Saxena (usx95) <details> <summary>Changes</summary> Fixes: https://github.com/llvm/llvm-project/issues/81589 --- Full diff: https://github.com/llvm/llvm-project/pull/100197.diff 2 Files Affected: - (modified) clang/lib/Sema/CheckExprLifetime.cpp (+8) - (modified) clang/test/SemaCXX/attr-lifetimebound.cpp (+21) ``````````diff diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index 5c8ef564f30aa..4d26a2e0f50c6 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "CheckExprLifetime.h" +#include "clang/AST/Decl.h" #include "clang/AST/Expr.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Sema/Initialization.h" @@ -548,6 +549,13 @@ static void visitLocalsRetainedByReferenceBinding(IndirectLocalPath &Path, EnableLifetimeWarnings); } + if (auto* M = dyn_cast<MemberExpr>(Init)) { + // Lifetime of a field is the lifetime of the base object. + if (isa<FieldDecl>(M->getMemberDecl())) + visitLocalsRetainedByInitializer(Path, M->getBase(), Visit, true, + EnableLifetimeWarnings); + } + if (isa<CallExpr>(Init)) { if (EnableLifetimeWarnings) handleGslAnnotatedTypes(Path, Init, Visit); diff --git a/clang/test/SemaCXX/attr-lifetimebound.cpp b/clang/test/SemaCXX/attr-lifetimebound.cpp index 70bc545c07bd9..b43c43bb21699 100644 --- a/clang/test/SemaCXX/attr-lifetimebound.cpp +++ b/clang/test/SemaCXX/attr-lifetimebound.cpp @@ -47,6 +47,26 @@ namespace usage_ok { q = A(); // expected-warning {{object backing the pointer q will be destroyed at the end of the full-expression}} r = A(1); // expected-warning {{object backing the pointer r will be destroyed at the end of the full-expression}} } + + struct FieldCheck { + struct Set { + int a; + }; + struct Pair { + const int& a; + int b; + Set c; + }; + Pair p; + FieldCheck(const int a): p(a){} + Pair& getPairR() [[clang::lifetimebound]] { return p; } + Pair* getPairP() [[clang::lifetimebound]] { return &p; } + }; + void test_field_access() { + const int& a = FieldCheck{0}.getPairR().a; // expected-warning {{temporary bound to local reference 'a' will be destroyed at the end of the full-expression}} + const int& b = FieldCheck{0}.getPairP()->b; // expected-warning {{temporary bound to local reference 'b' will be destroyed at the end of the full-expression}} + const int& c = FieldCheck{0}.getPairP()->c.a; // expected-warning {{temporary bound to local reference 'c' will be destroyed at the end of the full-expression}} + } } # 1 "<std>" 1 3 @@ -239,3 +259,4 @@ namespace move_forward_et_al_examples { S X; S *AddressOfOk = std::addressof(X); } // namespace move_forward_et_al_examples + `````````` </details> https://github.com/llvm/llvm-project/pull/100197 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits