Skip to content

Commit d283edc

Browse files
committed
[alpha.webkit.RawPtrRefMemberChecker] The checker doesn't warn Objective-C types in ivars. (llvm#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 a587ba9 commit d283edc

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
@@ -112,6 +112,14 @@ class RawPtrRefMemberChecker
112112
}
113113

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

@@ -182,9 +219,12 @@ class RawPtrRefMemberChecker
182219
SmallString<100> Buf;
183220
llvm::raw_svector_ostream Os(Buf);
184221

185-
if (isa<ObjCContainerDecl>(ClassCXXRD))
186-
Os << "Instance variable ";
187-
else
222+
if (isa<ObjCContainerDecl>(ClassCXXRD)) {
223+
if (isa<ObjCPropertyDecl>(Member))
224+
Os << "Property ";
225+
else
226+
Os << "Instance variable ";
227+
} else
188228
Os << "Member variable ";
189229
printQuotedName(Os, Member);
190230
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)