[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