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

Reply via email to