From: Eli Friedman Date: Sun, 26 Apr 2009 21:57:51 +0000 (+0000) Subject: Add a bit more handling for declarations like "int a[*]". X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f91f5c8a66ffd812f61819836529f8ad437f7e2b;p=clang Add a bit more handling for declarations like "int a[*]". git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70162 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index bc46bdf994..7225aadbbc 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -891,6 +891,8 @@ def err_illegal_decl_array_incomplete_type : Error< "array has incomplete element type %0">; def err_illegal_decl_array_of_references : Error< "'%0' declared as array of references">; +def err_array_star_outside_prototype : Error< + "star modifier used outside of function prototype">; def err_illegal_decl_pointer_to_reference : Error< "'%0' declared as a pointer to a reference">; def err_illegal_decl_mempointer_to_void : Error< diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index a94310bbdf..0331bbf40d 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -37,7 +37,8 @@ void Type::Destroy(ASTContext& C) { } void VariableArrayType::Destroy(ASTContext& C) { - SizeExpr->Destroy(C); + if (SizeExpr) + SizeExpr->Destroy(C); this->~VariableArrayType(); C.Deallocate(this); } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 883cf221fb..5df0aecd8f 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -500,7 +500,10 @@ QualType Sema::BuildArrayType(QualType T, ArrayType::ArraySizeModifier ASM, } llvm::APSInt ConstVal(32); if (!ArraySize) { - T = Context.getIncompleteArrayType(T, ASM, Quals); + if (ASM == ArrayType::Star) + T = Context.getVariableArrayType(T, 0, ASM, Quals); + else + T = Context.getIncompleteArrayType(T, ASM, Quals); } else if (ArraySize->isValueDependent()) { T = Context.getDependentSizedArrayType(T, ArraySize, ASM, Quals); } else if (!ArraySize->isIntegerConstantExpr(ConstVal, Context) || @@ -687,6 +690,15 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) { ASM = ArrayType::Static; else ASM = ArrayType::Normal; + if (ASM == ArrayType::Star && + D.getContext() != Declarator::PrototypeContext) { + // FIXME: This check isn't quite right: it allows star in prototypes + // for function definitions, and disallows some edge cases detailed + // in http://gcc.gnu.org/ml/gcc-patches/2009-02/msg00133.html + Diag(DeclType.Loc, diag::err_array_star_outside_prototype); + ASM = ArrayType::Normal; + D.setInvalidType(true); + } T = BuildArrayType(T, ASM, ArraySize, ATI.TypeQuals, DeclType.Loc, Name); break; } diff --git a/test/Sema/vla.c b/test/Sema/vla.c index 252e9ff62e..b4839143bf 100644 --- a/test/Sema/vla.c +++ b/test/Sema/vla.c @@ -43,3 +43,6 @@ void f3() // PR3663 static const unsigned array[((2 * (int)((((4) / 2) + 1.0/3.0) * (4) - 1e-8)) + 1)]; // expected-warning {{size of static array must be an integer constant expression}} + +int a[*]; // expected-error {{star modifier used outside of function prototype}} +int f4(int a[*][*]);