diff options
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 60 | ||||
-rw-r--r-- | test/SemaTemplate/member-initializers.cpp | 13 |
2 files changed, 46 insertions, 27 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 3d278b13ef..c5eda94b6a 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -947,40 +947,46 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl, Diag(ColonLoc, diag::err_only_constructors_take_base_inits); return; } - llvm::DenseMap<void*, CXXBaseOrMemberInitializer *>Members; - bool err = false; - for (unsigned i = 0; i < NumMemInits; i++) { - CXXBaseOrMemberInitializer *Member = - static_cast<CXXBaseOrMemberInitializer*>(MemInits[i]); - void *KeyToMember = GetKeyForMember(Member); - CXXBaseOrMemberInitializer *&PrevMember = Members[KeyToMember]; - if (!PrevMember) { - PrevMember = Member; - continue; - } - if (FieldDecl *Field = Member->getMember()) - Diag(Member->getSourceLocation(), - diag::error_multiple_mem_initialization) - << Field->getNameAsString(); - else { - Type *BaseClass = Member->getBaseClass(); - assert(BaseClass && "ActOnMemInitializers - neither field or base"); - Diag(Member->getSourceLocation(), - diag::error_multiple_base_initialization) - << BaseClass->getDesugaredType(true); + + if (!Constructor->isDependentContext()) { + llvm::DenseMap<void*, CXXBaseOrMemberInitializer *>Members; + bool err = false; + for (unsigned i = 0; i < NumMemInits; i++) { + CXXBaseOrMemberInitializer *Member = + static_cast<CXXBaseOrMemberInitializer*>(MemInits[i]); + void *KeyToMember = GetKeyForMember(Member); + CXXBaseOrMemberInitializer *&PrevMember = Members[KeyToMember]; + if (!PrevMember) { + PrevMember = Member; + continue; + } + if (FieldDecl *Field = Member->getMember()) + Diag(Member->getSourceLocation(), + diag::error_multiple_mem_initialization) + << Field->getNameAsString(); + else { + Type *BaseClass = Member->getBaseClass(); + assert(BaseClass && "ActOnMemInitializers - neither field or base"); + Diag(Member->getSourceLocation(), + diag::error_multiple_base_initialization) + << BaseClass->getDesugaredType(true); + } + Diag(PrevMember->getSourceLocation(), diag::note_previous_initializer) + << 0; + err = true; } - Diag(PrevMember->getSourceLocation(), diag::note_previous_initializer) - << 0; - err = true; - } - if (err) - return; + if (err) + return; + } BuildBaseOrMemberInitializers(Context, Constructor, reinterpret_cast<CXXBaseOrMemberInitializer **>(MemInits), NumMemInits); + if (Constructor->isDependentContext()) + return; + if (Diags.getDiagnosticLevel(diag::warn_base_initialized) == Diagnostic::Ignored && Diags.getDiagnosticLevel(diag::warn_field_initialized) == diff --git a/test/SemaTemplate/member-initializers.cpp b/test/SemaTemplate/member-initializers.cpp new file mode 100644 index 0000000000..62077fabc7 --- /dev/null +++ b/test/SemaTemplate/member-initializers.cpp @@ -0,0 +1,13 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +template<typename T> struct A { + A() : j(10), i(10) { } + + int i; + int j; +}; + +template<typename T> struct B : A<T> { + B() : A<T>() { } +}; + |