aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-04-26 21:57:51 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-04-26 21:57:51 +0000
commitf91f5c8a66ffd812f61819836529f8ad437f7e2b (patch)
tree1c409fa493e1bda75035839f8b3a64fdffb0d570
parentde1b60a9868f80f0872ed05d78df3b40a10ba5ca (diff)
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
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/AST/Type.cpp3
-rw-r--r--lib/Sema/SemaType.cpp14
-rw-r--r--test/Sema/vla.c3
4 files changed, 20 insertions, 2 deletions
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[*][*]);