Skip to content

Commit 0e333cb

Browse files
rniwaRyosuke Niwa
authored andcommitted
[alpha.webkit.ForwardDeclChecker] Recognize a forward declared template specialization (llvm#134545)
This PR fixes a bug that when a template specialization is declared with a forward declaration of a template, the checker fails to find its definition in the same translation unit and erroneously emit an unsafe forward declaration warning.
1 parent 9ecfa43 commit 0e333cb

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-2
lines changed

clang/lib/StaticAnalyzer/Checkers/WebKit/ForwardDeclChecker.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,18 @@ class ForwardDeclChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> {
125125
if (!R) // Forward declaration of a Objective-C interface is safe.
126126
return false;
127127
auto Name = R->getName();
128-
return !R->hasDefinition() && !RTC.isUnretained(QT) &&
129-
!SystemTypes.contains(CanonicalType) &&
128+
if (R->hasDefinition())
129+
return false;
130+
// Find a definition amongst template declarations.
131+
if (auto *Specialization = dyn_cast<ClassTemplateSpecializationDecl>(R)) {
132+
if (auto *S = Specialization->getSpecializedTemplate()) {
133+
for (S = S->getMostRecentDecl(); S; S = S->getPreviousDecl()) {
134+
if (S->isThisDeclarationADefinition())
135+
return false;
136+
}
137+
}
138+
}
139+
return !RTC.isUnretained(QT) && !SystemTypes.contains(CanonicalType) &&
130140
!SystemTypes.contains(PointeeType) && !Name.starts_with("Opaque") &&
131141
Name != "_NSZone";
132142
}

clang/test/Analysis/Checkers/WebKit/forward-decl-checker.mm

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,3 +138,20 @@ - (void)doMoreWork:(ObjCObj *)obj {
138138
}
139139

140140
@end
141+
142+
namespace template_forward_declare {
143+
144+
template<typename> class HashSet;
145+
146+
template<typename T>
147+
using SingleThreadHashSet = HashSet<T>;
148+
149+
template<typename> class HashSet { };
150+
151+
struct Font { };
152+
153+
struct ComplexTextController {
154+
SingleThreadHashSet<const Font>* fallbackFonts { nullptr };
155+
};
156+
157+
}

0 commit comments

Comments
 (0)