diff options
| author | Steve Naroff <snaroff@apple.com> | 2007-08-30 22:35:45 +0000 |
|---|---|---|
| committer | Steve Naroff <snaroff@apple.com> | 2007-08-30 22:35:45 +0000 |
| commit | d57fa94148963517a365e5bebdd9c72ab255c3b8 (patch) | |
| tree | 45beef0a28eb9cc01c8ee9090660f88bb8a73c97 /clang | |
| parent | fc7aafcef0825894dfe3a7a5840615847e13aeba (diff) | |
| download | bcm5719-llvm-d57fa94148963517a365e5bebdd9c72ab255c3b8.tar.gz bcm5719-llvm-d57fa94148963517a365e5bebdd9c72ab255c3b8.zip | |
Final phase of array cleanup (for now), removing a FIXME from yesterday.
Moved several array constraints checks from Sema::VerifyConstantArrayType() to
Sema::GetTypeForDeclarator(). VerifyConstantArrayType() is now very simple, and
could be removed eventually.
Now, we get the following (correct) messages for BlockVarDecls:-)
[dylan:~/llvm/tools/clang] admin% ../../Debug/bin/clang x.c -pedantic
x.c:4:20: error: size of array has non-integer type 'float'
int size_not_int[f];
^
x.c:5:21: error: array size is negative
int negative_size[1-2];
^~~
x.c:6:17: warning: zero size arrays are an extension
int zero_size[0];
^
3 diagnostics generated.
llvm-svn: 41624
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/Sema/SemaDecl.cpp | 43 | ||||
| -rw-r--r-- | clang/Sema/SemaType.cpp | 24 | ||||
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticKinds.def | 2 | ||||
| -rw-r--r-- | clang/test/Sema/array-constraint.c | 8 |
4 files changed, 34 insertions, 43 deletions
diff --git a/clang/Sema/SemaDecl.cpp b/clang/Sema/SemaDecl.cpp index f1a6e78b6a8..cc0682a8da5 100644 --- a/clang/Sema/SemaDecl.cpp +++ b/clang/Sema/SemaDecl.cpp @@ -25,59 +25,22 @@ #include "llvm/ADT/SmallSet.h" using namespace clang; -// C99: 6.7.5p3: Used by ParseDeclarator/ParseField to make sure we have -// a constant expression of type int with a value greater than zero. +// C99 6.7.2.1p8: Used by ParseDeclarator/ParseField to make sure we have +// a constant expression. We return true if we don't have a ConstantArrayType. bool Sema::VerifyConstantArrayType(const ArrayType *Array, SourceLocation DeclLoc) { if (const VariableArrayType *VLA = dyn_cast<VariableArrayType>(Array)) { Expr *Size = VLA->getSizeExpr(); - if (Size == 0) - return false; // incomplete type. - - if (!Size->getType()->isIntegerType()) { - Diag(Size->getLocStart(), diag::err_array_size_non_int, - Size->getType().getAsString(), Size->getSourceRange()); - return false; - } - // FIXME: I don't think this is needed. It remains to keep test - // builtin_classify_type() happy...will revisit soon (today is 8/29/07:-) - SourceLocation Loc; - llvm::APSInt SizeVal(32); - if (!Size->isIntegerConstantExpr(SizeVal, Context, &Loc)) { + if (Size) { // FIXME: This emits the diagnostic to enforce 6.7.2.1p8, but the message // is wrong. It is also wrong for static variables. // FIXME: This is also wrong for: // int sub1(int i, char *pi) { typedef int foo[i]; // struct bar {foo f1; int f2:3; int f3:4} *p; } Diag(DeclLoc, diag::err_typecheck_illegal_vla, Size->getSourceRange()); - return false; } return true; } - const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Array); - - assert(CAT && "Sema::VerifyConstantArrayType(): Illegal array type"); - - llvm::APSInt SizeVal(32); - SizeVal = CAT->getSize(); - - // We have a constant expression with an integer type, now make sure - // value greater than zero (C99 6.7.5.2p1). - - // FIXME: This check isn't specific to static VLAs, this should be moved - // elsewhere or replicated. 'int X[-1];' inside a function should emit an - // error. - if (SizeVal.isSigned()) { - llvm::APSInt Zero(SizeVal.getBitWidth()); - Zero.setIsUnsigned(false); - if (SizeVal < Zero) { - Diag(DeclLoc, diag::err_typecheck_negative_array_size); - return true; - } else if (SizeVal == 0) { - // GCC accepts zero sized static arrays. - Diag(DeclLoc, diag::err_typecheck_zero_array_size); - } - } return false; } diff --git a/clang/Sema/SemaType.cpp b/clang/Sema/SemaType.cpp index d1d62a6ea20..17b34628b5f 100644 --- a/clang/Sema/SemaType.cpp +++ b/clang/Sema/SemaType.cpp @@ -202,13 +202,33 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { D.setInvalidType(true); } } + // C99 6.7.5.2p1: The size expression shall have integer type. + if (ArraySize && !ArraySize->getType()->isIntegerType()) { + Diag(ArraySize->getLocStart(), diag::err_array_size_non_int, + ArraySize->getType().getAsString(), ArraySize->getSourceRange()); + D.setInvalidType(true); + } llvm::APSInt ConstVal(32); // If no expression was provided, we consider it a VLA. if (!ArraySize || !ArraySize->isIntegerConstantExpr(ConstVal, Context)) T = Context.getVariableArrayType(T, ArraySize, ASM, ATI.TypeQuals); - else + else { + // C99 6.7.5.2p1: If the expression is a constant expression, it shall + // have a value greater than zero. + if (ConstVal.isSigned()) { + if (ConstVal.isNegative()) { + Diag(ArraySize->getLocStart(), + diag::err_typecheck_negative_array_size, + ArraySize->getSourceRange()); + D.setInvalidType(true); + } else if (ConstVal == 0) { + // GCC accepts zero sized static arrays. + Diag(ArraySize->getLocStart(), diag::ext_typecheck_zero_array_size, + ArraySize->getSourceRange()); + } + } T = Context.getConstantArrayType(T, ConstVal, ASM, ATI.TypeQuals); - + } // If this is not C99, extwarn about VLA's and C99 array size modifiers. if (!getLangOptions().C99 && (ASM != ArrayType::Normal || diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index dbfa1e6f9ed..9eaf4d40616 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -534,7 +534,7 @@ DIAG(err_typecheck_illegal_vla, ERROR, "variable length array declared outside of any function") DIAG(err_typecheck_negative_array_size, ERROR, "array size is negative") -DIAG(err_typecheck_zero_array_size, EXTENSION, +DIAG(ext_typecheck_zero_array_size, EXTENSION, "zero size arrays are an extension") DIAG(err_array_size_non_int, ERROR, "size of array has non-integer type '%0'") diff --git a/clang/test/Sema/array-constraint.c b/clang/test/Sema/array-constraint.c index 4d1c2f16007..1ca3cd7aec9 100644 --- a/clang/test/Sema/array-constraint.c +++ b/clang/test/Sema/array-constraint.c @@ -31,3 +31,11 @@ typedef int (*pfunc)(void); pfunc xx(int f[](void)) { // expected-error {{'f' declared as array of functions}} return f; } + +void check_size() { + float f; + int size_not_int[f]; // expected-error {{size of array has non-integer type 'float'}} + int negative_size[1-2]; // expected-error{{array size is negative}} + int zero_size[0]; // expected-warning{{zero size arrays are an extension}} +} + |

