[cfe-commits] r76630 - in /cfe/trunk: lib/Sema/SemaDeclCXX.cpp test/SemaCXX/warn-reorder-ctor-initialization.cpp

Eli Friedman eli.friedman at gmail.com
Tue Jul 21 12:28:13 PDT 2009


Author: efriedma
Date: Tue Jul 21 14:28:10 2009
New Revision: 76630

URL: http://llvm.org/viewvc/llvm-project?rev=76630&view=rev
Log:
Misc fixes for -Wreorder:

1. Make it work correctly with anonymous unions.
2. Don't compute it if the warning isn't enabled.
3. Optimize the algorithm slightly to make it linear time in the 
case where we don't produce any warnings.


Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/SemaCXX/warn-reorder-ctor-initialization.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=76630&r1=76629&r2=76630&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Jul 21 14:28:10 2009
@@ -774,6 +774,29 @@
                                         IdLoc);
 }
 
+static void *GetKeyForTopLevelField(FieldDecl *Field) {
+  // For anonymous unions, use the class declaration as the key.
+  if (const RecordType *RT = Field->getType()->getAsRecordType()) {
+    if (RT->getDecl()->isAnonymousStructOrUnion())
+      return static_cast<void *>(RT->getDecl());
+  }
+  return static_cast<void *>(Field);
+}
+
+static void *GetKeyForMember(CXXBaseOrMemberInitializer *Member) {
+  // For fields injected into the class via declaration of an anonymous union,
+  // use its anonymous union class declaration as the unique key.
+  if (FieldDecl *Field = Member->getMember()) {
+    if (Field->getDeclContext()->isRecord()) {
+      RecordDecl *RD = cast<RecordDecl>(Field->getDeclContext());
+      if (RD->isAnonymousStructOrUnion())
+        return static_cast<void *>(RD);
+    }
+    return static_cast<void *>(Field);
+  }
+  return static_cast<RecordType *>(Member->getBaseClass());
+}
+
 void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, 
                                 SourceLocation ColonLoc,
                                 MemInitTy **MemInits, unsigned NumMemInits) {
@@ -792,13 +815,7 @@
   for (unsigned i = 0; i < NumMemInits; i++) {
     CXXBaseOrMemberInitializer *Member = 
       static_cast<CXXBaseOrMemberInitializer*>(MemInits[i]);
-    void *KeyToMember = Member->getBaseOrMember();
-    // For fields injected into the class via declaration of an anonymous union,
-    // use its anonymous union class declaration as the unique key.
-    if (FieldDecl *Field = Member->getMember())
-      if (Field->getDeclContext()->isRecord() &&
-          cast<RecordDecl>(Field->getDeclContext())->isAnonymousStructOrUnion())
-        KeyToMember = static_cast<void *>(Field->getDeclContext());
+    void *KeyToMember = GetKeyForMember(Member);
     CXXBaseOrMemberInitializer *&PrevMember = Members[KeyToMember];
     if (!PrevMember) {
       PrevMember = Member;
@@ -823,6 +840,11 @@
     Constructor->setBaseOrMemberInitializers(Context, 
                     reinterpret_cast<CXXBaseOrMemberInitializer **>(MemInits), 
                     NumMemInits);
+  }
+  if (!err && (Diags.getDiagnosticLevel(diag::warn_base_initialized)
+               != Diagnostic::Ignored ||
+               Diags.getDiagnosticLevel(diag::warn_field_initialized)
+               != Diagnostic::Ignored)) {
     // Also issue warning if order of ctor-initializer list does not match order
     // of 1) base class declarations and 2) order of non-static data members.
     llvm::SmallVector<const void*, 32> AllBaseOrMembers;
@@ -846,7 +868,7 @@
     
     for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
          E = ClassDecl->field_end(); Field != E; ++Field)
-      AllBaseOrMembers.push_back(*Field);
+      AllBaseOrMembers.push_back(GetKeyForTopLevelField(*Field));
     
     int Last = AllBaseOrMembers.size();
     int curIndex = 0;
@@ -854,19 +876,13 @@
     for (unsigned i = 0; i < NumMemInits; i++) {
       CXXBaseOrMemberInitializer *Member = 
         static_cast<CXXBaseOrMemberInitializer*>(MemInits[i]);
-      void *MemberInCtorList;
-      if (Member->isBaseInitializer())
-        MemberInCtorList = Member->getBaseClass();
-      else
-        MemberInCtorList = Member->getMember();
-      
-      int j;
-      for (j = curIndex; j < Last; j++)
-        if (MemberInCtorList == AllBaseOrMembers[j])
+      void *MemberInCtorList = GetKeyForMember(Member);
+
+      for (; curIndex < Last; curIndex++)
+        if (MemberInCtorList == AllBaseOrMembers[curIndex])
           break;
-      if (j == Last) {
-        if (!PrevMember)
-          continue;
+      if (curIndex == Last) {
+        assert(PrevMember && "Member not in member list?!");
         // Initializer as specified in ctor-initializer list is out of order.
         // Issue a warning diagnostic.
         if (PrevMember->isBaseInitializer()) {
@@ -893,11 +909,11 @@
                diag::note_fieldorbase_initialized_here) << 1
             << BaseClass->getDesugaredType(true);
         }
+        for (curIndex = 0; curIndex < Last; curIndex++)
+          if (MemberInCtorList == AllBaseOrMembers[curIndex]) 
+            break;
       }
       PrevMember = Member;
-      for (curIndex=0; curIndex < Last; curIndex++)
-        if (MemberInCtorList == AllBaseOrMembers[curIndex]) 
-          break;
     }
   }
 }

Modified: cfe/trunk/test/SemaCXX/warn-reorder-ctor-initialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-reorder-ctor-initialization.cpp?rev=76630&r1=76629&r2=76630&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/warn-reorder-ctor-initialization.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-reorder-ctor-initialization.cpp Tue Jul 21 14:28:10 2009
@@ -73,4 +73,17 @@
 			// expected-note {{base 'struct V'}}
 };
 
-
+class Anon {
+  int c; union {int a,b;}; int d;
+  Anon() : c(10), b(1), d(2) {}
+};
+class Anon2 {
+  int c; union {int a,b;}; int d;
+  Anon2() : c(2),
+            d(10), // expected-warning {{member 'd' will be initialized after}}
+            b(1) {} // expected-note {{field b}}
+};
+class Anon3 {
+  union {int a,b;};
+  Anon3() : b(1) {}
+};





More information about the cfe-commits mailing list