[cfe-commits] r75168 - in /cfe/trunk: include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaDeclCXX.cpp test/SemaCXX/constructor-initializer.cpp test/SemaCXX/warn-reorder-ctor-initialization.cpp
Fariborz Jahanian
fjahanian at apple.com
Thu Jul 9 13:00:06 PDT 2009
Author: fjahanian
Date: Thu Jul 9 14:59:47 2009
New Revision: 75168
URL: http://llvm.org/viewvc/llvm-project?rev=75168&view=rev
Log:
Sema check on out of order object initialization of
class object's base and members under -Wreorder flag.
Added:
cfe/trunk/test/SemaCXX/warn-reorder-ctor-initialization.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/SemaCXX/constructor-initializer.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=75168&r1=75167&r2=75168&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Thu Jul 9 14:59:47 2009
@@ -94,6 +94,7 @@
def UnusedValue : DiagGroup<"unused-value">;
def UnusedVariable : DiagGroup<"unused-variable">;
def ReadOnlySetterAttrs : DiagGroup<"readonly-setter-attrs">;
+def Reorder : DiagGroup<"reorder">;
def UndeclaredSelector : DiagGroup<"undeclared-selector">;
def : DiagGroup<"variadic-macros">;
def VectorConversions : DiagGroup<"vector-conversions">; // clang specific
@@ -135,6 +136,7 @@
VectorConversions,
VolatileRegisterVar,
ReadOnlySetterAttrs,
+ Reorder,
UndeclaredSelector
]>;
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=75168&r1=75167&r2=75168&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Jul 9 14:59:47 2009
@@ -1620,6 +1620,15 @@
"member initializer %0 does not name a non-static data member or base "
"class">;
+def warn_field_initialized : Warning<
+ "member '%0' will be initialized after">,
+ InGroup<Reorder>, DefaultIgnore;
+def warn_base_initialized : Warning<
+ "base class %0 will be initialized after">,
+ InGroup<Reorder>, DefaultIgnore;
+def note_fieldorbase_initialized_here : Note<
+ "%select{field|base}0 %1">;
+
def err_base_init_does_not_name_class : Error<
"constructor initializer %0 does not name a class">;
def err_base_init_direct_and_virtual : Error<
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=75168&r1=75167&r2=75168&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Jul 9 14:59:47 2009
@@ -819,10 +819,77 @@
<< 0;
err = true;
}
- if (!err)
+ if (!err) {
Constructor->setBaseOrMemberInitializers(Context,
reinterpret_cast<CXXBaseOrMemberInitializer **>(MemInits),
NumMemInits);
+ // 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.
+ // FIXME. proper handling in the presense of virtual base class.
+ llvm::SmallVector<const void*, 32> AllBaseOrMembers;
+
+ CXXRecordDecl *ClassDecl
+ = cast<CXXRecordDecl>(Constructor->getDeclContext());
+ for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+ E = ClassDecl->bases_end(); Base != E; ++Base)
+ AllBaseOrMembers.push_back(Base->getType()->getAsRecordType());
+
+ for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+ E = ClassDecl->field_end(); Field != E; ++Field)
+ AllBaseOrMembers.push_back(*Field);
+
+ int Last = AllBaseOrMembers.size();
+ int curIndex = 0;
+ CXXBaseOrMemberInitializer *PrevMember = 0;
+ 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])
+ break;
+ if (j == Last) {
+ if (!PrevMember)
+ continue;
+ // Initializer as specified in ctor-initializer list is out of order.
+ // Issue a warning diagnostic.
+ if (PrevMember->isBaseInitializer()) {
+ // Diagnostics is for an initialized base class.
+ Type *BaseClass = PrevMember->getBaseClass();
+ Diag(PrevMember->getSourceLocation(),
+ diag::warn_base_initialized)
+ << BaseClass->getDesugaredType(true);
+ }
+ else {
+ FieldDecl *Field = PrevMember->getMember();
+ Diag(PrevMember->getSourceLocation(),
+ diag::warn_field_initialized)
+ << Field->getNameAsString();
+ }
+ // Also the note!
+ if (FieldDecl *Field = Member->getMember())
+ Diag(Member->getSourceLocation(),
+ diag::note_fieldorbase_initialized_here) << 0
+ << Field->getNameAsString();
+ else {
+ Type *BaseClass = Member->getBaseClass();
+ Diag(Member->getSourceLocation(),
+ diag::note_fieldorbase_initialized_here) << 1
+ << BaseClass->getDesugaredType(true);
+ }
+ }
+ PrevMember = Member;
+ for (curIndex=0; curIndex < Last; curIndex++)
+ if (MemberInCtorList == AllBaseOrMembers[curIndex])
+ break;
+ }
+ }
}
namespace {
Modified: cfe/trunk/test/SemaCXX/constructor-initializer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constructor-initializer.cpp?rev=75168&r1=75167&r2=75168&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constructor-initializer.cpp (original)
+++ cfe/trunk/test/SemaCXX/constructor-initializer.cpp Thu Jul 9 14:59:47 2009
@@ -1,4 +1,4 @@
-// RUN: clang-cc -fsyntax-only -verify %s
+// RUN: clang-cc -Wreorder -fsyntax-only -verify %s
class A {
int m;
A() : A::m(17) { } // expected-error {{member initializer 'm' does not name a non-static data member or base class}}
@@ -64,7 +64,7 @@
};
struct Z : S {
- Z() : S(), X(), E() {} // expected-error {{type 'class E' is not a direct or virtual base of 'Z'}}
+ Z() : X(), S(), E() {} // expected-error {{type 'class E' is not a direct or virtual base of 'Z'}}
};
class U {
@@ -85,10 +85,12 @@
struct Current : Derived {
int Derived;
- Current() : Derived(1), ::Derived(),
+ Current() : Derived(1), ::Derived(), // expected-warning {{member 'Derived' will be initialized after}} \
+ // expected-note {{base '::Derived'}} \
+ // expected-warning {{base class '::Derived' will be initialized after}}
::Derived::Base(), // expected-error {{type '::Derived::Base' is not a direct or virtual base of 'Current'}}
Derived::Base1(), // expected-error {{type 'Derived::Base1' is not a direct or virtual base of 'Current'}}
- Derived::V(),
+ Derived::V(), // expected-note {{base 'Derived::V'}}
::NonExisting(), // expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
INT::NonExisting() {} // expected-error {{expected a class or namespace}} \
// expected-error {{member initializer 'NonExisting' does not name a non-static data member or}}
Added: 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=75168&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-reorder-ctor-initialization.cpp (added)
+++ cfe/trunk/test/SemaCXX/warn-reorder-ctor-initialization.cpp Thu Jul 9 14:59:47 2009
@@ -0,0 +1,18 @@
+// RUN: clang-cc -fsyntax-only -Wreorder -verify %s
+
+struct B {};
+
+struct B1 {};
+
+class complex : public B, B1 {
+public:
+ complex() : s2(1), // expected-warning {{member 's2' will be initialized after}}
+ s1(1) , // expected-note {{field s1}}
+ s3(3), // expected-warning {{member 's3' will be initialized after}}
+ B1(), // expected-note {{base 'struct B1'}} \
+ // expected-warning {{base class 'struct B1' will be initialized after}}
+ B() {} // expected-note {{base 'struct B'}}
+ int s1;
+ int s2;
+ int s3;
+};
More information about the cfe-commits
mailing list