-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[WebKit checkers] Treat global const variables as safe #136170
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This PR makes WebKit checkers treat a variable with global storage as safe instead of constraining to ones that start with k or _k.
@llvm/pr-subscribers-clang-static-analyzer-1 Author: Ryosuke Niwa (rniwa) ChangesThis PR makes WebKit checkers treat a variable with global storage as safe instead of constraining to ones that start with k or _k. Full diff: https://github.com/llvm/llvm-project/pull/136170.diff 5 Files Affected:
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
index c36c925c0d2d2..88b98756b2ca8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
@@ -30,12 +30,11 @@ bool tryToFindPtrOrigin(
std::function<bool(const clang::Expr *, bool)> callback) {
while (E) {
if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
- auto *ValDecl = DRE->getDecl();
- auto QT = ValDecl->getType();
- auto ValName = ValDecl->getName();
- if (ValDecl && (ValName.starts_with('k') || ValName.starts_with("_k")) &&
- QT.isConstQualified()) { // Treat constants such as kCF* as safe.
- return callback(E, true);
+ if (auto *VD = dyn_cast_or_null<VarDecl>(DRE->getDecl())) {
+ auto QT = VD->getType();
+ if (VD->hasGlobalStorage() && QT.isConstQualified()) {
+ return callback(E, true);
+ }
}
}
if (auto *tempExpr = dyn_cast<MaterializeTemporaryExpr>(E)) {
diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-call-args-arc.mm b/clang/test/Analysis/Checkers/WebKit/unretained-call-args-arc.mm
index 4207c1836079f..fa866258a2f6d 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-call-args-arc.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-call-args-arc.mm
@@ -18,6 +18,24 @@ void foo() {
} // namespace raw_ptr
+namespace const_global {
+
+extern NSString * const SomeConstant;
+extern CFDictionaryRef const SomeDictionary;
+void doWork(NSString *str, CFDictionaryRef dict);
+void use_const_global() {
+ doWork(SomeConstant, SomeDictionary);
+}
+
+NSString *provide_str();
+CFDictionaryRef provide_dict();
+void use_const_local() {
+ doWork(provide_str(), provide_dict());
+ // expected-warning@-1{{Call argument for parameter 'dict' is unretained and unsafe}}
+}
+
+} // namespace const_global
+
@interface AnotherObj : NSObject
- (void)foo:(SomeObj *)obj;
- (SomeObj *)getSomeObj;
diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm b/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
index eb36b49313d42..c33d53b047c2e 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
@@ -415,6 +415,25 @@ void idcf(CFTypeRef obj) {
} // ptr_conversion
+namespace const_global {
+
+extern NSString * const SomeConstant;
+extern CFDictionaryRef const SomeDictionary;
+void doWork(NSString *str, CFDictionaryRef dict);
+void use_const_global() {
+ doWork(SomeConstant, SomeDictionary);
+}
+
+NSString *provide_str();
+CFDictionaryRef provide_dict();
+void use_const_local() {
+ doWork(provide_str(), provide_dict());
+ // expected-warning@-1{{Call argument for parameter 'str' is unretained and unsafe}}
+ // expected-warning@-2{{Call argument for parameter 'dict' is unretained and unsafe}}
+}
+
+} // namespace const_global
+
@interface TestObject : NSObject
- (void)doWork:(NSString *)msg, ...;
- (void)doWorkOnSelf;
diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm
index 92a718f7e3a4c..a84bee8529645 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm
@@ -25,6 +25,26 @@ void bar() {
} // namespace raw_ptr
+namespace const_global {
+
+extern NSString * const SomeConstant;
+extern CFDictionaryRef const SomeDictionary;
+void doWork(NSString *, CFDictionaryRef);
+void use_const_global() {
+ doWork(SomeConstant, SomeDictionary);
+}
+
+NSString *provide_str();
+CFDictionaryRef provide_dict();
+void use_const_local() {
+ NSString * const str = provide_str();
+ CFDictionaryRef dict = provide_dict();
+ // expected-warning@-1{{Local variable 'dict' is unretained and unsafe [alpha.webkit.UnretainedLocalVarsChecker]}}
+ doWork(str, dict);
+}
+
+} // namespace const_global
+
@interface AnotherObj : NSObject
- (void)foo:(SomeObj *)obj;
@end
diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm
index a71a80ea3d647..10f7c9acb7a3c 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm
@@ -387,6 +387,27 @@ unsigned ccf(CFTypeRef obj) {
} // ptr_conversion
+namespace const_global {
+
+extern NSString * const SomeConstant;
+extern CFDictionaryRef const SomeDictionary;
+void doWork(NSString *, CFDictionaryRef);
+void use_const_global() {
+ doWork(SomeConstant, SomeDictionary);
+}
+
+NSString *provide_str();
+CFDictionaryRef provide_dict();
+void use_const_local() {
+ NSString * const str = provide_str();
+ // expected-warning@-1{{Local variable 'str' is unretained and unsafe [alpha.webkit.UnretainedLocalVarsChecker]}}
+ CFDictionaryRef dict = provide_dict();
+ // expected-warning@-1{{Local variable 'dict' is unretained and unsafe [alpha.webkit.UnretainedLocalVarsChecker]}}
+ doWork(str, dict);
+}
+
+} // namespace const_global
+
bool doMoreWorkOpaque(OtherObj*);
SomeObj* provide();
|
@llvm/pr-subscribers-clang Author: Ryosuke Niwa (rniwa) ChangesThis PR makes WebKit checkers treat a variable with global storage as safe instead of constraining to ones that start with k or _k. Full diff: https://github.com/llvm/llvm-project/pull/136170.diff 5 Files Affected:
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
index c36c925c0d2d2..88b98756b2ca8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp
@@ -30,12 +30,11 @@ bool tryToFindPtrOrigin(
std::function<bool(const clang::Expr *, bool)> callback) {
while (E) {
if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
- auto *ValDecl = DRE->getDecl();
- auto QT = ValDecl->getType();
- auto ValName = ValDecl->getName();
- if (ValDecl && (ValName.starts_with('k') || ValName.starts_with("_k")) &&
- QT.isConstQualified()) { // Treat constants such as kCF* as safe.
- return callback(E, true);
+ if (auto *VD = dyn_cast_or_null<VarDecl>(DRE->getDecl())) {
+ auto QT = VD->getType();
+ if (VD->hasGlobalStorage() && QT.isConstQualified()) {
+ return callback(E, true);
+ }
}
}
if (auto *tempExpr = dyn_cast<MaterializeTemporaryExpr>(E)) {
diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-call-args-arc.mm b/clang/test/Analysis/Checkers/WebKit/unretained-call-args-arc.mm
index 4207c1836079f..fa866258a2f6d 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-call-args-arc.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-call-args-arc.mm
@@ -18,6 +18,24 @@ void foo() {
} // namespace raw_ptr
+namespace const_global {
+
+extern NSString * const SomeConstant;
+extern CFDictionaryRef const SomeDictionary;
+void doWork(NSString *str, CFDictionaryRef dict);
+void use_const_global() {
+ doWork(SomeConstant, SomeDictionary);
+}
+
+NSString *provide_str();
+CFDictionaryRef provide_dict();
+void use_const_local() {
+ doWork(provide_str(), provide_dict());
+ // expected-warning@-1{{Call argument for parameter 'dict' is unretained and unsafe}}
+}
+
+} // namespace const_global
+
@interface AnotherObj : NSObject
- (void)foo:(SomeObj *)obj;
- (SomeObj *)getSomeObj;
diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm b/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
index eb36b49313d42..c33d53b047c2e 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-call-args.mm
@@ -415,6 +415,25 @@ void idcf(CFTypeRef obj) {
} // ptr_conversion
+namespace const_global {
+
+extern NSString * const SomeConstant;
+extern CFDictionaryRef const SomeDictionary;
+void doWork(NSString *str, CFDictionaryRef dict);
+void use_const_global() {
+ doWork(SomeConstant, SomeDictionary);
+}
+
+NSString *provide_str();
+CFDictionaryRef provide_dict();
+void use_const_local() {
+ doWork(provide_str(), provide_dict());
+ // expected-warning@-1{{Call argument for parameter 'str' is unretained and unsafe}}
+ // expected-warning@-2{{Call argument for parameter 'dict' is unretained and unsafe}}
+}
+
+} // namespace const_global
+
@interface TestObject : NSObject
- (void)doWork:(NSString *)msg, ...;
- (void)doWorkOnSelf;
diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm
index 92a718f7e3a4c..a84bee8529645 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars-arc.mm
@@ -25,6 +25,26 @@ void bar() {
} // namespace raw_ptr
+namespace const_global {
+
+extern NSString * const SomeConstant;
+extern CFDictionaryRef const SomeDictionary;
+void doWork(NSString *, CFDictionaryRef);
+void use_const_global() {
+ doWork(SomeConstant, SomeDictionary);
+}
+
+NSString *provide_str();
+CFDictionaryRef provide_dict();
+void use_const_local() {
+ NSString * const str = provide_str();
+ CFDictionaryRef dict = provide_dict();
+ // expected-warning@-1{{Local variable 'dict' is unretained and unsafe [alpha.webkit.UnretainedLocalVarsChecker]}}
+ doWork(str, dict);
+}
+
+} // namespace const_global
+
@interface AnotherObj : NSObject
- (void)foo:(SomeObj *)obj;
@end
diff --git a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm
index a71a80ea3d647..10f7c9acb7a3c 100644
--- a/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm
+++ b/clang/test/Analysis/Checkers/WebKit/unretained-local-vars.mm
@@ -387,6 +387,27 @@ unsigned ccf(CFTypeRef obj) {
} // ptr_conversion
+namespace const_global {
+
+extern NSString * const SomeConstant;
+extern CFDictionaryRef const SomeDictionary;
+void doWork(NSString *, CFDictionaryRef);
+void use_const_global() {
+ doWork(SomeConstant, SomeDictionary);
+}
+
+NSString *provide_str();
+CFDictionaryRef provide_dict();
+void use_const_local() {
+ NSString * const str = provide_str();
+ // expected-warning@-1{{Local variable 'str' is unretained and unsafe [alpha.webkit.UnretainedLocalVarsChecker]}}
+ CFDictionaryRef dict = provide_dict();
+ // expected-warning@-1{{Local variable 'dict' is unretained and unsafe [alpha.webkit.UnretainedLocalVarsChecker]}}
+ doWork(str, dict);
+}
+
+} // namespace const_global
+
bool doMoreWorkOpaque(OtherObj*);
SomeObj* provide();
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Thank you for the review! |
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/59/builds/16465 Here is the relevant piece of the build log for the reference
|
This PR makes WebKit checkers treat a variable with global storage as safe instead of constraining to ones that start with k or _k.
This PR makes WebKit checkers treat a variable with global storage as safe instead of constraining to ones that start with k or _k.
This PR makes WebKit checkers treat a variable with global storage as safe instead of constraining to ones that start with k or _k.
This PR makes WebKit checkers treat a variable with global storage as safe instead of constraining to ones that start with k or _k.
This PR makes WebKit checkers treat a variable with global storage as safe instead of constraining to ones that start with k or _k.