diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8a532d62a71e..5847945a4f8e 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1604,6 +1604,8 @@ def err_base_init_does_not_name_class : Error< def err_base_init_direct_and_virtual : Error< "base class initializer %0 names both a direct base class and an " "inherited virtual base class">; +def err_not_direct_base_or_virtual : Error< + "type %0 is not a direct or virtual base of '%1'">; def err_in_class_initializer_non_integral_type : Error< "in-class initializer has non-integral, non-enumeration type %0">; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 77823c3b820e..546c783a6237 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -750,6 +750,15 @@ Sema::ActOnMemInitializer(DeclPtrTy ConstructorD, if (DirectBaseSpec && VirtualBaseSpec) return Diag(IdLoc, diag::err_base_init_direct_and_virtual) << MemberOrBase << SourceRange(IdLoc, RParenLoc); + // C++ [base.class.init]p2: + // Unless the mem-initializer-id names a nonstatic data membeer of the + // constructor's class ot a direst or virtual base of that class, the + // mem-initializer is ill-formed. + if (!DirectBaseSpec && !VirtualBaseSpec) + return Diag(IdLoc, diag::err_not_direct_base_or_virtual) + << BaseType << ClassDecl->getNameAsCString() + << SourceRange(IdLoc, RParenLoc); + return new CXXBaseOrMemberInitializer(BaseType, (Expr **)Args, NumArgs, IdLoc); diff --git a/clang/test/SemaCXX/constructor-initializer.cpp b/clang/test/SemaCXX/constructor-initializer.cpp index d0c978a80d15..d8b95cec4cd9 100644 --- a/clang/test/SemaCXX/constructor-initializer.cpp +++ b/clang/test/SemaCXX/constructor-initializer.cpp @@ -54,3 +54,15 @@ class H : A { H::H() : A(10) { } + +class X {}; +class Y {}; + +struct S : Y, virtual X { + S (); +}; + +struct Z : S { + Z() : S(), X(), E() {} // expected-error {{type 'class E' is not a direct or virtual base of 'Z'}} +}; +