diff options
author | Ted Kremenek <kremenek@apple.com> | 2010-03-18 01:22:39 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2010-03-18 01:22:39 +0000 |
commit | ebd42f40803396d63bc59b77285d088cca61f53f (patch) | |
tree | af539c50c3cff116e78fff32639a35effcb2aa3c | |
parent | 9944c769b69b1904a7b16d3ce10fbdc9c67c764f (diff) |
Tweak dead stores checker to not emit a warning when initialization
a scalar variable with a scalar parameter. This is a
form of defensive programming. If the variable is unused,
it will be caused by -Wunused-variable.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98795 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Checker/CheckDeadStores.cpp | 25 | ||||
-rw-r--r-- | test/Analysis/dead-stores.c | 33 |
2 files changed, 37 insertions, 21 deletions
diff --git a/lib/Checker/CheckDeadStores.cpp b/lib/Checker/CheckDeadStores.cpp index 31f9390e62..d6ea187957 100644 --- a/lib/Checker/CheckDeadStores.cpp +++ b/lib/Checker/CheckDeadStores.cpp @@ -220,16 +220,25 @@ public: if (E->isConstantInitializer(Ctx)) return; - // Special case: check for initializations from constant - // variables. - // - // e.g. extern const int MyConstant; - // int x = MyConstant; - // if (DeclRefExpr *DRE=dyn_cast<DeclRefExpr>(E->IgnoreParenCasts())) - if (VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) + if (VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) { + // Special case: check for initialization from constant + // variables. + // + // e.g. extern const int MyConstant; + // int x = MyConstant; + // if (VD->hasGlobalStorage() && - VD->getType().isConstQualified()) return; + VD->getType().isConstQualified()) + return; + // Special case: check for initialization from scalar + // parameters. This is often a form of defensive + // programming. Non-scalars are still an error since + // because it more likely represents an actual algorithmic + // bug. + if (isa<ParmVarDecl>(VD) && VD->getType()->isScalarType()) + return; + } Report(V, DeadInit, V->getLocation(), E->getSourceRange()); } diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c index 9a266c9379..209ca6531c 100644 --- a/test/Analysis/dead-stores.c +++ b/test/Analysis/dead-stores.c @@ -1,18 +1,18 @@ -// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s -// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s -// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s -// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s -// RUN: %clang_cc1 -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s +// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-experimental-internal-checks -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s +// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s +// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=basic -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s +// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=basic -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s +// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-experimental-internal-checks -analyzer-check-objc-mem -analyzer-store=region -analyzer-constraints=range -analyzer-check-dead-stores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s void f1() { - int k, y; + int k, y; // expected-warning{{unused variable 'k'}} expected-warning{{unused variable 'y'}} int abc=1; - long idx=abc+3*5; // expected-warning {{never read}} + long idx=abc+3*5; // expected-warning {{never read}} expected-warning{{unused variable 'idx'}} } void f2(void *b) { char *c = (char*)b; // no-warning - char *d = b+1; // expected-warning {{never read}} + char *d = b+1; // expected-warning {{never read}} expected-warning{{unused variable 'd'}} printf("%s", c); // expected-warning{{implicitly declaring C library function 'printf' with type 'int (char const *, ...)'}} \ // expected-note{{please include the header <stdio.h> or explicitly provide a declaration for 'printf'}} } @@ -40,7 +40,7 @@ void f4(int k) { void f5() { int x = 4; // no-warning - int *p = &x; // expected-warning{{never read}} + int *p = &x; // expected-warning{{never read}} expected-warning{{unused variable 'p'}} } @@ -105,13 +105,20 @@ int f11b() { } int f12a(int y) { - int x = y; // expected-warning{{never read}} + int x = y; // expected-warning{{unused variable 'x'}} return 1; } int f12b(int y) { int x __attribute__((unused)) = y; // no-warning return 1; } +int f12c(int y) { + // Allow initialiation of scalar variables by parameters as a form of + // defensive programming. + int x = y; // no-warning + x = 1; + return x; +} // Filed with PR 2630. This code should produce no warnings. int f13(void) @@ -138,7 +145,7 @@ int f14(int count) { // Test case for <rdar://problem/6248086> void f15(unsigned x, unsigned y) { int count = x * y; // no-warning - int z[count]; + int z[count]; // expected-warning{{unused variable 'z'}} } int f16(int x) { @@ -367,7 +374,7 @@ void f23(int argc, char **argv) { } void f23_pos(int argc, char **argv) { - int shouldLog = (argc > 1); // expected-warning{{Value stored to 'shouldLog' during its initialization is never read}} + int shouldLog = (argc > 1); // expected-warning{{Value stored to 'shouldLog' during its initialization is never read}} expected-warning{{unused variable 'shouldLog'}} ^{ f23_aux("I did too use it!\n"); }(); @@ -377,7 +384,7 @@ void f24_A(int y) { // FIXME: One day this should be reported as dead since 'z = x + y' is dead. int x = (y > 2); // no-warning ^ { - int z = x + y; // expected-warning{{Value stored to 'z' during its initialization is never read}} + int z = x + y; // expected-warning{{Value stored to 'z' during its initialization is never read}} expected-warning{{unused variable 'z'}} }(); } |