forked from OSchip/llvm-project
Improve recovery when a constructor fails to type-check. Test case from Anders
llvm-svn: 67818
This commit is contained in:
parent
fdca4a7967
commit
f4d17c4f22
|
@ -2294,7 +2294,7 @@ void Sema::AddInitializerToDecl(DeclTy *dcl, ExprArg init, bool DirectInit) {
|
|||
|
||||
// A class is abstract if at least one function is pure virtual.
|
||||
cast<CXXRecordDecl>(CurContext)->setAbstract(true);
|
||||
} else {
|
||||
} else if (!Method->isInvalidDecl()) {
|
||||
Diag(Method->getLocation(), diag::err_non_virtual_pure)
|
||||
<< Method->getDeclName() << Init->getSourceRange();
|
||||
Method->setInvalidDecl();
|
||||
|
|
|
@ -1289,20 +1289,22 @@ bool Sema::CheckConstructorDeclarator(Declarator &D, QualType &R,
|
|||
/// well-formedness, issuing any diagnostics required. Returns true if
|
||||
/// the constructor declarator is invalid.
|
||||
bool Sema::CheckConstructor(CXXConstructorDecl *Constructor) {
|
||||
if (Constructor->isInvalidDecl())
|
||||
CXXRecordDecl *ClassDecl
|
||||
= dyn_cast<CXXRecordDecl>(Constructor->getDeclContext());
|
||||
if (!ClassDecl)
|
||||
return true;
|
||||
|
||||
CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Constructor->getDeclContext());
|
||||
bool Invalid = false;
|
||||
bool Invalid = Constructor->isInvalidDecl();
|
||||
|
||||
// C++ [class.copy]p3:
|
||||
// A declaration of a constructor for a class X is ill-formed if
|
||||
// its first parameter is of type (optionally cv-qualified) X and
|
||||
// either there are no other parameters or else all other
|
||||
// parameters have default arguments.
|
||||
if ((Constructor->getNumParams() == 1) ||
|
||||
(Constructor->getNumParams() > 1 &&
|
||||
Constructor->getParamDecl(1)->getDefaultArg() != 0)) {
|
||||
if (!Constructor->isInvalidDecl() &&
|
||||
((Constructor->getNumParams() == 1) ||
|
||||
(Constructor->getNumParams() > 1 &&
|
||||
Constructor->getParamDecl(1)->getDefaultArg() != 0))) {
|
||||
QualType ParamType = Constructor->getParamDecl(0)->getType();
|
||||
QualType ClassTy = Context.getTagDeclType(ClassDecl);
|
||||
if (Context.getCanonicalType(ParamType).getUnqualifiedType() == ClassTy) {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify %s
|
||||
|
||||
struct C {
|
||||
virtual C() = 0; // expected-error{{constructor cannot be declared 'virtual'}}
|
||||
};
|
||||
|
||||
void f() {
|
||||
C c;
|
||||
}
|
|
@ -9,7 +9,7 @@ class Foo {
|
|||
|
||||
((Foo))(INT); // expected-error{{cannot be redeclared}}
|
||||
|
||||
Foo(Foo foo, int i = 17, int j = 42); // expected-error {{copy constructor must pass its first argument by reference}}
|
||||
Foo(Foo foo, int i = 17, int j = 42); // expected-error{{copy constructor must pass its first argument by reference}}
|
||||
|
||||
static Foo(short, short); // expected-error{{constructor cannot be declared 'static'}}
|
||||
virtual Foo(double); // expected-error{{constructor cannot be declared 'virtual'}}
|
||||
|
|
Loading…
Reference in New Issue