From: Matt Beaumont-Gay Date: Wed, 19 Oct 2011 18:53:03 +0000 (+0000) Subject: Only warn at self-initialization if some later use is always uninitialized. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0d381810da19dd7677b9a79fca516d298fa5addb;p=clang Only warn at self-initialization if some later use is always uninitialized. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142538 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index babb8af18b..a8ee0b8617 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -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; +} }; } diff --git a/test/Sema/uninit-variables.c b/test/Sema/uninit-variables.c index 49af4f3226..d62186df73 100644 --- a/test/Sema/uninit-variables.c +++ b/test/Sema/uninit-variables.c @@ -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; } -