From 8603f9838f777da956a592475694e450e807bbb8 Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Tue, 21 Feb 2012 12:26:42 -0800 Subject: [PATCH] Issue an error if "uniform" or "varying" qualifiers are applied to void types. Issue #179. --- decl.cpp | 19 +++++++++---- parse.yy | 44 +++++++++++++++++++++++++---- tests_errors/void-qualifiers-1.ispc | 3 ++ tests_errors/void-qualifiers-2.ispc | 5 ++++ tests_errors/void-qualifiers-3.ispc | 3 ++ tests_errors/void-qualifiers-4.ispc | 3 ++ type.cpp | 9 ++---- 7 files changed, 69 insertions(+), 17 deletions(-) create mode 100644 tests_errors/void-qualifiers-1.ispc create mode 100644 tests_errors/void-qualifiers-2.ispc create mode 100644 tests_errors/void-qualifiers-3.ispc create mode 100644 tests_errors/void-qualifiers-4.ispc diff --git a/decl.cpp b/decl.cpp index ada96eca..608321cb 100644 --- a/decl.cpp +++ b/decl.cpp @@ -69,12 +69,21 @@ lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) { if ((typeQualifiers & TYPEQUAL_CONST) != 0) type = type->GetAsConstType(); - if ((typeQualifiers & TYPEQUAL_UNIFORM) != 0) - type = type->GetAsUniformType(); - else if ((typeQualifiers & TYPEQUAL_VARYING) != 0) - type = type->GetAsVaryingType(); + if ((typeQualifiers & TYPEQUAL_UNIFORM) != 0) { + if (type == AtomicType::Void) + Error(pos, "\"uniform\" qualifier is illegal with \"void\" type."); + else + type = type->GetAsUniformType(); + } + else if ((typeQualifiers & TYPEQUAL_VARYING) != 0) { + if (type == AtomicType::Void) + Error(pos, "\"varying\" qualifier is illegal with \"void\" type."); + else + type = type->GetAsVaryingType(); + } else - type = type->GetAsUnboundVariabilityType(); + if (type != AtomicType::Void) + type = type->GetAsUnboundVariabilityType(); if ((typeQualifiers & TYPEQUAL_UNSIGNED) != 0) { if ((typeQualifiers & TYPEQUAL_SIGNED) != 0) diff --git a/parse.yy b/parse.yy index d2507884..b807053f 100644 --- a/parse.yy +++ b/parse.yy @@ -473,8 +473,28 @@ rate_qualified_new rate_qualified_new_type : type_specifier { $$ = $1; } - | TOKEN_UNIFORM type_specifier { $$ = $2 ? $2->GetAsUniformType() : NULL; } - | TOKEN_VARYING type_specifier { $$ = $2 ? $2->GetAsVaryingType() : NULL; } + | TOKEN_UNIFORM type_specifier + { + if ($2 == NULL) + $$ = NULL; + else if ($2 == AtomicType::Void) { + Error(@1, "\"uniform\" qualifier is illegal with \"void\" type."); + $$ = NULL; + } + else + $$ = $2->GetAsUniformType(); + } + | TOKEN_VARYING type_specifier + { + if ($2 == NULL) + $$ = NULL; + else if ($2 == AtomicType::Void) { + Error(@1, "\"varying\" qualifier is illegal with \"void\" type."); + $$ = NULL; + } + else + $$ = $2->GetAsVaryingType(); + } ; new_expression @@ -803,10 +823,22 @@ specifier_qualifier_list | type_qualifier specifier_qualifier_list { if ($2 != NULL) { - if ($1 == TYPEQUAL_UNIFORM) - $$ = $2->GetAsUniformType(); - else if ($1 == TYPEQUAL_VARYING) - $$ = $2->GetAsVaryingType(); + if ($1 == TYPEQUAL_UNIFORM) { + if ($2 == AtomicType::Void) { + Error(@1, "\"uniform\" qualifier is illegal with \"void\" type."); + $$ = NULL; + } + else + $$ = $2->GetAsUniformType(); + } + else if ($1 == TYPEQUAL_VARYING) { + if ($2 == AtomicType::Void) { + Error(@1, "\"varying\" qualifier is illegal with \"void\" type."); + $$ = NULL; + } + else + $$ = $2->GetAsVaryingType(); + } else if ($1 == TYPEQUAL_CONST) $$ = $2->GetAsConstType(); else if ($1 == TYPEQUAL_SIGNED) { diff --git a/tests_errors/void-qualifiers-1.ispc b/tests_errors/void-qualifiers-1.ispc new file mode 100644 index 00000000..44e91343 --- /dev/null +++ b/tests_errors/void-qualifiers-1.ispc @@ -0,0 +1,3 @@ +// "varying" qualifier is illegal with "void" type + +varying void *foo; diff --git a/tests_errors/void-qualifiers-2.ispc b/tests_errors/void-qualifiers-2.ispc new file mode 100644 index 00000000..6d9d9c69 --- /dev/null +++ b/tests_errors/void-qualifiers-2.ispc @@ -0,0 +1,5 @@ +// "uniform" qualifier is illegal with "void" type + +struct FFF { + uniform void *x; +}; diff --git a/tests_errors/void-qualifiers-3.ispc b/tests_errors/void-qualifiers-3.ispc new file mode 100644 index 00000000..5e60d216 --- /dev/null +++ b/tests_errors/void-qualifiers-3.ispc @@ -0,0 +1,3 @@ +// "varying" qualifier is illegal with "void" type + +varying void *foo() { } diff --git a/tests_errors/void-qualifiers-4.ispc b/tests_errors/void-qualifiers-4.ispc new file mode 100644 index 00000000..c1cc75f9 --- /dev/null +++ b/tests_errors/void-qualifiers-4.ispc @@ -0,0 +1,3 @@ +// "varying" qualifier is illegal with "void" type + +void foo(varying void *x) { } diff --git a/type.cpp b/type.cpp index bdc096fd..cabcc41b 100644 --- a/type.cpp +++ b/type.cpp @@ -382,24 +382,21 @@ AtomicType::GetBaseType() const { const AtomicType * AtomicType::GetAsVaryingType() const { - if (this == AtomicType::Void) - return this; + Assert(this != AtomicType::Void); return typeTable[basicType][Varying][isConst ? 1 : 0]; } const AtomicType * AtomicType::GetAsUniformType() const { - if (this == AtomicType::Void) - return this; + Assert(this != AtomicType::Void); return typeTable[basicType][Uniform][isConst ? 1 : 0]; } const AtomicType * AtomicType::GetAsUnboundVariabilityType() const { - if (this == AtomicType::Void) - return this; + Assert(this != AtomicType::Void); return typeTable[basicType][Unbound][isConst ? 1 : 0]; }