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; +@property(readonly, nonnull) void (^propReturnsNonnullBlock)(void); +@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}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits