Author: Haojian Wu Date: 2024-11-29T23:48:09+01:00 New Revision: 52690db47da36a739ee506d3b3a7457fb918dc1e
URL: https://github.com/llvm/llvm-project/commit/52690db47da36a739ee506d3b3a7457fb918dc1e DIFF: https://github.com/llvm/llvm-project/commit/52690db47da36a739ee506d3b3a7457fb918dc1e.diff LOG: [clang] Fix -Wdangling false negative regressions caused by 117315 (#118088) A specialization declaration can have an attribute even if the primary template does not, particularly when the specialization is instantiated from an annotated using-alias declaration. Fix #118064 Added: Modified: clang/lib/Sema/CheckExprLifetime.cpp clang/test/Sema/warn-lifetime-analysis-nocfg.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index 15ceff873693a5..868081292bc32c 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -258,9 +258,27 @@ 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. + // + // 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)) - RD = CTSD->getSpecializedTemplate()->getTemplatedDecl(); - return RD->hasAttr<T>(); + Result |= CTSD->getSpecializedTemplate()->getTemplatedDecl()->hasAttr<T>(); + + 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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits