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

Reply via email to