[cfe-commits] r128376 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDecl.cpp test/PCH/pragma-diag-section.cpp test/PCH/pragma-diag.c test/PCH/rdar8852495.c test/Preprocessor/pragma_diagnostic_sections.cpp

Chandler Carruth chandlerc at gmail.com
Sun Mar 27 02:46:56 PDT 2011


Author: chandlerc
Date: Sun Mar 27 04:46:56 2011
New Revision: 128376

URL: http://llvm.org/viewvc/llvm-project?rev=128376&view=rev
Log:
Diagnose uninitialized uses of a variable within its own initializer.
This is basically the same idea as the warning on uninitialized uses of
fields within an initializer list. As such, it is on by default and
under -Wuninitialized.

Original patch by Richard Trieu, with some massaging from me on the
wording and grouping of the diagnostics.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/PCH/pragma-diag-section.cpp
    cfe/trunk/test/PCH/pragma-diag.c
    cfe/trunk/test/PCH/rdar8852495.c
    cfe/trunk/test/Preprocessor/pragma_diagnostic_sections.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=128376&r1=128375&r2=128376&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Mar 27 04:46:56 2011
@@ -871,6 +871,9 @@
   "uninitialized reference member is here">;
 def warn_field_is_uninit : Warning<"field is uninitialized when used here">,
   InGroup<Uninitialized>;
+def warn_uninit_self_reference_in_init : Warning<
+  "variable %0 is uninitialized when used within its own initialization">,
+  InGroup<Uninitialized>;
 def warn_uninit_var : Warning<"variable %0 is possibly uninitialized when used here">,
   InGroup<Uninitialized>, DefaultIgnore;
 def warn_maybe_uninit_var :

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=128376&r1=128375&r2=128376&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Mar 27 04:46:56 2011
@@ -25,6 +25,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/EvaluatedExprVisitor.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/CharUnits.h"
@@ -4664,6 +4665,46 @@
   return true;
 }
 
+namespace {
+  // Visits an initialization expression to see if OrigDecl is evaluated in
+  // its own initialization and throws a warning if it does.
+  class SelfReferenceChecker
+      : public EvaluatedExprVisitor<SelfReferenceChecker> {
+    Sema &S;
+    Decl *OrigDecl;
+
+  public:
+    typedef EvaluatedExprVisitor<SelfReferenceChecker> Inherited;
+
+    SelfReferenceChecker(Sema &S, Decl *OrigDecl) : Inherited(S.Context),
+                                                    S(S), OrigDecl(OrigDecl) { }
+
+    void VisitExpr(Expr *E) {
+      if (isa<ObjCMessageExpr>(*E)) return;
+      Inherited::VisitExpr(E);
+    }
+
+    void VisitImplicitCastExpr(ImplicitCastExpr *E) {
+      CheckForSelfReference(E);
+      Inherited::VisitImplicitCastExpr(E);
+    }
+
+    void CheckForSelfReference(ImplicitCastExpr *E) {
+      if (E->getCastKind() != CK_LValueToRValue) return;
+      Expr* SubExpr = E->getSubExpr()->IgnoreParenImpCasts();
+      DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr);
+      if (!DRE) return;
+      Decl* ReferenceDecl = DRE->getDecl();
+      if (OrigDecl != ReferenceDecl) return;
+      LookupResult Result(S, DRE->getNameInfo(), Sema::LookupOrdinaryName,
+                          Sema::NotForRedeclaration);
+      S.Diag(SubExpr->getLocStart(), diag::warn_uninit_self_reference_in_init)
+        << Result.getLookupName() << OrigDecl->getLocation()
+        << SubExpr->getSourceRange();
+    }
+  };
+}
+
 /// AddInitializerToDecl - Adds the initializer Init to the
 /// declaration dcl. If DirectInit is true, this is C++ direct
 /// initialization rather than copy initialization.
@@ -4674,6 +4715,8 @@
   if (RealDecl == 0 || RealDecl->isInvalidDecl())
     return;
 
+  SelfReferenceChecker(*this, RealDecl).VisitExpr(Init);
+
   if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(RealDecl)) {
     // With declarators parsed the way they are, the parser cannot
     // distinguish between a normal initializer and a pure-specifier.
@@ -5231,7 +5274,7 @@
     if (Decl *D = Group[i])
       Decls.push_back(D);
 
-  return BuildDeclaratorGroup(Decls.data(), Decls.size(), 
+  return BuildDeclaratorGroup(Decls.data(), Decls.size(),
                               DS.getTypeSpecType() == DeclSpec::TST_auto);
 }
 

Modified: cfe/trunk/test/PCH/pragma-diag-section.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/pragma-diag-section.cpp?rev=128376&r1=128375&r2=128376&view=diff
==============================================================================
--- cfe/trunk/test/PCH/pragma-diag-section.cpp (original)
+++ cfe/trunk/test/PCH/pragma-diag-section.cpp Sun Mar 27 04:46:56 2011
@@ -12,7 +12,10 @@
 #pragma clang diagnostic ignored "-Wtautological-compare"
 template <typename T>
 struct TS {
-    void m() { T b = b==b; }
+    void m() {
+      T a = 0;
+      T b = a==a;
+    }
 };
 #pragma clang diagnostic pop
 

Modified: cfe/trunk/test/PCH/pragma-diag.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/pragma-diag.c?rev=128376&r1=128375&r2=128376&view=diff
==============================================================================
--- cfe/trunk/test/PCH/pragma-diag.c (original)
+++ cfe/trunk/test/PCH/pragma-diag.c Sun Mar 27 04:46:56 2011
@@ -13,7 +13,8 @@
 #else
 
 void f() {
-  int b = b==b;
+  int a = 0;
+  int b = a==a;
 }
 
 #endif

Modified: cfe/trunk/test/PCH/rdar8852495.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/rdar8852495.c?rev=128376&r1=128375&r2=128376&view=diff
==============================================================================
--- cfe/trunk/test/PCH/rdar8852495.c (original)
+++ cfe/trunk/test/PCH/rdar8852495.c Sun Mar 27 04:46:56 2011
@@ -16,7 +16,8 @@
 #else
 
 int f() {
-  int b = b==b;
+  int a;
+  int b = a==a;
   unsigned x;
   signed y;
   return x == y;

Modified: cfe/trunk/test/Preprocessor/pragma_diagnostic_sections.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/pragma_diagnostic_sections.cpp?rev=128376&r1=128375&r2=128376&view=diff
==============================================================================
--- cfe/trunk/test/Preprocessor/pragma_diagnostic_sections.cpp (original)
+++ cfe/trunk/test/Preprocessor/pragma_diagnostic_sections.cpp Sun Mar 27 04:46:56 2011
@@ -2,14 +2,14 @@
 
 // rdar://8365684
 struct S {
-    void m1() { int b = b==b; } // expected-warning {{always evaluates to true}}
+    void m1() { int b; while (b==b); } // expected-warning {{always evaluates to true}}
 
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wtautological-compare"
-    void m2() { int b = b==b; }
+    void m2() { int b; while (b==b); }
 #pragma clang diagnostic pop
 
-    void m3() { int b = b==b; } // expected-warning {{always evaluates to true}}
+    void m3() { int b; while (b==b); } // expected-warning {{always evaluates to true}}
 };
 
 //------------------------------------------------------------------------------
@@ -18,7 +18,7 @@
 #pragma clang diagnostic ignored "-Wtautological-compare"
 template <typename T>
 struct TS {
-    void m() { T b = b==b; }
+    void m() { T b; while (b==b); }
 };
 #pragma clang diagnostic pop
 





More information about the cfe-commits mailing list