Fix cases where we were trying to type cast instead of type convert.

Also, removed erroneous checks about the type of the test expression
in DoStmt and ForStmt.

These together were preventing conversion of pointer types to boolean
values, so things like "while (ptr)" would improperly not compile.

Issue #346.
This commit is contained in:
Matt Pharr
2012-08-03 12:47:53 -07:00
parent 8f5189f606
commit 2a19cc1758

View File

@@ -917,12 +917,6 @@ Stmt *
DoStmt::TypeCheck() { DoStmt::TypeCheck() {
const Type *testType; const Type *testType;
if (testExpr != NULL && (testType = testExpr->GetType()) != NULL) { if (testExpr != NULL && (testType = testExpr->GetType()) != NULL) {
if (!testType->IsNumericType() && !testType->IsBoolType()) {
Error(testExpr->pos, "Type \"%s\" can't be converted to boolean for \"while\" "
"test in \"do\" loop.", testExpr->GetType()->GetString().c_str());
return NULL;
}
// Should the test condition for the loop be uniform or varying? // Should the test condition for the loop be uniform or varying?
// It can be uniform only if three conditions are met: // It can be uniform only if three conditions are met:
// //
@@ -942,9 +936,9 @@ DoStmt::TypeCheck() {
bool uniformTest = (testType->IsUniformType() && bool uniformTest = (testType->IsUniformType() &&
!g->opt.disableUniformControlFlow && !g->opt.disableUniformControlFlow &&
!lHasVaryingBreakOrContinue(bodyStmts)); !lHasVaryingBreakOrContinue(bodyStmts));
testExpr = new TypeCastExpr(uniformTest ? AtomicType::UniformBool : testExpr = TypeConvertExpr(testExpr, uniformTest ? AtomicType::UniformBool :
AtomicType::VaryingBool, AtomicType::VaryingBool,
testExpr, testExpr->pos); "\"do\" statement");
} }
return this; return this;
@@ -1118,20 +1112,14 @@ Stmt *
ForStmt::TypeCheck() { ForStmt::TypeCheck() {
const Type *testType; const Type *testType;
if (test && (testType = test->GetType()) != NULL) { if (test && (testType = test->GetType()) != NULL) {
if (!testType->IsNumericType() && !testType->IsBoolType()) {
Error(test->pos, "Type \"%s\" can't be converted to boolean for \"for\" "
"loop test.", test->GetType()->GetString().c_str());
return NULL;
}
// See comments in DoStmt::TypeCheck() regarding // See comments in DoStmt::TypeCheck() regarding
// 'uniformTest' and the type cast here. // 'uniformTest' and the type conversion here.
bool uniformTest = (testType->IsUniformType() && bool uniformTest = (testType->IsUniformType() &&
!g->opt.disableUniformControlFlow && !g->opt.disableUniformControlFlow &&
!lHasVaryingBreakOrContinue(stmts)); !lHasVaryingBreakOrContinue(stmts));
test = new TypeCastExpr(uniformTest ? AtomicType::UniformBool : test = TypeConvertExpr(test, uniformTest ? AtomicType::UniformBool :
AtomicType::VaryingBool, test, test->pos); AtomicType::VaryingBool,
test = ::TypeCheck(test); "\"for\"/\"while\" statement");
if (test == NULL) if (test == NULL)
return NULL; return NULL;
} }
@@ -3183,15 +3171,11 @@ AssertStmt::TypeCheck() {
const Type *type; const Type *type;
if (expr && (type = expr->GetType()) != NULL) { if (expr && (type = expr->GetType()) != NULL) {
bool isUniform = type->IsUniformType(); bool isUniform = type->IsUniformType();
if (!type->IsNumericType() && !type->IsBoolType()) { expr = TypeConvertExpr(expr, isUniform ? AtomicType::UniformBool :
Error(expr->pos, "Type \"%s\" can't be converted to boolean for \"assert\".", AtomicType::VaryingBool,
type->GetString().c_str()); "\"assert\" statement");
if (expr == NULL)
return NULL; return NULL;
}
expr = new TypeCastExpr(isUniform ? AtomicType::UniformBool :
AtomicType::VaryingBool,
expr, expr->pos);
expr = ::TypeCheck(expr);
} }
return this; return this;
} }