From 1da2834b1e1a49711b191f39a1352e8d8eaec04a Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Sun, 25 Mar 2012 13:10:12 -0700 Subject: [PATCH] Allow the last member of a struct to be an unsized/zero-length array. This enables the C truck of allocating a dynamic amount of storage for the struct in order to extend out the array to the desired length. --- decl.cpp | 19 ++++++++++--------- tests/struct-zero-len-array-member.ispc | 24 ++++++++++++++++++++++++ tests_errors/struct-unsized-array.ispc | 2 +- 3 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 tests/struct-zero-len-array-member.ispc diff --git a/decl.cpp b/decl.cpp index f4382c8b..c881c7e7 100644 --- a/decl.cpp +++ b/decl.cpp @@ -739,15 +739,7 @@ GetStructTypesNamesPositions(const std::vector &sd, if (Type::Equal(sym->type, AtomicType::Void)) Error(d->pos, "\"void\" type illegal for struct member."); - const ArrayType *arrayType = - dynamic_cast(sym->type); - if (arrayType != NULL && arrayType->GetElementCount() == 0) { - Error(d->pos, "Unsized arrays aren't allowed in struct " - "definitions."); - elementTypes->push_back(NULL); - } - else - elementTypes->push_back(sym->type); + elementTypes->push_back(sym->type); if (seenNames.find(sym->name) != seenNames.end()) Error(d->pos, "Struct member \"%s\" has same name as a " @@ -759,4 +751,13 @@ GetStructTypesNamesPositions(const std::vector &sd, elementPositions->push_back(sym->pos); } } + + for (int i = 0; i < (int)elementTypes->size() - 1; ++i) { + const ArrayType *arrayType = + dynamic_cast((*elementTypes)[i]); + + if (arrayType != NULL && arrayType->GetElementCount() == 0) + Error((*elementPositions)[i], "Unsized arrays aren't allowed except " + "for the last member in a struct definition."); + } } diff --git a/tests/struct-zero-len-array-member.ispc b/tests/struct-zero-len-array-member.ispc new file mode 100644 index 00000000..83e91854 --- /dev/null +++ b/tests/struct-zero-len-array-member.ispc @@ -0,0 +1,24 @@ + +struct Foo { + float x; + float a[0]; +}; + +export uniform int width() { return programCount; } + + +export void f_f(uniform float RET[], uniform float aFOO[]) { + uniform int nFloats = 3+programCount; + varying Foo * uniform ptr = (varying Foo * uniform)(uniform new varying int32[nFloats]); + memset(ptr, 0, nFloats*sizeof(int32)); + + for (uniform int i = 0; i < nFloats-1; ++i) + ptr->a[i] = i; + ptr->x = aFOO[programIndex]; + + RET[programIndex] = ptr->a[1+programIndex]; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 1 + programIndex; +} diff --git a/tests_errors/struct-unsized-array.ispc b/tests_errors/struct-unsized-array.ispc index 77553eff..7238a351 100644 --- a/tests_errors/struct-unsized-array.ispc +++ b/tests_errors/struct-unsized-array.ispc @@ -1,4 +1,4 @@ -// Unsized arrays aren't allowed in struct definitions +// Unsized arrays aren't allowed except for the last member in a struct definition. struct Foo { float a[];