[cfe-commits] r168031 - in /cfe/trunk: lib/Sema/SemaDeclCXX.cpp test/SemaCXX/constructor-initializer.cpp

Nick Lewycky nicholas at mxc.ca
Thu Nov 15 00:19:20 PST 2012


Author: nicholas
Date: Thu Nov 15 02:19:20 2012
New Revision: 168031

URL: http://llvm.org/viewvc/llvm-project?rev=168031&view=rev
Log:
Teach the uninitialized field warning about anonymous structs and union members.
Fixes PR14073!

Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/SemaCXX/constructor-initializer.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=168031&r1=168030&r2=168031&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Nov 15 02:19:20 2012
@@ -1795,7 +1795,11 @@
   public:
     typedef EvaluatedExprVisitor<UninitializedFieldVisitor> Inherited;
     UninitializedFieldVisitor(Sema &S, ValueDecl *VD) : Inherited(S.Context),
-                                                        S(S), VD(VD) {
+                                                        S(S) {
+      if (IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(VD))
+        this->VD = IFD->getAnonField();
+      else
+        this->VD = VD;
     }
 
     void HandleExpr(Expr *E) {
@@ -1812,23 +1816,33 @@
 
       if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
         if (isa<EnumConstantDecl>(ME->getMemberDecl()))
-            return;
+          return;
+
+        // FieldME is the inner-most MemberExpr that is not an anonymous struct
+        // or union.
+        MemberExpr *FieldME = ME;
+
         Expr *Base = E;
         while (isa<MemberExpr>(Base)) {
-          ME = dyn_cast<MemberExpr>(Base);
-          if (VarDecl *VarD = dyn_cast<VarDecl>(ME->getMemberDecl()))
-            if (VarD->hasGlobalStorage())
-              return;
+          ME = cast<MemberExpr>(Base);
+
+          if (isa<VarDecl>(ME->getMemberDecl()))
+            return;
+
+          if (FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))
+            if (!FD->isAnonymousStructOrUnion())
+              FieldME = ME;
+
           Base = ME->getBase();
         }
 
-        if (VD == ME->getMemberDecl() && isa<CXXThisExpr>(Base)) {
+        if (VD == FieldME->getMemberDecl() && isa<CXXThisExpr>(Base)) {
           unsigned diag = VD->getType()->isReferenceType()
               ? diag::warn_reference_field_is_uninit
               : diag::warn_field_is_uninit;
-          S.Diag(ME->getExprLoc(), diag) << ME->getMemberNameInfo().getName();
-          return;
+          S.Diag(FieldME->getExprLoc(), diag) << VD;
         }
+        return;
       }
 
       if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) {

Modified: cfe/trunk/test/SemaCXX/constructor-initializer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constructor-initializer.cpp?rev=168031&r1=168030&r2=168031&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constructor-initializer.cpp (original)
+++ cfe/trunk/test/SemaCXX/constructor-initializer.cpp Thu Nov 15 02:19:20 2012
@@ -283,3 +283,9 @@
       int member; // expected-error {{expected ')'}}
   };
 }
+
+namespace PR14073 {
+  struct S1 { union { int n; }; S1() : n(n) {} };  // expected-warning {{field 'n' is uninitialized when used here}}
+  struct S2 { union { union { int n; }; char c; }; S2() : n(n) {} };  // expected-warning {{field 'n' is uninitialized when used here}}
+  struct S3 { struct { int n; }; S3() : n(n) {} };  // expected-warning {{field 'n' is uninitialized when used here}}
+}





More information about the cfe-commits mailing list