File tree Expand file tree Collapse file tree 2 files changed +43
-2
lines changed Expand file tree Collapse file tree 2 files changed +43
-2
lines changed Original file line number Diff line number Diff line change @@ -258,9 +258,27 @@ template <typename T> static bool isRecordWithAttr(QualType Type) {
258258 auto *RD = Type->getAsCXXRecordDecl ();
259259 if (!RD)
260260 return false ;
261+ // Generally, if a primary template class declaration is annotated with an
262+ // attribute, all its specializations generated from template instantiations
263+ // should inherit the attribute.
264+ //
265+ // However, since lifetime analysis occurs during parsing, we may encounter
266+ // cases where a full definition of the specialization is not required. In
267+ // such cases, the specialization declaration remains incomplete and lacks the
268+ // attribute. Therefore, we fall back to checking the primary template class.
269+ //
270+ // Note: it is possible for a specialization declaration to have an attribute
271+ // even if the primary template does not.
272+ //
273+ // FIXME: What if the primary template and explicit specialization
274+ // declarations have conflicting attributes? We should consider diagnosing
275+ // this scenario.
276+ bool Result = RD->hasAttr <T>();
277+
261278 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
262- RD = CTSD->getSpecializedTemplate ()->getTemplatedDecl ();
263- return RD->hasAttr <T>();
279+ Result |= CTSD->getSpecializedTemplate ()->getTemplatedDecl ()->hasAttr <T>();
280+
281+ return Result;
264282}
265283
266284bool isPointerLikeType (QualType QT) {
Original file line number Diff line number Diff line change @@ -670,3 +670,26 @@ void test13() {
670670}
671671
672672} // namespace GH100526
673+
674+ namespace std {
675+ template <typename T>
676+ class __set_iterator {};
677+
678+ template <typename T>
679+ struct BB {
680+ typedef __set_iterator<T> iterator;
681+ };
682+
683+ template <typename T>
684+ class set {
685+ public:
686+ typedef typename BB<T>::iterator iterator;
687+ iterator begin () const ;
688+ };
689+ } // namespace std
690+ namespace GH118064 {
691+
692+ void test () {
693+ auto y = std::set<int >{}.begin (); // expected-warning {{object backing the pointer}}
694+ }
695+ } // namespace GH118064
You can’t perform that action at this time.
0 commit comments