Hi rsmith,
Hi,
Attached patch contains the implementation of a fix for PR18393[1]. According
to standard "An abstract class shall not be used as a parameter type, as a
function return type, or as the type of an explicit conversion" (class.abstract
$10.4.3).
Currently, checking if type isn't abstract class is done when method is
defined, but I don't see any reason why clang shouldn't do it as early as
possible, in this case, when function/method is declared. Test also attached.
Please, review and provide feedback or propose additional tests.
Thanks in advance
Robert Matusewicz
http://reviews.llvm.org/D5409
Files:
lib/Sema/SemaDecl.cpp
test/SemaCXX/abstract.cpp
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<FunctionType>()->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<typename T>
+ struct Sample {
+ public:
+ typename T::type abstract();
+ void abstract(typename T::type);
+ };
+}
+
namespace pr12658 {
class C {
public:
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits