aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2008-02-17 00:59:11 +0000
committerEli Friedman <eli.friedman@gmail.com>2008-02-17 00:59:11 +0000
commitd3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0 (patch)
treeb6b796ce7ee36fe3a7de84c9139a526d0fe5f17e
parent19a1d7c646729eb858b15583e647262a22de3637 (diff)
Implemnt isVariablyModifiedType correctly.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47233 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--AST/Type.cpp28
-rw-r--r--test/Sema/typedef-variable-type.c3
2 files changed, 25 insertions, 6 deletions
diff --git a/AST/Type.cpp b/AST/Type.cpp
index 13ffb0e220..7e72d82bc2 100644
--- a/AST/Type.cpp
+++ b/AST/Type.cpp
@@ -246,13 +246,29 @@ const VariableArrayType *Type::getAsVariableArrayType() const {
return getDesugaredType()->getAsVariableArrayType();
}
-/// isVariablyModifiedType (C99 6.7.5.2p2) - Return true for variable array
-/// types that have a non-constant expression. This does not include "[]".
+/// isVariablyModifiedType (C99 6.7.5p3) - Return true for variable length
+/// array types and types that contain variable array types in their
+/// declarator
bool Type::isVariablyModifiedType() const {
- if (const VariableArrayType *VAT = getAsVariableArrayType()) {
- if (VAT->getSizeExpr())
- return true;
- }
+ // A VLA is a veriably modified type
+ if (getAsVariableArrayType())
+ return true;
+
+ // An array can contain a variably modified type
+ if (const ArrayType* AT = getAsArrayType())
+ return AT->getElementType()->isVariablyModifiedType();
+
+ // A pointer can point to a variably modified type
+ if (const PointerType* PT = getAsPointerType())
+ return PT->getPointeeType()->isVariablyModifiedType();
+
+ // A function can return a variably modified type
+ // This one isn't completely obvious, but it follows from the
+ // definition in C99 6.7.5p3. Because of this rule, it's
+ // illegal to declare a function returning a variably modified type.
+ if (const FunctionType* FT = getAsFunctionType())
+ return FT->getResultType()->isVariablyModifiedType();
+
return false;
}
diff --git a/test/Sema/typedef-variable-type.c b/test/Sema/typedef-variable-type.c
new file mode 100644
index 0000000000..3abca4314e
--- /dev/null
+++ b/test/Sema/typedef-variable-type.c
@@ -0,0 +1,3 @@
+// RUN: clang %s -verify -fsyntax-only -pedantic
+
+typedef int (*a)[!.0]; // expected-error{{variable length array declared outside of any function}}