diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index c958dd1027c4..2d0251cc1441 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -951,7 +951,7 @@ Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) { // Block scope. C99 6.7p7: If an identifier for an object is declared with // no linkage (C99 6.2.2p6), the type for the object shall be complete... if (BVD && IDecl->getStorageClass() != VarDecl::Extern) { - if (T->isIncompleteType()) { + if (T->isIncompleteType() && !IDecl->isInvalidDecl()) { Diag(IDecl->getLocation(), diag::err_typecheck_decl_incomplete_type, T.getAsString()); IDecl->setInvalidDecl(); @@ -967,7 +967,7 @@ Sema::DeclTy *Sema::FinalizeDeclaratorGroup(Scope *S, DeclTy *group) { if (T->isIncompleteArrayType()) { // C99 6.9.2 (p2, p5): Implicit initialization causes an incomplete // array to be completed. Don't issue a diagnostic. - } else if (T->isIncompleteType()) { + } else if (T->isIncompleteType() && !IDecl->isInvalidDecl()) { // C99 6.9.2p3: If the declaration of an identifier for an object is // a tentative definition and has internal linkage (C99 6.2.2p3), the // declared type shall not be an incomplete type. @@ -1100,7 +1100,8 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) { // C99 6.7.5.3p4: the parameters in a parameter type list in a function // declarator that is part of a function definition of that function // shall not have incomplete type. - if (parmDecl->getType()->isIncompleteType()) { + if (parmDecl->getType()->isIncompleteType() && + !parmDecl->isInvalidDecl()) { Diag(parmDecl->getLocation(), diag::err_typecheck_decl_incomplete_type, parmDecl->getType().getAsString()); parmDecl->setInvalidDecl(); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index d4cb979563f3..ad9d138f91b8 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -203,7 +203,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { DeclType.Ref.AttrList = ProcessTypeAttributes(T, AL); break; case DeclaratorChunk::Array: { - const DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr; + DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr; Expr *ArraySize = static_cast(ATI.NumElts); ArrayType::ArraySizeModifier ASM; if (ATI.isStar) @@ -246,9 +246,11 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { Diag(ArraySize->getLocStart(), diag::err_array_size_non_int, ArraySize->getType().getAsString(), ArraySize->getSourceRange()); D.setInvalidType(true); + delete ArraySize; + ATI.NumElts = ArraySize = 0; } llvm::APSInt ConstVal(32); - // If no expression was provided, we consider it a VLA. + // If no expression was provided, we consider it an incomplete array. if (!ArraySize) { T = Context.getIncompleteArrayType(T, ASM, ATI.TypeQuals); } else if (!ArraySize->isIntegerConstantExpr(ConstVal, Context)) { diff --git a/clang/test/Sema/array-init.c b/clang/test/Sema/array-init.c index 849737e49e60..56be42c695f0 100644 --- a/clang/test/Sema/array-init.c +++ b/clang/test/Sema/array-init.c @@ -126,8 +126,7 @@ void illegal() { { 6 }, }, }; - // FIXME: the following two errors are redundant - int a[][] = { 1, 2 }; // expected-error{{array has incomplete element type 'int []'}} expected-error{{variable has incomplete type 'int []'}} + int a[][] = { 1, 2 }; // expected-error{{array has incomplete element type 'int []'}} } typedef int AryT[]; @@ -159,7 +158,7 @@ void charArrays() char c3[5] = { "Hello" }; char c4[4] = { "Hello" }; //expected-warning{{initializer-string for char array is too long}} - int i3[] = {}; //expected-error{{at least one initializer value required to size array}} expected-error{{variable has incomplete type 'int []'}} expected-warning{{use of GNU empty initializer extension}} + int i3[] = {}; //expected-error{{at least one initializer value required to size array}} expected-warning{{use of GNU empty initializer extension}} } void variableArrayInit() { diff --git a/clang/test/Sema/decl-invalid.c b/clang/test/Sema/decl-invalid.c index d241adcf2aef..281e8a8d5c05 100644 --- a/clang/test/Sema/decl-invalid.c +++ b/clang/test/Sema/decl-invalid.c @@ -1,3 +1,11 @@ // RUN: clang %s -fsyntax-only -verify typedef union __mbstate_t; // expected-error: {{expected identifier or}} + + +// PR2017 +void x(); +int a() { + int r[x()]; // expected-error: {{size of array has non-integer type 'void'}} +} +