Skip to content

Commit

Permalink
[analyzer] trackNullOrUndefValue: always track through parentheses an…
Browse files Browse the repository at this point in the history
…d casts.

When trying to figure out where a null or undefined value came from,
parentheses and cast expressions are either completely irrelevant, or,
in the case of lvalue-to-rvale cast, straightforwardly lead us in the right
direction when we remove them.

There is a regression that causes a certain diagnostic to appear twice in the
path-notes.cpp test (changed to FIXME). It would be addressed in the next
commit.

Differential revision: https://reviews.llvm.org/D41254

llvm-svn: 321133
  • Loading branch information
haoNoQ committed Dec 20, 2017
1 parent aee3acb commit fee1010
Show file tree
Hide file tree
Showing 6 changed files with 596 additions and 335 deletions.
8 changes: 2 additions & 6 deletions clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
Expand Up @@ -985,12 +985,8 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N,
if (!S || !N)
return false;

if (const Expr *Ex = dyn_cast<Expr>(S)) {
Ex = Ex->IgnoreParenCasts();
const Expr *PeeledEx = peelOffOuterExpr(Ex, N);
if (Ex != PeeledEx)
S = PeeledEx;
}
if (const Expr *Ex = dyn_cast<Expr>(S))
S = peelOffOuterExpr(Ex, N);

const Expr *Inner = nullptr;
if (const Expr *Ex = dyn_cast<Expr>(S)) {
Expand Down
7 changes: 3 additions & 4 deletions clang/test/Analysis/inlining/false-positive-suppression.m
Expand Up @@ -5,7 +5,7 @@

#define ARC __has_feature(objc_arc)

#if defined(SUPPRESSED) && !ARC
#ifdef SUPPRESSED
// expected-no-diagnostics
#endif

Expand All @@ -27,9 +27,8 @@ void testNilReceiverHelperA(int *x) {

void testNilReceiverHelperB(int *x) {
*x = 1;
// FIXME: Suppression for this case isn't working under ARC. It should.
#if !defined(SUPPRESSED) || (defined(SUPPRESSED) && ARC)
// expected-warning@-3 {{Dereference of null pointer}}
#if !defined(SUPPRESSED)
// expected-warning@-2 {{Dereference of null pointer}}
#endif
}

Expand Down
33 changes: 33 additions & 0 deletions clang/test/Analysis/inlining/inline-defensive-checks.c
Expand Up @@ -197,6 +197,12 @@ void idcTrackConstraintThroughSymbolicRegion(int **x) {
**x = 7; // expected-warning{{Dereference of null pointer}}
}

void idcTrackConstraintThroughSymbolicRegionAndParens(int **x) {
idc(*x);
// FIXME: Should not warn.
*(*x) = 7; // expected-warning{{Dereference of null pointer}}
}

int *idcPlainNull(int coin) {
if (coin)
return 0;
Expand All @@ -208,3 +214,30 @@ void idcTrackZeroValueThroughSymbolicRegion(int coin, int **x) {
*x = idcPlainNull(coin);
**x = 7; // no-warning
}

void idcTrackZeroValueThroughSymbolicRegionAndParens(int coin, int **x) {
*x = idcPlainNull(coin);
*(*x) = 7; // no-warning
}

struct WithInt {
int i;
};

struct WithArray {
struct WithInt arr[1];
};

struct WithArray *idcPlainNullWithArray(int coin) {
if (coin)
return 0;
static struct WithArray S;
return &S;
}

void idcTrackZeroValueThroughSymbolicRegionWithArray(int coin, struct WithArray **s) {
*s = idcPlainNullWithArray(coin);
(*s)->arr[0].i = 1; // no-warning
// Same thing.
(*s)->arr->i = 1; // no-warning
}

0 comments on commit fee1010

Please sign in to comment.