Skip to content

Commit 1dceba3

Browse files
tripleCCtripleCC
and
tripleCC
authored
[analyzer] Fix false negative when accessing a nonnull property from … (llvm#67563)
``` @interface A : NSObject @Property (nonnull, nonatomic, strong) NSString *name; + (nullable instancetype)shared; @EnD @[[A shared].name]; ``` Consider the code above, the nullability of the name property should depend on the result of the shared method. A warning is expected because of adding a nullable object to array. ObjCMessageExpr gets the actual type through Sema::getMessageSendResultType, instead of using the return type of MethodDecl directly. The final type is generated by considering the nullability of receiver and MethodDecl together. Thus, the RetType in NullabilityChecker should all be replaced with M.getOriginExpr()->getType(). Co-authored-by: tripleCC <[email protected]>
1 parent a6cdbba commit 1dceba3

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,14 @@ void NullabilityChecker::checkPostCall(const CallEvent &Call,
899899
const NullabilityState *TrackedNullability =
900900
State->get<NullabilityMap>(Region);
901901

902+
// ObjCMessageExpr gets the actual type through
903+
// Sema::getMessageSendResultType, instead of using the return type of
904+
// MethodDecl directly. The final type is generated by considering the
905+
// nullability of receiver and MethodDecl together. Thus, The type of
906+
// ObjCMessageExpr is prefer.
907+
if (const Expr *E = Call.getOriginExpr())
908+
ReturnType = E->getType();
909+
902910
if (!TrackedNullability &&
903911
getNullabilityAnnotation(ReturnType) == Nullability::Nullable) {
904912
State = State->set<NullabilityMap>(Region, Nullability::Nullable);
@@ -1053,7 +1061,7 @@ void NullabilityChecker::checkPostObjCMessage(const ObjCMethodCall &M,
10531061
}
10541062

10551063
// No tracked information. Use static type information for return value.
1056-
Nullability RetNullability = getNullabilityAnnotation(RetType);
1064+
Nullability RetNullability = getNullabilityAnnotation(Message->getType());
10571065

10581066
// Properties might be computed, which means the property value could
10591067
// theoretically change between calls even in commonly-observed cases like

clang/test/Analysis/nullability.mm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ - (void)takesUnspecified:(int *)p;
5555
@property(readonly, nullable) void (^propReturnsNullableBlock)(void);
5656
@property(readonly, nullable) int *propReturnsNullable;
5757
@property(readonly) int *propReturnsUnspecified;
58+
+ (nullable TestObject *)getNullableObject;
5859
@end
5960

6061
TestObject * getUnspecifiedTestObject();
@@ -256,6 +257,12 @@ void testObjCPropertyReadNullability() {
256257
case 8:
257258
[o takesNonnullBlock:o.propReturnsNullableBlock]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
258259
break;
260+
case 9:
261+
[o takesNonnull:getNullableTestObject().propReturnsNonnull]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
262+
break;
263+
case 10:
264+
[o takesNonnull:[TestObject getNullableObject].propReturnsNonnull]; // expected-warning {{Nullable pointer is passed to a callee that requires a non-null 1st parameter}}
265+
break;
259266
}
260267
}
261268

0 commit comments

Comments
 (0)