[cfe-commits] r86500 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/CodeGen/CGCXX.cpp lib/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp test/CodeGenCXX/virt.cpp test/SemaCXX/constructor-initializer.cpp test/SemaCXX/default-constructor-initializers.cpp test/SemaCXX/value-initialization.cpp
Fariborz Jahanian
fjahanian at apple.com
Mon Nov 9 10:25:43 PST 2009
Looks good. Some comments below.
- Thanks, Fariborz
On Nov 8, 2009, at 5:05 PM, Eli Friedman wrote:
> Author: efriedma
> Date: Sun Nov 8 19:05:47 2009
> New Revision: 86500
>
> URL: http://llvm.org/viewvc/llvm-project?rev=86500&view=rev
> Log:
> Unify the codepaths used to verify base and member initializers for
> explicitly
> and implicitly defined constructors. This has a number of benefits:
>
> 1. Less code.
>
> 2. Explicit and implicit constructors get the same diagnostics.
>
> 3. The AST explicitly contains constructor calls from implicit default
> constructors. This allows handing some cases that previously
> weren't handled
> correctly in IRGen without any additional code. Specifically,
> implicit default
> constructors containing calls to constructors with default arguments
> are now
> handled correctly.
Please provide a test case for this situation.
>
>
>
> Modified:
> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> cfe/trunk/lib/CodeGen/CGCXX.cpp
> cfe/trunk/lib/Sema/Sema.h
> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp
> cfe/trunk/test/CodeGenCXX/virt.cpp
> cfe/trunk/test/SemaCXX/constructor-initializer.cpp
> cfe/trunk/test/SemaCXX/default-constructor-initializers.cpp
> cfe/trunk/test/SemaCXX/value-initialization.cpp
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=86500&r1=86499&r2=86500&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sun Nov 8
> 19:05:47 2009
> @@ -430,9 +430,13 @@
> "cannot initialize object parameter of type %0 with an expression "
> "of type %1">;
>
> -def err_missing_default_constructor : Error<
> - "default constructor for %1 is missing in initialization of "
> - "%select{base class|member}0">;
> +def note_field_decl : Note<"member is declared here">;
> +def note_previous_class_decl : Note<
> + "%0 declared here">;
> +def err_missing_default_ctor : Error<
> + "%select{|implicit default }0constructor for %1 must explicitly
> initialize "
> + "the %select{base class|member}2 %3 which does not have a default "
> + "constructor">;
> def err_illegal_union_member : Error<
> "union member %0 has a non-trivial %select{constructor|"
> "copy constructor|copy assignment operator|destructor}1">;
> @@ -763,27 +767,18 @@
> "default arguments cannot be added to an out-of-line definition of
> a member "
> "of a %select{class template|class template partial specialization|
> nested "
> "class in a template}0">;
> -def note_field_decl : Note<"member is declared here">;
> -def err_defining_default_ctor : Error<
> - "cannot define the implicit default constructor for %0, because
> %select{base class|member's type}1 "
> - "%2 does not have any default constructor">;
> -def note_previous_class_decl : Note<
> - "%0 declared here">;
> def err_uninitialized_member_for_assign : Error<
> "cannot define the implicit default assignment operator for %0,
> because "
> "non-static %select{reference|const}1 member %2 can't use default "
> "assignment operator">;
> def note_first_required_here : Note<
> "synthesized method is first required here">;
> -def err_unintialized_member : Error<
> - "cannot define the implicit default constructor for %0, because "
> - "%select{reference|const}1 member %2 cannot be default-
> initialized">;
> def err_null_intialized_reference_member : Error<
> "cannot initialize the member to null in default constructor
> because "
> "reference member %0 cannot be null-initialized">;
> def err_unintialized_member_in_ctor : Error<
> - "constructor for %0 must explicitly initialize the "
> - "%select{reference|const}1 member %2 ">;
> + "%select{|implicit default }0constructor for %1 must explicitly
> initialize "
> + "the %select{reference|const}2 member %3">;
>
> def err_use_of_default_argument_to_function_declared_later : Error<
> "use of default argument to function %0 that is declared later in
> class %1">;
>
> Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=86500&r1=86499&r2=86500&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGCXX.cpp Sun Nov 8 19:05:47 2009
> @@ -1483,64 +1483,6 @@
> PopCXXTemporary();
> }
>
> - if (!CD->getNumBaseOrMemberInitializers() && !CD->isTrivial()) {
> - // Nontrivial default constructor with no initializer list. It
> may still
> - // have bases classes and/or contain non-static data members
> which require
> - // construction.
> - for (CXXRecordDecl::base_class_const_iterator Base =
> - ClassDecl->bases_begin();
> - Base != ClassDecl->bases_end(); ++Base) {
> - // FIXME. copy assignment of virtual base NYI
> - if (Base->isVirtual())
> - continue;
> -
> - CXXRecordDecl *BaseClassDecl
> - = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()-
> >getDecl());
> - if (BaseClassDecl->hasTrivialConstructor())
> - continue;
> - if (CXXConstructorDecl *BaseCX =
> - BaseClassDecl->getDefaultConstructor(getContext())) {
> - LoadOfThis = LoadCXXThis();
> - llvm::Value *V = GetAddressCXXOfBaseClass(LoadOfThis,
> ClassDecl,
> - BaseClassDecl,
> - /
> *NullCheckValue=*/false);
> - EmitCXXConstructorCall(BaseCX, Ctor_Complete, V, 0, 0);
> - }
> - }
> -
> - for (CXXRecordDecl::field_iterator Field = ClassDecl-
> >field_begin(),
> - FieldEnd = ClassDecl->field_end();
> - Field != FieldEnd; ++Field) {
> - QualType FieldType = getContext().getCanonicalType((*Field)-
> >getType());
> - const ConstantArrayType *Array =
> - getContext().getAsConstantArrayType(FieldType);
> - if (Array)
> - FieldType = getContext().getBaseElementType(FieldType);
> - if (!FieldType->getAs<RecordType>() || Field-
> >isAnonymousStructOrUnion())
> - continue;
> - const RecordType *ClassRec = FieldType->getAs<RecordType>();
> - CXXRecordDecl *MemberClassDecl =
> - dyn_cast<CXXRecordDecl>(ClassRec->getDecl());
> - if (!MemberClassDecl || MemberClassDecl-
> >hasTrivialConstructor())
> - continue;
> - if (CXXConstructorDecl *MamberCX =
> - MemberClassDecl->getDefaultConstructor(getContext())) {
> - LoadOfThis = LoadCXXThis();
> - LValue LHS = EmitLValueForField(LoadOfThis, *Field, false,
> 0);
> - if (Array) {
> - const llvm::Type *BasePtr = ConvertType(FieldType);
> - BasePtr = llvm::PointerType::getUnqual(BasePtr);
> - llvm::Value *BaseAddrPtr =
> - Builder.CreateBitCast(LHS.getAddress(), BasePtr);
> - EmitCXXAggrConstructorCall(MamberCX, Array, BaseAddrPtr);
> - }
> - else
> - EmitCXXConstructorCall(MamberCX, Ctor_Complete,
> LHS.getAddress(),
> - 0, 0);
> - }
> - }
> - }
> -
> // Initialize the vtable pointer
> if (ClassDecl->isDynamicClass()) {
> if (!LoadOfThis)
>
> Modified: cfe/trunk/lib/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=86500&r1=86499&r2=86500&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/Sema/Sema.h (original)
> +++ cfe/trunk/lib/Sema/Sema.h Sun Nov 8 19:05:47 2009
> @@ -1747,11 +1747,6 @@
> const FunctionProtoType *Proto,
> Expr **Args, unsigned NumArgs,
> SourceLocation RParenLoc);
> - void BuildBaseOrMemberInitializers(ASTContext &C,
> - CXXConstructorDecl *Constructor,
> - CXXBaseOrMemberInitializer
> **Initializers,
> - unsigned NumInitializers
> - );
>
> void DeconstructCallFunction(Expr *FnExpr,
> NamedDecl *&Function,
> @@ -2280,8 +2275,7 @@
> void SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
> CXXBaseOrMemberInitializer
> **Initializers,
> unsigned NumInitializers,
> -
> llvm::SmallVectorImpl<CXXBaseSpecifier *>& Bases,
> - llvm::SmallVectorImpl<FieldDecl
> *>&Members);
> + bool IsImplicitConstructor);
>
> /// computeBaseOrMembersToDestroy - Compute information in current
> /// destructor decl's AST of bases and non-static data members
> which will be
>
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=86500&r1=86499&r2=86500&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sun Nov 8 19:05:47 2009
> @@ -1190,8 +1190,7 @@
> Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
> CXXBaseOrMemberInitializer
> **Initializers,
> unsigned NumInitializers,
> -
> llvm::SmallVectorImpl<CXXBaseSpecifier *>& Bases,
> - llvm::SmallVectorImpl<FieldDecl
> *>&Fields) {
> + bool IsImplicitConstructor) {
> // We need to build the initializer AST according to order of
> construction
> // and not what user specified in the Initializers list.
> CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Constructor-
> >getDeclContext());
> @@ -1254,7 +1253,11 @@
> assert(VBaseDecl && "SetBaseOrMemberInitializers - VBaseDecl
> null");
> CXXConstructorDecl *Ctor = VBaseDecl-
> >getDefaultConstructor(Context);
> if (!Ctor) {
> - Bases.push_back(VBase);
> + Diag(Constructor->getLocation(),
> diag::err_missing_default_ctor)
> + << (int)IsImplicitConstructor <<
> Context.getTagDeclType(ClassDecl)
> + << 0 << VBase->getType();
> + Diag(VBaseDecl->getLocation(),
> diag::note_previous_class_decl)
> + << Context.getTagDeclType(VBaseDecl);
> continue;
> }
>
> @@ -1299,7 +1302,11 @@
> assert(BaseDecl && "SetBaseOrMemberInitializers - BaseDecl
> null");
> CXXConstructorDecl *Ctor = BaseDecl-
> >getDefaultConstructor(Context);
> if (!Ctor) {
> - Bases.push_back(Base);
> + Diag(Constructor->getLocation(),
> diag::err_missing_default_ctor)
> + << (int)IsImplicitConstructor <<
> Context.getTagDeclType(ClassDecl)
> + << 0 << Base->getType();
> + Diag(BaseDecl->getLocation(),
> diag::note_previous_class_decl)
> + << Context.getTagDeclType(BaseDecl);
> continue;
> }
>
> @@ -1357,17 +1364,20 @@
> continue;
> }
>
> - if ((*Field)->getType()->isDependentType()) {
> - Fields.push_back(*Field);
> + if ((*Field)->getType()->isDependentType())
> continue;
> - }
Yes. good point.
>
>
> QualType FT = Context.getBaseElementType((*Field)->getType());
> if (const RecordType* RT = FT->getAs<RecordType>()) {
> CXXConstructorDecl *Ctor =
> cast<CXXRecordDecl>(RT->getDecl())-
> >getDefaultConstructor(Context);
> if (!Ctor) {
> - Fields.push_back(*Field);
> + Diag(Constructor->getLocation(),
> diag::err_missing_default_ctor)
> + << (int)IsImplicitConstructor <<
> Context.getTagDeclType(ClassDecl)
> + << 1 << (*Field)->getDeclName();
> + Diag(Field->getLocation(), diag::note_field_decl);
> + Diag(RT->getDecl()->getLocation(),
> diag::note_previous_class_decl)
> + << Context.getTagDeclType(RT->getDecl());
> continue;
> }
>
> @@ -1383,22 +1393,24 @@
> SourceLocation());
>
> AllToInit.push_back(Member);
> - if (Ctor)
> - MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
> - if (FT.isConstQualified() && (!Ctor || Ctor->isTrivial())) {
> + MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
> + if (FT.isConstQualified() && Ctor->isTrivial()) {
> Diag(Constructor->getLocation(),
> diag::err_unintialized_member_in_ctor)
> - << Context.getTagDeclType(ClassDecl) << 1 << (*Field)-
> >getDeclName();
> + << (int)IsImplicitConstructor <<
> Context.getTagDeclType(ClassDecl)
> + << 1 << (*Field)->getDeclName();
> Diag((*Field)->getLocation(), diag::note_declared_at);
> }
> }
> else if (FT->isReferenceType()) {
> Diag(Constructor->getLocation(),
> diag::err_unintialized_member_in_ctor)
> - << Context.getTagDeclType(ClassDecl) << 0 << (*Field)-
> >getDeclName();
> + << (int)IsImplicitConstructor <<
> Context.getTagDeclType(ClassDecl)
> + << 0 << (*Field)->getDeclName();
> Diag((*Field)->getLocation(), diag::note_declared_at);
> }
> else if (FT.isConstQualified()) {
> Diag(Constructor->getLocation(),
> diag::err_unintialized_member_in_ctor)
> - << Context.getTagDeclType(ClassDecl) << 1 << (*Field)-
> >getDeclName();
> + << (int)IsImplicitConstructor <<
> Context.getTagDeclType(ClassDecl)
> + << 1 << (*Field)->getDeclName();
> Diag((*Field)->getLocation(), diag::note_declared_at);
> }
> }
> @@ -1415,29 +1427,6 @@
> }
> }
>
> -void
> -Sema::BuildBaseOrMemberInitializers(ASTContext &C,
> - CXXConstructorDecl *Constructor,
> - CXXBaseOrMemberInitializer
> **Initializers,
> - unsigned NumInitializers
> - ) {
> - llvm::SmallVector<CXXBaseSpecifier *, 4> Bases;
> - llvm::SmallVector<FieldDecl *, 4> Members;
> -
> - SetBaseOrMemberInitializers(Constructor,
> - Initializers, NumInitializers, Bases,
> Members);
> - for (unsigned int i = 0; i < Bases.size(); i++) {
> - if (!Bases[i]->getType()->isDependentType())
> - Diag(Bases[i]->getSourceRange().getBegin(),
> - diag::err_missing_default_constructor) << 0 << Bases[i]-
> >getType();
> - }
> - for (unsigned int i = 0; i < Members.size(); i++) {
> - if (!Members[i]->getType()->isDependentType())
> - Diag(Members[i]->getLocation(),
> diag::err_missing_default_constructor)
> - << 1 << Members[i]->getType();
> - }
> -}
> -
> static void *GetKeyForTopLevelField(FieldDecl *Field) {
> // For anonymous unions, use the class declaration as the key.
> if (const RecordType *RT = Field->getType()->getAs<RecordType>()) {
> @@ -1462,7 +1451,7 @@
> if (Member->isMemberInitializer()) {
> FieldDecl *Field = Member->getMember();
>
> - // After BuildBaseOrMemberInitializers call, Field is the
> anonymous union
> + // After SetBaseOrMemberInitializers call, Field is the
> anonymous union
> // data member of the class. Data member used in the initializer
> list is
> // in AnonUnionMember field.
> if (MemberMaybeAnon && Field->isAnonymousStructOrUnion())
> @@ -1527,9 +1516,9 @@
> return;
> }
>
> - BuildBaseOrMemberInitializers(Context, Constructor,
> + SetBaseOrMemberInitializers(Constructor,
> reinterpret_cast<CXXBaseOrMemberInitializer
> **>(MemInits),
> - NumMemInits);
> + NumMemInits, false);
>
> if (Constructor->isDependentContext())
> return;
> @@ -1694,9 +1683,7 @@
>
> if (CXXConstructorDecl *Constructor
> = dyn_cast<CXXConstructorDecl>(CDtorDecl.getAs<Decl>()))
> - BuildBaseOrMemberInitializers(Context,
> - Constructor,
> - (CXXBaseOrMemberInitializer
> **)0, 0);
> + SetBaseOrMemberInitializers(Constructor, 0, 0, false);
> }
>
> namespace {
> @@ -2973,67 +2960,11 @@
> CXXRecordDecl *ClassDecl
> = cast<CXXRecordDecl>(Constructor->getDeclContext());
> assert(ClassDecl && "DefineImplicitDefaultConstructor - invalid
> constructor");
> - // Before the implicitly-declared default constructor for a class
> is
> - // implicitly defined, all the implicitly-declared default
> constructors
> - // for its base class and its non-static data members shall have
> been
> - // implicitly defined.
> - bool err = false;
> - for (CXXRecordDecl::base_class_iterator Base = ClassDecl-
> >bases_begin(),
> - E = ClassDecl->bases_end(); Base != E; ++Base) {
> - CXXRecordDecl *BaseClassDecl
> - = cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()-
> >getDecl());
> - if (!BaseClassDecl->hasTrivialConstructor()) {
> - if (CXXConstructorDecl *BaseCtor =
> - BaseClassDecl->getDefaultConstructor(Context))
> - MarkDeclarationReferenced(CurrentLocation, BaseCtor);
> - else {
> - Diag(CurrentLocation, diag::err_defining_default_ctor)
> - << Context.getTagDeclType(ClassDecl) << 0
> - << Context.getTagDeclType(BaseClassDecl);
> - Diag(BaseClassDecl->getLocation(),
> diag::note_previous_class_decl)
> - << Context.getTagDeclType(BaseClassDecl);
> - err = true;
> - }
> - }
> - }
> - for (CXXRecordDecl::field_iterator Field = ClassDecl-
> >field_begin(),
> - E = ClassDecl->field_end(); Field != E; ++Field) {
> - QualType FieldType = Context.getCanonicalType((*Field)-
> >getType());
> - if (const ArrayType *Array = Context.getAsArrayType(FieldType))
> - FieldType = Array->getElementType();
> - if (const RecordType *FieldClassType = FieldType-
> >getAs<RecordType>()) {
> - CXXRecordDecl *FieldClassDecl
> - = cast<CXXRecordDecl>(FieldClassType->getDecl());
> - if (!FieldClassDecl->hasTrivialConstructor()) {
> - if (CXXConstructorDecl *FieldCtor =
> - FieldClassDecl->getDefaultConstructor(Context))
> - MarkDeclarationReferenced(CurrentLocation, FieldCtor);
> - else {
> - Diag(CurrentLocation, diag::err_defining_default_ctor)
> - << Context.getTagDeclType(ClassDecl) << 1 <<
> - Context.getTagDeclType(FieldClassDecl);
> - Diag((*Field)->getLocation(), diag::note_field_decl);
> - Diag(FieldClassDecl->getLocation(),
> diag::note_previous_class_decl)
> - << Context.getTagDeclType(FieldClassDecl);
> - err = true;
> - }
> - }
> - } else if (FieldType->isReferenceType()) {
> - Diag(CurrentLocation, diag::err_unintialized_member)
> - << Context.getTagDeclType(ClassDecl) << 0 << Field-
> >getDeclName();
> - Diag((*Field)->getLocation(), diag::note_declared_at);
> - err = true;
> - } else if (FieldType.isConstQualified()) {
> - Diag(CurrentLocation, diag::err_unintialized_member)
> - << Context.getTagDeclType(ClassDecl) << 1 << Field-
> >getDeclName();
> - Diag((*Field)->getLocation(), diag::note_declared_at);
> - err = true;
> - }
> - }
> - if (!err)
> - Constructor->setUsed();
> - else
> - Constructor->setInvalidDecl();
> +
We need to make the Constructor invalid. This changes that.
>
> + SetBaseOrMemberInitializers(Constructor, 0, 0, true);
> +
> + Constructor->setUsed();
> + return;
> }
>
> void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation,
>
> Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp?rev=86500&r1=86499&r2=86500&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp (original)
> +++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp Sun Nov
> 8 19:05:47 2009
> @@ -12,7 +12,7 @@
>
> void g() { }
>
> - struct Inner {
> + struct Inner { // expected-error{{implicit default}}
> T value; // expected-note {{member is declared here}}
> };
>
> @@ -26,8 +26,7 @@
> xih.g(); // okay
> xih.f(); // expected-note{{instantiation}}
>
> - // FIXME: diagnostic here has incorrect reason (PR5154)
> - X<IntHolder, int>::Inner inner; // expected-error{{implicit
> default}}
> + X<IntHolder, int>::Inner inner;
>
> return X<IntHolder, int>::value; // expected-note{{instantiation}}
> }
>
> Modified: cfe/trunk/test/CodeGenCXX/virt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/virt.cpp?rev=86500&r1=86499&r2=86500&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/test/CodeGenCXX/virt.cpp (original)
> +++ cfe/trunk/test/CodeGenCXX/virt.cpp Sun Nov 8 19:05:47 2009
> @@ -4,6 +4,7 @@
> // RUN: clang-cc -triple x86_64-apple-darwin -std=c++0x -emit-llvm
> %s -o %t-64.ll
> // RUN: FileCheck -check-prefix LPLL64 --input-file=%t-64.ll %s
>
> +// XFAIL: *
>
> struct B {
> virtual void bar1();
>
> Modified: cfe/trunk/test/SemaCXX/constructor-initializer.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constructor-initializer.cpp?rev=86500&r1=86499&r2=86500&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/test/SemaCXX/constructor-initializer.cpp (original)
> +++ cfe/trunk/test/SemaCXX/constructor-initializer.cpp Sun Nov 8
> 19:05:47 2009
> @@ -99,7 +99,9 @@
>
> // FIXME. This is bad message!
> struct M { // expected-note {{candidate function}} \
> - // expected-note {{candidate function}}
> + // expected-note {{candidate function}} \
> + // expected-note {{declared here}} \
> + // expected-note {{declared here}}
> M(int i, int j); // expected-note {{candidate function}} \
> // // expected-note {{candidate function}}
> };
> @@ -110,9 +112,10 @@
> M m1;
> };
>
> -struct P : M { // expected-error {{default constructor for 'struct
> M' is missing in initialization of base class}}
> - P() { }
> - M m; // expected-error {{default constructor for 'struct M' is
> missing in initialization of member}}
> +struct P : M {
> + P() { } // expected-error {{base class 'struct M'}} \
> + // expected-error {{member 'm'}}
> + M m; // expected-note {{member is declared here}}
> };
>
> struct Q {
>
> Modified: cfe/trunk/test/SemaCXX/default-constructor-initializers.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/default-constructor-initializers.cpp?rev=86500&r1=86499&r2=86500&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/test/SemaCXX/default-constructor-initializers.cpp
> (original)
> +++ cfe/trunk/test/SemaCXX/default-constructor-initializers.cpp Sun
> Nov 8 19:05:47 2009
> @@ -9,18 +9,18 @@
> X2(int);
> };
>
> -struct X3 : public X2 {
> +struct X3 : public X2 { // expected-error {{must explicitly
> initialize the base class 'struct X2'}}
> };
> -X3 x3; // expected-error {{cannot define the implicit default
> constructor for 'struct X3', because base class 'struct X2' does not
> have any default constructor}}
> +X3 x3;
>
>
> -struct X4 {
> +struct X4 { // expected-error {{must explicitly initialize the
> member 'x2'}} \
> + // expected-error {{must explicitly initialize the
> reference member 'rx2'}}
> X2 x2; // expected-note {{member is declared here}}
> X2 & rx2; // expected-note {{declared at}}
> };
>
> -X4 x4; // expected-error {{cannot define the implicit default
> constructor for 'struct X4', because member's type 'struct X2' does
> not have any default constructor}} \
> - // expected-error {{cannot define the implicit default
> constructor for 'struct X4', because reference member 'rx2' cannot
> be default-initialized}}
> +X4 x4;
This is important omission of diagnostics at point of declarations
which prompted error on constructor synthesis.
Please restore them.
- Thanks, Fariborz
>
>
>
> struct Y1 { // has no implicit default constructor
> @@ -45,12 +45,12 @@
> // More tests
>
>
> -struct Z1 {
> +struct Z1 { // expected-error {{must explicitly initialize the
> reference member 'z'}} \
> + // expected-error {{must explicitly initialize the
> const member 'c1'}}
> int& z; // expected-note {{declared at}}
> const int c1; // expected-note {{declared at}}
> volatile int v1;
> };
>
> -Z1 z1; // expected-error {{cannot define the implicit default
> constructor for 'struct Z1', because reference member 'z' cannot be
> default-initialized}} \
> - // expected-error {{cannot define the implicit default
> constructor for 'struct Z1', because const member 'c1' cannot be
> default-initialized}}
> +Z1 z1;
>
>
> Modified: cfe/trunk/test/SemaCXX/value-initialization.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/value-initialization.cpp?rev=86500&r1=86499&r2=86500&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/test/SemaCXX/value-initialization.cpp (original)
> +++ cfe/trunk/test/SemaCXX/value-initialization.cpp Sun Nov 8
> 19:05:47 2009
> @@ -1,10 +1,10 @@
> // RUN: clang-cc -fsyntax-only -verify %s -std=c++0x
>
> -struct A {
> +struct A { // expected-error {{implicit default constructor for
> 'struct A' must explicitly initialize the const member 'i'}}
> const int i; // expected-note {{declared at}}
> virtual void f() { }
> };
>
> int main () {
> - (void)A(); // expected-error {{cannot define the implicit
> default constructor for 'struct A', because const member 'i' cannot
> be default-initialized}}
> + (void)A();
> }
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list