aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-03-18 01:22:39 +0000
committerTed Kremenek <kremenek@apple.com>2010-03-18 01:22:39 +0000
commitebd42f40803396d63bc59b77285d088cca61f53f (patch)
treeaf539c50c3cff116e78fff32639a35effcb2aa3c
parent9944c769b69b1904a7b16d3ce10fbdc9c67c764f (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.cpp25
-rw-r--r--test/Analysis/dead-stores.c33
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'}}
}();
}