diff --git a/parse.yy b/parse.yy index b9c33a91..239f5239 100644 --- a/parse.yy +++ b/parse.yy @@ -947,10 +947,16 @@ direct_declarator { int size; if ($1 != NULL && lGetConstantInt($3, &size, @3, "Array dimension")) { - Declarator *d = new Declarator(DK_ARRAY, Union(@1, @4)); - d->arraySize = size; - d->child = $1; - $$ = d; + if (size < 0) { + Error(@3, "Array dimension must be non-negative."); + $$ = NULL; + } + else { + Declarator *d = new Declarator(DK_ARRAY, Union(@1, @4)); + d->arraySize = size; + d->child = $1; + $$ = d; + } } else $$ = NULL; @@ -1141,10 +1147,16 @@ direct_abstract_declarator | '[' constant_expression ']' { int size; - if (lGetConstantInt($2, &size, @2, "Array dimension")) { - Declarator *d = new Declarator(DK_ARRAY, Union(@1, @3)); - d->arraySize = size; - $$ = d; + if ($2 != NULL && lGetConstantInt($2, &size, @2, "Array dimension")) { + if (size < 0) { + Error(@2, "Array dimension must be non-negative."); + $$ = NULL; + } + else { + Declarator *d = new Declarator(DK_ARRAY, Union(@1, @3)); + d->arraySize = size; + $$ = d; + } } else $$ = NULL; @@ -1159,11 +1171,17 @@ direct_abstract_declarator | direct_abstract_declarator '[' constant_expression ']' { int size; - if (lGetConstantInt($3, &size, @3, "Array dimension")) { - Declarator *d = new Declarator(DK_ARRAY, Union(@1, @4)); - d->arraySize = size; - d->child = $1; - $$ = d; + if ($3 != NULL && lGetConstantInt($3, &size, @3, "Array dimension")) { + if (size < 0) { + Error(@3, "Array dimension must be non-negative."); + $$ = NULL; + } + else { + Declarator *d = new Declarator(DK_ARRAY, Union(@1, @4)); + d->arraySize = size; + d->child = $1; + $$ = d; + } } else $$ = NULL; @@ -1674,6 +1692,10 @@ lGetConstantInt(Expr *expr, int *value, SourcePos pos, const char *usage) { Error(pos, "%s must be a compile-time integer constant.", usage); return false; } + if ((int64_t)((int32_t)ci->getSExtValue()) != ci->getSExtValue()) { + Error(pos, "%s must be representable with a 32-bit integer.", usage); + return false; + } *value = (int)ci->getZExtValue(); return true; } diff --git a/tests_errors/array-dim-huge.ispc b/tests_errors/array-dim-huge.ispc new file mode 100644 index 00000000..df061810 --- /dev/null +++ b/tests_errors/array-dim-huge.ispc @@ -0,0 +1,7 @@ +// Array dimension must be representable with a 32-bit integer. + +struct foo { + int x[0xffffffffffff]; +}; + + diff --git a/tests_errors/array-dim-negative.ispc b/tests_errors/array-dim-negative.ispc new file mode 100644 index 00000000..1be67104 --- /dev/null +++ b/tests_errors/array-dim-negative.ispc @@ -0,0 +1,7 @@ +// Array dimension must be non-negative + +struct foo { + int x[-1]; +}; + +