llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-analysis Author: Baranov Victor (vbvictor) <details> <summary>Changes</summary> Closes https://github.com/llvm/llvm-project/issues/177798. Same pattern with `getTemplateInstantiationPattern()` for attrs checking is already used in other LLVM places, e.g.: https://github.com/llvm/llvm-project/blame/main/clang/lib/CodeGen/CodeGenModule.cpp#L2830-L2839 --- Full diff: https://github.com/llvm/llvm-project/pull/178000.diff 2 Files Affected: - (modified) clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp (+12-5) - (modified) clang/test/Sema/warn-lifetime-analysis-nocfg.cpp (+24-2) ``````````diff diff --git a/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp b/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp index 93c7a86d0a57c..dd925d2b8fe6e 100644 --- a/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp +++ b/clang/lib/Analysis/LifetimeSafety/LifetimeAnnotations.cpp @@ -74,11 +74,18 @@ bool implicitObjectParamIsLifetimeBound(const FunctionDecl *FD) { FD = getDeclWithMergedLifetimeBoundAttrs(FD); // Attribute merging doesn't work well with attributes on function types (like // 'this' param). We need to check all redeclarations. - for (const FunctionDecl *Redecl : FD->redecls()) { - const TypeSourceInfo *TSI = Redecl->getTypeSourceInfo(); - if (TSI && getLifetimeBoundAttrFromFunctionType(*TSI)) - return true; - } + auto CheckRedecls = [](const FunctionDecl *F) { + return llvm::any_of(F->redecls(), [](const FunctionDecl *Redecl) { + const TypeSourceInfo *TSI = Redecl->getTypeSourceInfo(); + return TSI && getLifetimeBoundAttrFromFunctionType(*TSI); + }); + }; + + if (CheckRedecls(FD)) + return true; + if (const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern(); + Pattern && CheckRedecls(Pattern)) + return true; return isNormalAssignmentOperator(FD); } diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp index 99a796c360a7f..605479d4db372 100644 --- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -1252,6 +1252,24 @@ inline const char* StringTemplateSpecC<char>::data() const [[clang::lifetimeboun return buffer; } +template<typename T> +class MemberFuncsTpl { +public: + // Template Version A: Attribute on declaration only + const T* memberA(const T& x [[clang::lifetimebound]]); + // Template Version B: Attribute on definition only + const T* memberB(const T& x); + // Template Version C: Attribute on BOTH declaration and definition + const T* memberC(const T& x [[clang::lifetimebound]]); +}; + +template<typename T> +const T* MemberFuncsTpl<T>::memberA(const T& x) { return &x; } +template<typename T> +const T* MemberFuncsTpl<T>::memberB(const T& x [[clang::lifetimebound]]) { return &x; } +template<typename T> +const T* MemberFuncsTpl<T>::memberC(const T& x [[clang::lifetimebound]]) { return &x; } + void test() { // Non-templated tests const auto ptrA = StringA().data(); // Declaration-only attribute // expected-warning {{temporary whose address is used}} @@ -1260,13 +1278,17 @@ void test() { // Templated tests (generic templates) const auto ptrTA = StringTemplateA<char>().data(); // Declaration-only attribute // expected-warning {{temporary whose address is used}} - // FIXME: Definition is not instantiated until the end of TU. The attribute is not merged when this call is processed. - const auto ptrTB = StringTemplateB<char>().data(); // Definition-only attribute + const auto ptrTB = StringTemplateB<char>().data(); // Definition-only attribute // expected-warning {{temporary whose address is used}} const auto ptrTC = StringTemplateC<char>().data(); // Both have attribute // expected-warning {{temporary whose address is used}} // Template specialization tests const auto ptrTSA = StringTemplateSpecA<char>().data(); // Declaration-only attribute // expected-warning {{temporary whose address is used}} const auto ptrTSB = StringTemplateSpecB<char>().data(); // Definition-only attribute // expected-warning {{temporary whose address is used}} const auto ptrTSC = StringTemplateSpecC<char>().data(); // Both have attribute // expected-warning {{temporary whose address is used}} + + MemberFuncsTpl<int> mtf; + const int* pTMA = mtf.memberA(1); // Declaration-only attribute // expected-warning {{temporary whose address is used}} + const int* pTMB = mtf.memberB(2); // Definition-only attribute // FIXME: Definition-only attribute + const int* pTMC = mtf.memberC(3); // Both have attribute // expected-warning {{temporary whose address is used}} } } // namespace GH175391 `````````` </details> https://github.com/llvm/llvm-project/pull/178000 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
