[cfe-commits] r128894 - in /cfe/trunk: lib/Sema/AnalysisBasedWarnings.cpp test/Sema/uninit-variables.c test/SemaCXX/uninitialized.cpp
Chandler Carruth
chandlerc at gmail.com
Tue Apr 5 10:41:31 PDT 2011
Author: chandlerc
Date: Tue Apr 5 12:41:31 2011
New Revision: 128894
URL: http://llvm.org/viewvc/llvm-project?rev=128894&view=rev
Log:
Fix PR9624 by explicitly disabling uninitialized warnings for direct self-init:
int x = x;
GCC disables its warnings on this construct as a way of indicating that
the programmer intentionally wants the variable to be uninitialized.
Only the warning on the initializer is turned off in this iteration.
This makes the code a lot more ugly, but starts commenting the
surprising behavior here. This is a WIP, I want to refactor it
substantially for clarity, and to determine whether subsequent warnings
should be suppressed or not.
Modified:
cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
cfe/trunk/test/Sema/uninit-variables.c
cfe/trunk/test/SemaCXX/uninitialized.cpp
Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=128894&r1=128893&r2=128894&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original)
+++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Tue Apr 5 12:41:31 2011
@@ -410,16 +410,6 @@
};
}
-static bool isSelfInit(ASTContext &Context,
- const VarDecl *VD, const DeclRefExpr *DR) {
- if (const Expr *E = VD->getInit()) {
- ContainsReference CR(Context, DR);
- CR.Visit(const_cast<Expr*>(E));
- return CR.doesContainReference();
- }
- return false;
-}
-
typedef std::pair<const Expr*, bool> UninitUse;
namespace {
@@ -473,17 +463,37 @@
for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve; ++vi)
{
const bool isAlwaysUninit = vi->second;
- bool showDefinition = true;
+ bool isSelfInit = false;
if (const DeclRefExpr *dr = dyn_cast<DeclRefExpr>(vi->first)) {
if (isAlwaysUninit) {
- if (isSelfInit(S.Context, vd, dr)) {
+ // Inspect the initializer of the variable declaration which is
+ // being referenced prior to its initialization. We emit
+ // specialized diagnostics for self-initialization, and we
+ // specifically avoid warning about self references which take the
+ // form of:
+ //
+ // int x = x;
+ //
+ // This is used to indicate to GCC that 'x' is intentionally left
+ // uninitialized. Proven code paths which access 'x' in
+ // an uninitialized state after this will still warn.
+ //
+ // TODO: Should we suppress maybe-uninitialized warnings for
+ // variables initialized in this way?
+ if (const Expr *E = vd->getInit()) {
+ if (dr == E->IgnoreParenImpCasts())
+ continue;
+
+ ContainsReference CR(S.Context, dr);
+ CR.Visit(const_cast<Expr*>(E));
+ isSelfInit = CR.doesContainReference();
+ }
+ if (isSelfInit) {
S.Diag(dr->getLocStart(),
diag::warn_uninit_self_reference_in_init)
<< vd->getDeclName() << vd->getLocation() << dr->getSourceRange();
- showDefinition = false;
- }
- else {
+ } else {
S.Diag(dr->getLocStart(), diag::warn_uninit_var)
<< vd->getDeclName() << dr->getSourceRange();
}
@@ -501,8 +511,9 @@
<< vd->getDeclName();
}
- // Report where the variable was declared.
- if (showDefinition)
+ // Report where the variable was declared when the use wasn't within
+ // the initializer of that declaration.
+ if (!isSelfInit)
S.Diag(vd->getLocStart(), diag::note_uninit_var_def)
<< vd->getDeclName();
Modified: cfe/trunk/test/Sema/uninit-variables.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/uninit-variables.c?rev=128894&r1=128893&r2=128894&view=diff
==============================================================================
--- cfe/trunk/test/Sema/uninit-variables.c (original)
+++ cfe/trunk/test/Sema/uninit-variables.c Tue Apr 5 12:41:31 2011
@@ -92,7 +92,7 @@
}
void test15() {
- int x = x; // expected-warning{{variable 'x' is uninitialized when used within its own initialization}}
+ int x = x; // no-warning: signals intended lack of initialization.
}
// Don't warn in the following example; shows dataflow confluence.
Modified: cfe/trunk/test/SemaCXX/uninitialized.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/uninitialized.cpp?rev=128894&r1=128893&r2=128894&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/uninitialized.cpp (original)
+++ cfe/trunk/test/SemaCXX/uninitialized.cpp Tue Apr 5 12:41:31 2011
@@ -7,7 +7,7 @@
// Test self-references within initializers which are guaranteed to be
// uninitialized.
-int a = a; // FIXME: This doesn't warn!? Seems it doesn't cast 'a' to an RValue.
+int a = a; // no-warning: used to signal intended lack of initialization.
int b = b + 1; // expected-warning {{variable 'b' is uninitialized when used within its own initialization}}
int c = (c + c); // expected-warning 2 {{variable 'c' is uninitialized when used within its own initialization}}
void test() {
More information about the cfe-commits
mailing list