Skip to content

Commit a05aeda

Browse files
authored
[RawPtrRefMemberChecker] Member variable checker should allow T* in smart pointer classes (#136503)
This PR fixes member variable checker to allow the usage of T* in smart pointer classes. e.g. alpha.webkit.NoUncheckedPtrMemberChecker should allow T* to appear within RefPtr.
1 parent 3fbbe9b commit a05aeda

File tree

5 files changed

+34
-18
lines changed

5 files changed

+34
-18
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,13 @@ bool isRetainPtr(const CXXRecordDecl *R) {
436436
return false;
437437
}
438438

439+
bool isSmartPtr(const CXXRecordDecl *R) {
440+
assert(R);
441+
if (auto *TmplR = R->getTemplateInstantiationPattern())
442+
return isSmartPtrClass(safeGetName(TmplR));
443+
return false;
444+
}
445+
439446
bool isPtrConversion(const FunctionDecl *F) {
440447
assert(F);
441448
if (isCtorOfRefCounted(F))

clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ bool isCheckedPtr(const clang::CXXRecordDecl *Class);
5858
/// \returns true if \p Class is a RetainPtr, false if not.
5959
bool isRetainPtr(const clang::CXXRecordDecl *Class);
6060

61+
/// \returns true if \p Class is a smart pointer (RefPtr, WeakPtr, etc...),
62+
/// false if not.
63+
bool isSmartPtr(const clang::CXXRecordDecl *Class);
64+
6165
/// \returns true if \p Class is ref-countable AND not ref-counted, false if
6266
/// not, std::nullopt if inconclusive.
6367
std::optional<bool> isUncounted(const clang::QualType T);

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

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ class RawPtrRefMemberChecker
4141
virtual std::optional<bool>
4242
isPtrCompatible(const clang::QualType,
4343
const clang::CXXRecordDecl *R) const = 0;
44-
virtual bool isPtrCls(const clang::CXXRecordDecl *) const = 0;
4544
virtual const char *typeName() const = 0;
4645
virtual const char *invariant() const = 0;
4746

@@ -205,8 +204,8 @@ class RawPtrRefMemberChecker
205204
// Ref-counted smartpointers actually have raw-pointer to uncounted type as
206205
// a member but we trust them to handle it correctly.
207206
auto CXXRD = llvm::dyn_cast_or_null<CXXRecordDecl>(RD);
208-
if (CXXRD)
209-
return isPtrCls(CXXRD);
207+
if (CXXRD && isSmartPtr(CXXRD))
208+
return true;
210209

211210
return false;
212211
}
@@ -270,10 +269,6 @@ class NoUncountedMemberChecker final : public RawPtrRefMemberChecker {
270269
return R ? isRefCountable(R) : std::nullopt;
271270
}
272271

273-
bool isPtrCls(const clang::CXXRecordDecl *R) const final {
274-
return isRefCounted(R);
275-
}
276-
277272
const char *typeName() const final { return "ref-countable type"; }
278273

279274
const char *invariant() const final {
@@ -293,10 +288,6 @@ class NoUncheckedPtrMemberChecker final : public RawPtrRefMemberChecker {
293288
return R ? isCheckedPtrCapable(R) : std::nullopt;
294289
}
295290

296-
bool isPtrCls(const clang::CXXRecordDecl *R) const final {
297-
return isCheckedPtr(R);
298-
}
299-
300291
const char *typeName() const final { return "CheckedPtr capable type"; }
301292

302293
const char *invariant() const final {
@@ -319,10 +310,6 @@ class NoUnretainedMemberChecker final : public RawPtrRefMemberChecker {
319310
return RTC->isUnretained(QT);
320311
}
321312

322-
bool isPtrCls(const clang::CXXRecordDecl *R) const final {
323-
return isRetainPtr(R);
324-
}
325-
326313
const char *typeName() const final { return "retainable type"; }
327314

328315
const char *invariant() const final {

clang/test/Analysis/Checkers/WebKit/unchecked-members.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,12 @@ namespace ignore_unions {
5050
void forceTmplToInstantiate(FooTmpl<CheckedObj>) { }
5151

5252
} // namespace ignore_unions
53+
54+
namespace checked_ptr_ref_ptr_capable {
55+
56+
RefCountableAndCheckable* provide();
57+
void foo() {
58+
RefPtr<RefCountableAndCheckable> foo = provide();
59+
}
60+
61+
} // checked_ptr_ref_ptr_capable

clang/test/Analysis/Checkers/WebKit/uncounted-members.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ namespace members {
3434
private:
3535
RefCountable* a = nullptr;
3636
};
37-
}
37+
} // members
3838

3939
namespace ignore_unions {
4040
union Foo {
@@ -49,7 +49,7 @@ namespace ignore_unions {
4949
};
5050

5151
void forceTmplToInstantiate(RefPtr<RefCountable>) {}
52-
}
52+
} // ignore_unions
5353

5454
namespace ignore_system_header {
5555

@@ -67,4 +67,13 @@ namespace ignore_non_ref_countable {
6767
struct Bar {
6868
Foo* foo;
6969
};
70-
}
70+
} // ignore_non_ref_countable
71+
72+
namespace checked_ptr_ref_ptr_capable {
73+
74+
RefCountableAndCheckable* provide();
75+
void foo() {
76+
CheckedPtr<RefCountableAndCheckable> foo = provide();
77+
}
78+
79+
} // checked_ptr_ref_ptr_capable

0 commit comments

Comments
 (0)