[clang] 993060e - [StaticAnalyzer] Fix block pointer type nullability check
Balazs Benics via cfe-commits
cfe-commits at lists.llvm.org
Tue May 30 02:20:28 PDT 2023
Author: tripleCC
Date: 2023-05-30T11:20:05+02:00
New Revision: 993060e1d31d07e9c44e7164d24f9f495197ca87
URL: https://github.com/llvm/llvm-project/commit/993060e1d31d07e9c44e7164d24f9f495197ca87
DIFF: https://github.com/llvm/llvm-project/commit/993060e1d31d07e9c44e7164d24f9f495197ca87.diff
LOG: [StaticAnalyzer] Fix block pointer type nullability check
This patch fixes a false negative when the property type
is an objective-c block pointer.
Patch By tripleCC!
Differential Revision: https://reviews.llvm.org/D151651
Added:
Modified:
clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
clang/test/Analysis/nullability.mm
Removed:
################################################################################
diff --git a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
index da8529f4ea813..11d5e77db0c73 100644
--- a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
@@ -306,6 +306,10 @@ static NullConstraint getNullConstraint(DefinedOrUnknownSVal Val,
return NullConstraint::Unknown;
}
+static bool isValidPointerType(QualType T) {
+ return T->isAnyPointerType() || T->isBlockPointerType();
+}
+
const SymbolicRegion *
NullabilityChecker::getTrackRegion(SVal Val, bool CheckSuperRegion) const {
if (!NeedTracking)
@@ -621,7 +625,7 @@ void NullabilityChecker::checkPreStmt(const ReturnStmt *S,
if (!RetExpr)
return;
- if (!RetExpr->getType()->isAnyPointerType())
+ if (!isValidPointerType(RetExpr->getType()))
return;
ProgramStateRef State = C.getState();
@@ -754,7 +758,7 @@ void NullabilityChecker::checkPreCall(const CallEvent &Call,
if (!ArgSVal)
continue;
- if (!Param->getType()->isAnyPointerType() &&
+ if (!isValidPointerType(Param->getType()) &&
!Param->getType()->isReferenceType())
continue;
@@ -841,7 +845,7 @@ void NullabilityChecker::checkPostCall(const CallEvent &Call,
if (!FuncType)
return;
QualType ReturnType = FuncType->getReturnType();
- if (!ReturnType->isAnyPointerType())
+ if (!isValidPointerType(ReturnType))
return;
ProgramStateRef State = C.getState();
if (State->get<InvariantViolated>())
@@ -935,7 +939,7 @@ void NullabilityChecker::checkPostObjCMessage(const ObjCMethodCall &M,
if (!Decl)
return;
QualType RetType = Decl->getReturnType();
- if (!RetType->isAnyPointerType())
+ if (!isValidPointerType(RetType))
return;
ProgramStateRef State = C.getState();
@@ -1089,9 +1093,9 @@ void NullabilityChecker::checkPostStmt(const ExplicitCastExpr *CE,
CheckerContext &C) const {
QualType OriginType = CE->getSubExpr()->getType();
QualType DestType = CE->getType();
- if (!OriginType->isAnyPointerType())
+ if (!isValidPointerType(OriginType))
return;
- if (!DestType->isAnyPointerType())
+ if (!isValidPointerType(DestType))
return;
ProgramStateRef State = C.getState();
@@ -1215,7 +1219,7 @@ void NullabilityChecker::checkBind(SVal L, SVal V, const Stmt *S,
return;
QualType LocType = TVR->getValueType();
- if (!LocType->isAnyPointerType())
+ if (!isValidPointerType(LocType))
return;
ProgramStateRef State = C.getState();
diff --git a/clang/test/Analysis/nullability.mm b/clang/test/Analysis/nullability.mm
index f9b3fc60c5a02..44c241e07ee50 100644
--- a/clang/test/Analysis/nullability.mm
+++ b/clang/test/Analysis/nullability.mm
@@ -46,10 +46,13 @@ - (int *_Nonnull)returnsNonnull;
- (int *_Nullable)returnsNullable;
- (int *)returnsUnspecified;
- (void)takesNonnull:(int *_Nonnull)p;
+- (void)takesNonnullBlock:(void (^ _Nonnull)(void))block;
- (void)takesNullable:(int *_Nullable)p;
- (void)takesUnspecified:(int *)p;
@property(readonly, strong) NSString *stuff;
@property(readonly, nonnull) int *propReturnsNonnull;
+ at property(readonly, nonnull) void (^propReturnsNonnullBlock)(void);
+ at property(readonly, nullable) void (^propReturnsNullableBlock)(void);
@property(readonly, nullable) int *propReturnsNullable;
@property(readonly) int *propReturnsUnspecified;
@end
@@ -65,6 +68,7 @@ - (void)takesUnspecified:(int *)p;
void takesNullable(Dummy *_Nullable);
void takesNonnull(Dummy *_Nonnull);
void takesUnspecified(Dummy *);
+void takesNonnullBlock(void (^ _Nonnull)(void));
Dummy *_Nullable returnsNullable();
Dummy *_Nonnull returnsNonnull();
@@ -197,6 +201,7 @@ void testObjCPropertyReadNullability() {
switch (getRandom()) {
case 0:
[o takesNonnull:o.propReturnsNonnull]; // no-warning
+ [o takesNonnullBlock:o.propReturnsNonnullBlock]; // no-warning
break;
case 1:
[o takesNonnull:o.propReturnsUnspecified]; // no-warning
@@ -236,6 +241,9 @@ void testObjCPropertyReadNullability() {
assert(o.propReturnsNullable);
[o takesNonnull:o.propReturnsNullable]; // no-warning
break;
+ case 8:
+ [o takesNonnullBlock:o.propReturnsNullableBlock]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
+ break;
}
}
@@ -308,6 +316,11 @@ void testIndirectNilPassToNonnull() {
takesNonnull(p); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}}
}
+void testBlockIndirectNilPassToNonnull() {
+ void (^p)(void) = nil;
+ takesNonnullBlock(p); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}}
+}
+
void testConditionalNilPassToNonnull(Dummy *p) {
if (!p) {
takesNonnull(p); // expected-warning {{Null passed to a callee that requires a non-null 1st parameter}}
More information about the cfe-commits
mailing list