[cfe-commits] r102452 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaType.cpp test/SemaCXX/abstract.cpp

Douglas Gregor dgregor at apple.com
Tue Apr 27 12:38:14 PDT 2010


Author: dgregor
Date: Tue Apr 27 14:38:14 2010
New Revision: 102452

URL: http://llvm.org/viewvc/llvm-project?rev=102452&view=rev
Log:
Diagnose the use of abstract types as array element types. Previously,
we were relying on checking for abstract class types when an array
type was actually used to declare a variable, parameter, etc. However,
we need to check when the construct the array for, e.g., SFINAE
purposes (see DR337). Fixes problems with Boost's is_abstract type
trait. 


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaType.cpp
    cfe/trunk/test/SemaCXX/abstract.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=102452&r1=102451&r2=102452&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Apr 27 14:38:14 2010
@@ -406,6 +406,7 @@
   "allocation of an object of abstract type %0">;
 def err_throw_abstract_type : Error<
   "cannot throw an object of abstract type %0">;
+def err_array_of_abstract_type : Error<"array of abstract class type %0">;
 
 def err_multiple_final_overriders : Error<
   "virtual function %q0 has more than one final overrider in %1">; 

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=102452&r1=102451&r2=102452&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Tue Apr 27 14:38:14 2010
@@ -607,15 +607,31 @@
                               SourceRange Brackets, DeclarationName Entity) {
 
   SourceLocation Loc = Brackets.getBegin();
-  // C99 6.7.5.2p1: If the element type is an incomplete or function type,
-  // reject it (e.g. void ary[7], struct foo ary[7], void ary[7]())
-  // Not in C++, though. There we only dislike void.
   if (getLangOptions().CPlusPlus) {
+    // C++ [dcl.array]p1:
+    //   T is called the array element type; this type shall not be a reference
+    //   type, the (possibly cv-qualified) type void, a function type or an 
+    //   abstract class type.
+    //
+    // Note: function types are handled in the common path with C.
+    if (T->isReferenceType()) {
+      Diag(Loc, diag::err_illegal_decl_array_of_references)
+      << getPrintableNameForEntity(Entity) << T;
+      return QualType();
+    }
+    
     if (T->isVoidType()) {
       Diag(Loc, diag::err_illegal_decl_array_incomplete_type) << T;
       return QualType();
     }
+    
+    if (RequireNonAbstractType(Brackets.getBegin(), T, 
+                               diag::err_array_of_abstract_type))
+      return QualType();
+    
   } else {
+    // C99 6.7.5.2p1: If the element type is an incomplete or function type,
+    // reject it (e.g. void ary[7], struct foo ary[7], void ary[7]())
     if (RequireCompleteType(Loc, T,
                             diag::err_illegal_decl_array_incomplete_type))
       return QualType();
@@ -627,13 +643,6 @@
     return QualType();
   }
 
-  // C++ 8.3.2p4: There shall be no ... arrays of references ...
-  if (T->isReferenceType()) {
-    Diag(Loc, diag::err_illegal_decl_array_of_references)
-      << getPrintableNameForEntity(Entity) << T;
-    return QualType();
-  }
-
   if (Context.getCanonicalType(T) == Context.UndeducedAutoTy) {
     Diag(Loc,  diag::err_illegal_decl_array_of_auto)
       << getPrintableNameForEntity(Entity);

Modified: cfe/trunk/test/SemaCXX/abstract.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/abstract.cpp?rev=102452&r1=102451&r2=102452&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/abstract.cpp (original)
+++ cfe/trunk/test/SemaCXX/abstract.cpp Tue Apr 27 14:38:14 2010
@@ -42,11 +42,11 @@
   t3(C()); // expected-error {{allocation of an object of abstract type 'C'}}
 }
 
-C e1[2]; // expected-error {{variable type 'C' is an abstract class}}
-C (*e2)[2]; // expected-error {{variable type 'C' is an abstract class}}
-C (**e3)[2]; // expected-error {{variable type 'C' is an abstract class}}
+C e1[2]; // expected-error {{array of abstract class type 'C'}}
+C (*e2)[2]; // expected-error {{array of abstract class type 'C'}}
+C (**e3)[2]; // expected-error {{array of abstract class type 'C'}}
 
-void t4(C c[2]); // expected-error {{parameter type 'C' is an abstract class}}
+void t4(C c[2]); // expected-error {{array of abstract class type 'C'}}
 
 void t5(void (*)(C)); // expected-error {{parameter type 'C' is an abstract class}}
 
@@ -168,4 +168,3 @@
   struct D : C {};
   D y;
 }
-





More information about the cfe-commits mailing list