forked from OSchip/llvm-project
Make sure to call CompleteConstructorCall for bases and members that are initialized implicitly in constructors so that default arguments etc are set correctly. Fixes PR5283.
llvm-svn: 85510
This commit is contained in:
parent
2b09590321
commit
561f793890
|
@ -2304,7 +2304,7 @@ public:
|
|||
SourceLocation RParenLoc,
|
||||
CXXRecordDecl *ClassDecl);
|
||||
|
||||
void setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
||||
void SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
||||
CXXBaseOrMemberInitializer **Initializers,
|
||||
unsigned NumInitializers,
|
||||
llvm::SmallVectorImpl<CXXBaseSpecifier *>& Bases,
|
||||
|
|
|
@ -3769,6 +3769,9 @@ Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope,
|
|||
}
|
||||
|
||||
Sema::DeclPtrTy Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, DeclPtrTy D) {
|
||||
// Clear the last template instantiation error context.
|
||||
LastTemplateInstantiationErrorContext = ActiveTemplateInstantiation();
|
||||
|
||||
if (!D)
|
||||
return D;
|
||||
FunctionDecl *FD = 0;
|
||||
|
|
|
@ -1123,7 +1123,7 @@ Sema::BuildBaseInitializer(QualType BaseType, Expr **Args,
|
|||
}
|
||||
|
||||
void
|
||||
Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
||||
Sema::SetBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
||||
CXXBaseOrMemberInitializer **Initializers,
|
||||
unsigned NumInitializers,
|
||||
llvm::SmallVectorImpl<CXXBaseSpecifier *>& Bases,
|
||||
|
@ -1179,7 +1179,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
|||
AllBaseFields.lookup(VBase->getType()->getAs<RecordType>())) {
|
||||
CXXRecordDecl *BaseDecl =
|
||||
cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
|
||||
assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
|
||||
assert(BaseDecl && "SetBaseOrMemberInitializers - BaseDecl null");
|
||||
if (CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context))
|
||||
MarkDeclarationReferenced(Value->getSourceLocation(), Ctor);
|
||||
AllToInit.push_back(Value);
|
||||
|
@ -1187,18 +1187,26 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
|||
else {
|
||||
CXXRecordDecl *VBaseDecl =
|
||||
cast<CXXRecordDecl>(VBase->getType()->getAs<RecordType>()->getDecl());
|
||||
assert(VBaseDecl && "setBaseOrMemberInitializers - VBaseDecl null");
|
||||
assert(VBaseDecl && "SetBaseOrMemberInitializers - VBaseDecl null");
|
||||
CXXConstructorDecl *Ctor = VBaseDecl->getDefaultConstructor(Context);
|
||||
if (!Ctor)
|
||||
if (!Ctor) {
|
||||
Bases.push_back(VBase);
|
||||
else
|
||||
MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
|
||||
continue;
|
||||
}
|
||||
|
||||
ASTOwningVector<&ActionBase::DeleteExpr> CtorArgs(*this);
|
||||
if (CompleteConstructorCall(Ctor, MultiExprArg(*this, 0, 0),
|
||||
Constructor->getLocation(), CtorArgs))
|
||||
continue;
|
||||
|
||||
MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
|
||||
|
||||
CXXBaseOrMemberInitializer *Member =
|
||||
new (Context) CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,
|
||||
Ctor,
|
||||
SourceLocation(),
|
||||
SourceLocation());
|
||||
new (Context) CXXBaseOrMemberInitializer(VBase->getType(),
|
||||
CtorArgs.takeAs<Expr>(),
|
||||
CtorArgs.size(), Ctor,
|
||||
SourceLocation(),
|
||||
SourceLocation());
|
||||
AllToInit.push_back(Member);
|
||||
}
|
||||
}
|
||||
|
@ -1216,7 +1224,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
|||
AllBaseFields.lookup(Base->getType()->getAs<RecordType>())) {
|
||||
CXXRecordDecl *BaseDecl =
|
||||
cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
|
||||
assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
|
||||
assert(BaseDecl && "SetBaseOrMemberInitializers - BaseDecl null");
|
||||
if (CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context))
|
||||
MarkDeclarationReferenced(Value->getSourceLocation(), Ctor);
|
||||
AllToInit.push_back(Value);
|
||||
|
@ -1224,18 +1232,26 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
|||
else {
|
||||
CXXRecordDecl *BaseDecl =
|
||||
cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
|
||||
assert(BaseDecl && "setBaseOrMemberInitializers - BaseDecl null");
|
||||
assert(BaseDecl && "SetBaseOrMemberInitializers - BaseDecl null");
|
||||
CXXConstructorDecl *Ctor = BaseDecl->getDefaultConstructor(Context);
|
||||
if (!Ctor)
|
||||
if (!Ctor) {
|
||||
Bases.push_back(Base);
|
||||
else
|
||||
MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
|
||||
continue;
|
||||
}
|
||||
|
||||
ASTOwningVector<&ActionBase::DeleteExpr> CtorArgs(*this);
|
||||
if (CompleteConstructorCall(Ctor, MultiExprArg(*this, 0, 0),
|
||||
Constructor->getLocation(), CtorArgs))
|
||||
continue;
|
||||
|
||||
MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
|
||||
|
||||
CXXBaseOrMemberInitializer *Member =
|
||||
new (Context) CXXBaseOrMemberInitializer(Base->getType(), 0, 0,
|
||||
BaseDecl->getDefaultConstructor(Context),
|
||||
SourceLocation(),
|
||||
SourceLocation());
|
||||
new (Context) CXXBaseOrMemberInitializer(Base->getType(),
|
||||
CtorArgs.takeAs<Expr>(),
|
||||
CtorArgs.size(), Ctor,
|
||||
SourceLocation(),
|
||||
SourceLocation());
|
||||
AllToInit.push_back(Member);
|
||||
}
|
||||
}
|
||||
|
@ -1268,7 +1284,7 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
|||
QualType FT = (*Field)->getType();
|
||||
if (const RecordType* RT = FT->getAs<RecordType>()) {
|
||||
CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RT->getDecl());
|
||||
assert(FieldRecDecl && "setBaseOrMemberInitializers - BaseDecl null");
|
||||
assert(FieldRecDecl && "SetBaseOrMemberInitializers - BaseDecl null");
|
||||
if (CXXConstructorDecl *Ctor =
|
||||
FieldRecDecl->getDefaultConstructor(Context))
|
||||
MarkDeclarationReferenced(Value->getSourceLocation(), Ctor);
|
||||
|
@ -1281,13 +1297,22 @@ Sema::setBaseOrMemberInitializers(CXXConstructorDecl *Constructor,
|
|||
if (const RecordType* RT = FT->getAs<RecordType>()) {
|
||||
CXXConstructorDecl *Ctor =
|
||||
cast<CXXRecordDecl>(RT->getDecl())->getDefaultConstructor(Context);
|
||||
if (!Ctor && !FT->isDependentType())
|
||||
if (!Ctor && !FT->isDependentType()) {
|
||||
Fields.push_back(*Field);
|
||||
continue;
|
||||
}
|
||||
|
||||
ASTOwningVector<&ActionBase::DeleteExpr> CtorArgs(*this);
|
||||
if (CompleteConstructorCall(Ctor, MultiExprArg(*this, 0, 0),
|
||||
Constructor->getLocation(), CtorArgs))
|
||||
continue;
|
||||
|
||||
CXXBaseOrMemberInitializer *Member =
|
||||
new (Context) CXXBaseOrMemberInitializer((*Field), 0, 0,
|
||||
Ctor,
|
||||
SourceLocation(),
|
||||
SourceLocation());
|
||||
new (Context) CXXBaseOrMemberInitializer(*Field,CtorArgs.takeAs<Expr>(),
|
||||
CtorArgs.size(), Ctor,
|
||||
SourceLocation(),
|
||||
SourceLocation());
|
||||
|
||||
AllToInit.push_back(Member);
|
||||
if (Ctor)
|
||||
MarkDeclarationReferenced(Constructor->getLocation(), Ctor);
|
||||
|
@ -1327,10 +1352,10 @@ Sema::BuildBaseOrMemberInitializers(ASTContext &C,
|
|||
CXXBaseOrMemberInitializer **Initializers,
|
||||
unsigned NumInitializers
|
||||
) {
|
||||
llvm::SmallVector<CXXBaseSpecifier *, 4>Bases;
|
||||
llvm::SmallVector<FieldDecl *, 4>Members;
|
||||
llvm::SmallVector<CXXBaseSpecifier *, 4> Bases;
|
||||
llvm::SmallVector<FieldDecl *, 4> Members;
|
||||
|
||||
setBaseOrMemberInitializers(Constructor,
|
||||
SetBaseOrMemberInitializers(Constructor,
|
||||
Initializers, NumInitializers, Bases, Members);
|
||||
for (unsigned int i = 0; i < Bases.size(); i++)
|
||||
Diag(Bases[i]->getSourceRange().getBegin(),
|
||||
|
|
|
@ -84,3 +84,27 @@ struct X1 {
|
|||
void test_X1() {
|
||||
X1<int> x1;
|
||||
}
|
||||
|
||||
// PR5283
|
||||
namespace PR5283 {
|
||||
template<typename T> struct A {
|
||||
A(T = 1); // expected-error 3 {{incompatible type initializing 'int', expected 'int *'}}
|
||||
};
|
||||
|
||||
struct B : A<int*> {
|
||||
B();
|
||||
};
|
||||
B::B() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
|
||||
|
||||
struct C : virtual A<int*> {
|
||||
C();
|
||||
};
|
||||
C::C() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
|
||||
|
||||
struct D {
|
||||
D();
|
||||
|
||||
A<int*> a;
|
||||
};
|
||||
D::D() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue