diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2008-02-17 00:59:11 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2008-02-17 00:59:11 +0000 |
commit | d3f2f79fedfef7cae818c55a1f3d7a8f5992e5a0 (patch) | |
tree | b6b796ce7ee36fe3a7de84c9139a526d0fe5f17e | |
parent | 19a1d7c646729eb858b15583e647262a22de3637 (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.cpp | 28 | ||||
-rw-r--r-- | test/Sema/typedef-variable-type.c | 3 |
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}} |