Skip to content

Commit 1319614

Browse files
committed
[analyzer] Weaken assertion in trackNullOrUndefValue()
We should ignore paren casts when making sure that the semantic expression in a PseudoObjectExpr for an ObjC getter is a message send. This has no other intended functionality change. Adding a test for this exposed an interesting issue in another test case that only manifests under ARC. trackNullOrUndefValue() is not properly suppressing for nil values that are the result of nil propagation from a nil receiver when the nil is returned from a function. I've added a FIXME for that missing suppression. rdar://problem/27290568 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@279181 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent bf02f12 commit 1319614

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,7 @@ static const Expr *peelOffOuterExpr(const Expr *Ex,
916916
if (PropRef && PropRef->isMessagingGetter()) {
917917
const Expr *GetterMessageSend =
918918
POE->getSemanticExpr(POE->getNumSemanticExprs() - 1);
919-
assert(isa<ObjCMessageExpr>(GetterMessageSend));
919+
assert(isa<ObjCMessageExpr>(GetterMessageSend->IgnoreParenCasts()));
920920
return peelOffOuterExpr(GetterMessageSend, N);
921921
}
922922
}

test/Analysis/inlining/false-positive-suppression.m

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
22
// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -DSUPPRESSED=1 %s
3+
// RUN: %clang_cc1 -analyze -analyzer-checker=core -fobjc-arc -verify -DSUPPRESSED=1 %s
34
// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s
45

5-
#ifdef SUPPRESSED
6+
#define ARC __has_feature(objc_arc)
7+
8+
#if defined(SUPPRESSED) && !ARC
69
// expected-no-diagnostics
710
#endif
811

@@ -24,8 +27,9 @@ void testNilReceiverHelperA(int *x) {
2427

2528
void testNilReceiverHelperB(int *x) {
2629
*x = 1;
27-
#ifndef SUPPRESSED
28-
// expected-warning@-2 {{Dereference of null pointer}}
30+
// FIXME: Suppression for this case isn't working under ARC. It should.
31+
#if !defined(SUPPRESSED) || (defined(SUPPRESSED) && ARC)
32+
// expected-warning@-3 {{Dereference of null pointer}}
2933
#endif
3034
}
3135

@@ -40,13 +44,17 @@ void testNilReceiver(int coin) {
4044
// FALSE NEGATIVES (over-suppression)
4145

4246
__attribute__((objc_root_class))
43-
@interface SomeClass
47+
@interface SomeClass {
48+
int ivar;
49+
}
4450
-(int *)methodReturningNull;
4551

4652
@property(readonly) int *propertyReturningNull;
4753

4854
@property(readonly) int *synthesizedProperty;
4955

56+
@property(readonly) SomeClass *propertyReturningNil;
57+
5058
@end
5159

5260
@interface SubOfSomeClass : SomeClass
@@ -64,6 +72,10 @@ -(int *)propertyReturningNull {
6472
return 0;
6573
}
6674

75+
-(SomeClass *)propertyReturningNil {
76+
return 0;
77+
}
78+
6779
+(int *)classPropertyReturningNull {
6880
return 0;
6981
}
@@ -103,6 +115,16 @@ void testClassPropertyReturningNull() {
103115
#endif
104116
}
105117

118+
@implementation SomeClass (ForTestOfPropertyReturningNil)
119+
void testPropertyReturningNil(SomeClass *sc) {
120+
SomeClass *result = sc.propertyReturningNil;
121+
result->ivar = 1;
122+
#ifndef SUPPRESSED
123+
// expected-warning@-2 {{Access to instance variable 'ivar' results in a dereference of a null pointer (loaded from variable 'result')}}
124+
#endif
125+
}
126+
@end
127+
106128
void testSynthesizedPropertyReturningNull(SomeClass *sc) {
107129
if (sc.synthesizedProperty)
108130
return;

0 commit comments

Comments
 (0)