]> granicus.if.org Git - clang/commitdiff
Implemnt isVariablyModifiedType correctly.
authorEli Friedman <eli.friedman@gmail.com>
Sun, 17 Feb 2008 00:59:11 +0000 (00:59 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Sun, 17 Feb 2008 00:59:11 +0000 (00:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47233 91177308-0d34-0410-b5e6-96231b3b80d8

AST/Type.cpp
test/Sema/typedef-variable-type.c [new file with mode: 0644]

index 13ffb0e220988a2f5cc9531e78df3e1617ee46b1..7e72d82bc2b7f146c742ab90a6910852603c632b 100644 (file)
@@ -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 (file)
index 0000000..3abca43
--- /dev/null
@@ -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}}