summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2013-01-17 08:49:22 +0000
committerDavid Blaikie <dblaikie@gmail.com>2013-01-17 08:49:22 +0000
commitb61b815fc83bca62e498a9951189a607a0d41f34 (patch)
tree6e207230810f896de3298ccedd7b4474fe9e8bb6
parent98154a917f1b24a0cd8369f217e3a3976a5dfa2a (diff)
downloadbcm5719-llvm-b61b815fc83bca62e498a9951189a607a0d41f34.tar.gz
bcm5719-llvm-b61b815fc83bca62e498a9951189a607a0d41f34.zip
Improve -Wreorder to handle cases of anonymous class member ordering
llvm-svn: 172707
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp37
-rw-r--r--clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp11
2 files changed, 22 insertions, 26 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index c794d7e964a..61d8dfce5fc 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -3214,13 +3214,17 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
return HadError;
}
-static void *GetKeyForTopLevelField(FieldDecl *Field) {
- // For anonymous unions, use the class declaration as the key.
+static void PopulateKeysForFields(FieldDecl *Field, SmallVectorImpl<const void*> &IdealInits) {
if (const RecordType *RT = Field->getType()->getAs<RecordType>()) {
- if (RT->getDecl()->isAnonymousStructOrUnion())
- return RT->getDecl();
+ const RecordDecl *RD = RT->getDecl();
+ if (RD->isAnonymousStructOrUnion()) {
+ for (RecordDecl::field_iterator Field = RD->field_begin(),
+ E = RD->field_end(); Field != E; ++Field)
+ PopulateKeysForFields(*Field, IdealInits);
+ return;
+ }
}
- return Field;
+ IdealInits.push_back(Field);
}
static void *GetKeyForBase(ASTContext &Context, QualType BaseType) {
@@ -3232,26 +3236,7 @@ static void *GetKeyForMember(ASTContext &Context,
if (!Member->isAnyMemberInitializer())
return GetKeyForBase(Context, QualType(Member->getBaseClass(), 0));
- // For fields injected into the class via declaration of an anonymous union,
- // use its anonymous union class declaration as the unique key.
- FieldDecl *Field = Member->getAnyMember();
-
- // If the field is a member of an anonymous struct or union, our key
- // is the anonymous record decl that's a direct child of the class.
- RecordDecl *RD = Field->getParent();
- if (RD->isAnonymousStructOrUnion()) {
- while (true) {
- RecordDecl *Parent = cast<RecordDecl>(RD->getDeclContext());
- if (Parent->isAnonymousStructOrUnion())
- RD = Parent;
- else
- break;
- }
-
- return RD;
- }
-
- return Field;
+ return Member->getAnyMember();
}
static void DiagnoseBaseOrMemInitializerOrder(
@@ -3302,7 +3287,7 @@ static void DiagnoseBaseOrMemInitializerOrder(
if (Field->isUnnamedBitfield())
continue;
- IdealInitKeys.push_back(GetKeyForTopLevelField(*Field));
+ PopulateKeysForFields(*Field, IdealInitKeys);
}
unsigned NumIdealInits = IdealInitKeys.size();
diff --git a/clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp b/clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
index 8c254e5515b..6d38ec95fbf 100644
--- a/clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
+++ b/clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp
@@ -130,3 +130,14 @@ namespace PR7179 {
};
};
}
+
+namespace test3 {
+ struct foo {
+ struct {
+ int a;
+ int b;
+ };
+ foo() : b(), a() { // expected-warning {{field 'b' will be initialized after field 'a'}}
+ }
+ };
+}
OpenPOWER on IntegriCloud