diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Analysis/CheckDeadStores.cpp | 11 | ||||
-rw-r--r-- | clang/test/Analysis/dead-stores.c | 20 |
2 files changed, 24 insertions, 7 deletions
diff --git a/clang/lib/Analysis/CheckDeadStores.cpp b/clang/lib/Analysis/CheckDeadStores.cpp index d5cb7ca7fdd..dd70ed7f2c1 100644 --- a/clang/lib/Analysis/CheckDeadStores.cpp +++ b/clang/lib/Analysis/CheckDeadStores.cpp @@ -134,16 +134,15 @@ public: if (DeclRefExpr* DR = dyn_cast<DeclRefExpr>(B->getLHS())) if (VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) { - Expr* RHS = B->getRHS()->IgnoreParenCasts(); - // Special case: check for assigning null to a pointer. // This is a common form of defensive programming. if (VD->getType()->isPointerType()) { - if (IntegerLiteral* L = dyn_cast<IntegerLiteral>(RHS)) - // FIXME: Probably should have an Expr::isNullPointerConstant. - if (L->getValue() == 0) - return; + if (B->getRHS()->isNullPointerConstant(Ctx, + Expr::NPC_ValueDependentIsNull)) + return; } + + Expr* RHS = B->getRHS()->IgnoreParenCasts(); // Special case: self-assignments. These are often used to shut up // "unused variable" compiler warnings. if (DeclRefExpr* RhsDR = dyn_cast<DeclRefExpr>(RHS)) diff --git a/clang/test/Analysis/dead-stores.c b/clang/test/Analysis/dead-stores.c index 811ac813c7e..2dfb5993566 100644 --- a/clang/test/Analysis/dead-stores.c +++ b/clang/test/Analysis/dead-stores.c @@ -34,7 +34,7 @@ void f4(int k) { k = 2; // expected-warning {{never read}} } - + void f5() { int x = 4; // no-warning @@ -55,6 +55,24 @@ int f7(int *p) { return 1; } +int f7b(int *p) { + // This is allowed for defensive programming. + p = (0); // no-warning + return 1; +} + +int f7c(int *p) { + // This is allowed for defensive programming. + p = (void*) 0; // no-warning + return 1; +} + +int f7d(int *p) { + // This is allowed for defensive programming. + p = (void*) (0); // no-warning + return 1; +} + int f8(int *p) { extern int *baz(); if ((p = baz())) // expected-warning{{Although the value}} |