diff options
author | David Blaikie <dblaikie@gmail.com> | 2013-01-17 08:49:22 +0000 |
---|---|---|
committer | David Blaikie <dblaikie@gmail.com> | 2013-01-17 08:49:22 +0000 |
commit | b61b815fc83bca62e498a9951189a607a0d41f34 (patch) | |
tree | 6e207230810f896de3298ccedd7b4474fe9e8bb6 | |
parent | 98154a917f1b24a0cd8369f217e3a3976a5dfa2a (diff) | |
download | bcm5719-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.cpp | 37 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-reorder-ctor-initialization.cpp | 11 |
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'}} + } + }; +} |