Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -6609,11 +6609,7 @@ bool isExplicit = D.getDeclSpec().isExplicitSpecified(); bool isConstexpr = D.getDeclSpec().isConstexprSpecified(); - // Check that the return type is not an abstract class type. - // For record types, this is done by the AbstractClassUsageDiagnoser once - // the class has been completely parsed. - if (!DC->isRecord() && - SemaRef.RequireNonAbstractType( + if (SemaRef.RequireNonAbstractType( D.getIdentifierLoc(), R->getAs()->getReturnType(), diag::err_abstract_type_in_decl, SemaRef.AbstractReturnType)) D.setInvalidType(); @@ -9827,11 +9823,7 @@ TSInfo, StorageClass, nullptr); - // Parameters can not be abstract class types. - // For record types, this is done by the AbstractClassUsageDiagnoser once - // the class has been completely parsed. - if (!CurContext->isRecord() && - RequireNonAbstractType(NameLoc, T, diag::err_abstract_type_in_decl, + if (RequireNonAbstractType(NameLoc, T, diag::err_abstract_type_in_decl, AbstractParamType)) New->setInvalidDecl(); Index: test/SemaCXX/abstract.cpp =================================================================== --- test/SemaCXX/abstract.cpp +++ test/SemaCXX/abstract.cpp @@ -267,6 +267,30 @@ }; } +namespace PR18393 { + struct A { + typedef A type; + virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'A'}} + }; + + struct B { + A f1(); // expected-error {{return type 'PR18393::A' is an abstract class}} + + void f2(A a); // expected-error {{parameter type 'PR18393::A' is an abstract class}} + }; + + A f1(); // expected-error {{return type 'PR18393::A' is an abstract class}} + + void f2(A a); // expected-error {{parameter type 'PR18393::A' is an abstract class}} + + template + struct Sample { + public: + typename T::type abstract(); + void abstract(typename T::type); + }; +} + namespace pr12658 { class C { public: