diff --git a/Sema/SemaType.cpp b/Sema/SemaType.cpp index 388359a753..5b1db6e39b 100644 --- a/Sema/SemaType.cpp +++ b/Sema/SemaType.cpp @@ -103,9 +103,6 @@ static QualType ConvertDeclSpecToType(const DeclSpec &DS, ASTContext &Ctx) { QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { QualType T = ConvertDeclSpecToType(D.getDeclSpec(), Context); - // If there was an error parsing declspecs, return a null type pointer. - if (T.isNull()) return T; - // Apply const/volatile/restrict qualifiers to T. T = T.getQualifiedType(D.getDeclSpec().getTypeQualifiers()); @@ -120,19 +117,19 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { // C++ 8.3.2p4: There shall be no ... pointers to references ... Diag(D.getIdentifierLoc(), diag::err_illegal_decl_pointer_to_reference, D.getIdentifier()->getName()); - return QualType(); + T = Context.IntTy; } // Apply the pointer typequals to the pointer object. T = Context.getPointerType(T).getQualifiedType(DeclType.Ptr.TypeQuals); break; case DeclaratorChunk::Reference: - if (isa(T.getCanonicalType().getTypePtr())) { + if (const ReferenceType *RT = T->isReferenceType()) { // C++ 8.3.2p4: There shall be no references to references ... Diag(D.getIdentifierLoc(), diag::err_illegal_decl_reference_to_reference, D.getIdentifier()->getName()); - return QualType(); + T = RT->getReferenceeType(); } T = Context.getReferenceType(T); @@ -146,31 +143,29 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { ASM = ArrayType::Static; else ASM = ArrayType::Normal; - - Type *CanonicalT = T.getCanonicalType().getTypePtr(); - + // 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 (T->isIncompleteType()) { Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_incomplete_type, T.getAsString()); - return QualType(); - } else if (isa(CanonicalT)) { + T = Context.IntTy; + } else if (T->isFunctionType()) { Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_of_functions, D.getIdentifier()->getName()); - return QualType(); - } else if (isa(CanonicalT)) { + T = Context.getPointerType(T); + } else if (const ReferenceType *RT = T->isReferenceType()) { // C++ 8.3.2p4: There shall be no ... arrays of references ... Diag(D.getIdentifierLoc(), diag::err_illegal_decl_array_of_references, D.getIdentifier()->getName()); - return QualType(); - } else if (RecordType *EltTy = dyn_cast(CanonicalT)) { + T = RT->getReferenceeType(); + } else if (RecordType *EltTy =dyn_cast(T.getCanonicalType())){ // If the element type is a struct or union that contains a variadic // array, reject it: C99 6.7.2.1p2. if (EltTy->getDecl()->hasFlexibleArrayMember()) { Diag(DeclType.Loc, diag::err_flexible_array_in_array, T.getAsString()); - return QualType(); + T = Context.IntTy; } } T = Context.getArrayType(T, ASM, ATI.TypeQuals, diff --git a/test/Sema/array-constraint.c b/test/Sema/array-constraint.c new file mode 100644 index 0000000000..4b70bb9bb3 --- /dev/null +++ b/test/Sema/array-constraint.c @@ -0,0 +1,11 @@ +// RUN: clang -parse-ast-check %s + +struct s; +struct s* t (struct s z[]) { // expected-error {{array has incomplete element type}} + return z; +} + +void *k (void l[2]) { // expected-error {{array has incomplete element type}} + return l; +} +