https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/118088
>From b165ad7accfc746210c5ca894b488553124253ed Mon Sep 17 00:00:00 2001 From: Haojian Wu <hokein...@gmail.com> Date: Fri, 29 Nov 2024 13:35:56 +0100 Subject: [PATCH 1/2] [clang] Fix a regression. --- clang/lib/Sema/CheckExprLifetime.cpp | 18 +++++++++++++-- .../Sema/warn-lifetime-analysis-nocfg.cpp | 23 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index 15ceff873693a5..86a5fa662aed0e 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -258,9 +258,23 @@ template <typename T> static bool isRecordWithAttr(QualType Type) { auto *RD = Type->getAsCXXRecordDecl(); if (!RD) return false; + // Generally, if a primary template class declaration is annotated with an + // attribute, all its specializations generated from template instantiations + // should inherit the attribute. + // + // However, since lifetime analysis occurs during parsing, we may encounter + // cases where a full definition of the specialization is not required. In + // such cases, the specialization declaration remains incomplete and lacks the + // attribute. Therefore, we fall back to checking the primary template class. + // + // Note: it is possible for a specialization declaration to have an attribute + // even if the primary template does not. + bool Result = RD->hasAttr<T>(); + if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) - RD = CTSD->getSpecializedTemplate()->getTemplatedDecl(); - return RD->hasAttr<T>(); + Result |= (bool)CTSD->getSpecializedTemplate()->getTemplatedDecl(); + + return Result; } bool isPointerLikeType(QualType QT) { diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp index c18ecd86ad06f0..fc876926ba2e63 100644 --- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -670,3 +670,26 @@ void test13() { } } // namespace GH100526 + +namespace std { +template <typename T> +class __set_iterator {}; + +template<typename T> +struct BB { + typedef __set_iterator<T> iterator; +}; + +template <typename T> +class set { +public: + typedef typename BB<T>::iterator iterator; + iterator begin() const; +}; +} // namespace std +namespace GH118064{ + +void test() { + auto y = std::set<int>{}.begin(); // expected-warning {{object backing the pointer}} +} +} // namespace GH118064 >From 11300e4a5a7632233bfd6c33ffaea4bd969b50c0 Mon Sep 17 00:00:00 2001 From: Haojian Wu <hokein...@gmail.com> Date: Fri, 29 Nov 2024 13:54:03 +0100 Subject: [PATCH 2/2] Add a missing comment. --- clang/lib/Sema/CheckExprLifetime.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index 86a5fa662aed0e..868081292bc32c 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -269,10 +269,14 @@ template <typename T> static bool isRecordWithAttr(QualType Type) { // // Note: it is possible for a specialization declaration to have an attribute // even if the primary template does not. + // + // FIXME: What if the primary template and explicit specialization + // declarations have conflicting attributes? We should consider diagnosing + // this scenario. bool Result = RD->hasAttr<T>(); if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) - Result |= (bool)CTSD->getSpecializedTemplate()->getTemplatedDecl(); + Result |= CTSD->getSpecializedTemplate()->getTemplatedDecl()->hasAttr<T>(); return Result; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits