Skip to content

Commit 304b3c5

Browse files
authored
[alpha.webkit.RawPtrRefMemberChecker] The checker doesn't warn Objective-C types in ivars. (#132833)
This PR fixes the bug that we weren't generating warnings when a raw poiner is used to point to a NS type in Objective-C ivars. Also fix the bug that we weren't suppressing this warning in system headers.
1 parent fb0cd98 commit 304b3c5

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

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

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,14 @@ class RawPtrRefMemberChecker
111111
}
112112

113113
void visitObjCDecl(const ObjCContainerDecl *CD) const {
114+
if (BR->getSourceManager().isInSystemHeader(CD->getLocation()))
115+
return;
116+
117+
ObjCContainerDecl::PropertyMap map;
118+
CD->collectPropertiesToImplement(map);
119+
for (auto it : map)
120+
visitObjCPropertyDecl(CD, it.second);
121+
114122
if (auto *ID = dyn_cast<ObjCInterfaceDecl>(CD)) {
115123
for (auto *Ivar : ID->ivars())
116124
visitIvarDecl(CD, Ivar);
@@ -133,6 +141,35 @@ class RawPtrRefMemberChecker
133141
std::optional<bool> IsCompatible = isPtrCompatible(QT, IvarCXXRD);
134142
if (IsCompatible && *IsCompatible)
135143
reportBug(Ivar, IvarType, IvarCXXRD, CD);
144+
} else {
145+
std::optional<bool> IsCompatible = isPtrCompatible(QT, nullptr);
146+
auto *PointeeType = IvarType->getPointeeType().getTypePtrOrNull();
147+
if (IsCompatible && *IsCompatible) {
148+
auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
149+
if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
150+
reportBug(Ivar, IvarType, ObjCType->getDecl(), CD);
151+
}
152+
}
153+
}
154+
155+
void visitObjCPropertyDecl(const ObjCContainerDecl *CD,
156+
const ObjCPropertyDecl *PD) const {
157+
auto QT = PD->getType();
158+
const Type *PropType = QT.getTypePtrOrNull();
159+
if (!PropType)
160+
return;
161+
if (auto *PropCXXRD = PropType->getPointeeCXXRecordDecl()) {
162+
std::optional<bool> IsCompatible = isPtrCompatible(QT, PropCXXRD);
163+
if (IsCompatible && *IsCompatible)
164+
reportBug(PD, PropType, PropCXXRD, CD);
165+
} else {
166+
std::optional<bool> IsCompatible = isPtrCompatible(QT, nullptr);
167+
auto *PointeeType = PropType->getPointeeType().getTypePtrOrNull();
168+
if (IsCompatible && *IsCompatible) {
169+
auto *Desugared = PointeeType->getUnqualifiedDesugaredType();
170+
if (auto *ObjCType = dyn_cast_or_null<ObjCInterfaceType>(Desugared))
171+
reportBug(PD, PropType, ObjCType->getDecl(), CD);
172+
}
136173
}
137174
}
138175

@@ -181,9 +218,12 @@ class RawPtrRefMemberChecker
181218
SmallString<100> Buf;
182219
llvm::raw_svector_ostream Os(Buf);
183220

184-
if (isa<ObjCContainerDecl>(ClassCXXRD))
185-
Os << "Instance variable ";
186-
else
221+
if (isa<ObjCContainerDecl>(ClassCXXRD)) {
222+
if (isa<ObjCPropertyDecl>(Member))
223+
Os << "Property ";
224+
else
225+
Os << "Instance variable ";
226+
} else
187227
Os << "Member variable ";
188228
printQuotedName(Os, Member);
189229
Os << " in ";

clang/test/Analysis/Checkers/WebKit/mock-system-header.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,14 @@ enum os_log_type_t : uint8_t {
2929
typedef struct os_log_s *os_log_t;
3030
os_log_t os_log_create(const char *subsystem, const char *category);
3131
void os_log_msg(os_log_t oslog, os_log_type_t type, const char *msg, ...);
32+
33+
typedef const struct __attribute__((objc_bridge(NSString))) __CFString * CFStringRef;
34+
35+
#ifdef __OBJC__
36+
@class NSString;
37+
@interface SystemObject {
38+
NSString *ns_string;
39+
CFStringRef cf_string;
40+
}
41+
@end
42+
#endif

clang/test/Analysis/Checkers/WebKit/unretained-members.mm

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.NoUnretainedMemberChecker -verify %s
22

33
#include "objc-mock-types.h"
4+
#include "mock-system-header.h"
45

56
namespace members {
67

@@ -58,3 +59,13 @@ void forceTmplToInstantiate(FooTmpl<SomeObj, CFMutableArrayRef>) {}
5859

5960
void forceTmplToInstantiate(RefPtr<SomeObj>) {}
6061
}
62+
63+
@interface AnotherObject : NSObject {
64+
NSString *ns_string;
65+
// expected-warning@-1{{Instance variable 'ns_string' in 'AnotherObject' is a raw pointer to retainable type 'NSString'; member variables must be a RetainPtr}}
66+
CFStringRef cf_string;
67+
// expected-warning@-1{{Instance variable 'cf_string' in 'AnotherObject' is a retainable type 'CFStringRef'; member variables must be a RetainPtr}}
68+
}
69+
@property(nonatomic, strong) NSString *prop_string;
70+
// expected-warning@-1{{Property 'prop_string' in 'AnotherObject' is a raw pointer to retainable type 'NSString'; member variables must be a RetainPtr}}
71+
@end

0 commit comments

Comments
 (0)