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) {
258
258
auto *RD = Type->getAsCXXRecordDecl ();
259
259
if (!RD)
260
260
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
+
261
278
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;
264
282
}
265
283
266
284
bool isPointerLikeType (QualType QT) {
Original file line number Diff line number Diff line change @@ -670,3 +670,26 @@ void test13() {
670
670
}
671
671
672
672
} // 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