Only warn at self-initialization if some later use is always uninitialized.

llvm-svn: 142538
This commit is contained in:
Matt Beaumont-Gay 2011-10-19 18:53:03 +00:00
parent e0d0908356
commit 4b489fa629
2 changed files with 22 additions and 3 deletions

View File

@ -586,9 +586,10 @@ public:
// Specially handle the case where we have uses of an uninitialized
// variable, but the root cause is an idiomatic self-init. We want
// to report the diagnostic at the self-init since that is the root cause.
if (!vec->empty() && hasSelfInit)
if (!vec->empty() && hasSelfInit && hasAlwaysUninitializedUse(vec))
DiagnoseUninitializedUse(S, vd, vd->getInit()->IgnoreParenCasts(),
true, /* alwaysReportSelfInit */ true);
/* isAlwaysUninit */ true,
/* alwaysReportSelfInit */ true);
else {
// Sort the uses by their SourceLocations. While not strictly
// guaranteed to produce them in line/column order, this will provide
@ -610,6 +611,16 @@ public:
}
delete uses;
}
private:
static bool hasAlwaysUninitializedUse(const UsesVec* vec) {
for (UsesVec::const_iterator i = vec->begin(), e = vec->end(); i != e; ++i) {
if (i->second) {
return true;
}
}
return false;
}
};
}

View File

@ -44,6 +44,15 @@ int test7(int y) {
return x; // expected-warning{{variable 'x' may be uninitialized when used here}}
}
int test7b(int y) {
int x = x; // expected-note{{variable 'x' is declared here}}
if (y)
x = 1;
// Warn with "may be uninitialized" here (not "is uninitialized"), since the
// self-initialization is intended to suppress a -Wuninitialized warning.
return x; // expected-warning{{variable 'x' may be uninitialized when used here}}
}
int test8(int y) {
int x;
if (y)
@ -415,4 +424,3 @@ void rdar9432305(float *P) {
for (; i < 10000; ++i) // expected-warning {{variable 'i' is uninitialized when used here}}
P[i] = 0.0f;
}