Skip to content

Commit b165ad7

Browse files
committed
[clang] Fix a regression.
1 parent 26baa00 commit b165ad7

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

clang/lib/Sema/CheckExprLifetime.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,23 @@ 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+
bool Result = RD->hasAttr<T>();
273+
261274
if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
262-
RD = CTSD->getSpecializedTemplate()->getTemplatedDecl();
263-
return RD->hasAttr<T>();
275+
Result |= (bool)CTSD->getSpecializedTemplate()->getTemplatedDecl();
276+
277+
return Result;
264278
}
265279

266280
bool isPointerLikeType(QualType QT) {

clang/test/Sema/warn-lifetime-analysis-nocfg.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff 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

0 commit comments

Comments
 (0)