Additional error checking for 'return' statements.
This commit is contained in:
@@ -716,7 +716,7 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
|
||||
case SLANG_OPER_RETURN:
|
||||
/* do return replacement here too */
|
||||
assert(oper->num_children == 0 || oper->num_children == 1);
|
||||
if (!_slang_is_noop(oper)) {
|
||||
if (oper->num_children == 1 && !_slang_is_noop(&oper->children[0])) {
|
||||
/* replace:
|
||||
* return expr;
|
||||
* with:
|
||||
@@ -725,6 +725,14 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
|
||||
* then do substitutions on the assignment.
|
||||
*/
|
||||
slang_operation *blockOper, *assignOper, *returnOper;
|
||||
|
||||
/* check if function actually has a return type */
|
||||
assert(A->CurFunction);
|
||||
if (A->CurFunction->header.type.specifier.type == SLANG_SPEC_VOID) {
|
||||
slang_info_log_error(A->log, "illegal return expression");
|
||||
return;
|
||||
}
|
||||
|
||||
blockOper = slang_operation_new(1);
|
||||
blockOper->type = SLANG_OPER_BLOCK_NO_NEW_SCOPE;
|
||||
blockOper->num_children = 2;
|
||||
@@ -755,6 +763,14 @@ slang_substitute(slang_assemble_ctx *A, slang_operation *oper,
|
||||
slang_operation_copy(oper, blockOper);
|
||||
slang_operation_destruct(blockOper);
|
||||
}
|
||||
else {
|
||||
/* check if return value was expected */
|
||||
assert(A->CurFunction);
|
||||
if (A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) {
|
||||
slang_info_log_error(A->log, "return statement requires an expression");
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SLANG_OPER_ASSIGN:
|
||||
@@ -806,6 +822,11 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
|
||||
slang_variable **substOld;
|
||||
slang_operation **substNew;
|
||||
GLuint substCount, numCopyIn, i;
|
||||
slang_function *prevFunction;
|
||||
|
||||
/* save / push */
|
||||
prevFunction = A->CurFunction;
|
||||
A->CurFunction = fun;
|
||||
|
||||
/*assert(oper->type == SLANG_OPER_CALL); (or (matrix) multiply, etc) */
|
||||
assert(fun->param_count == totalArgs);
|
||||
@@ -1027,6 +1048,10 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun,
|
||||
fun->parameters->num_variables, numArgs);
|
||||
slang_print_tree(top, 0);
|
||||
#endif
|
||||
|
||||
/* pop */
|
||||
A->CurFunction = prevFunction;
|
||||
|
||||
return top;
|
||||
}
|
||||
|
||||
@@ -1703,9 +1728,24 @@ _slang_gen_logical_or(slang_assemble_ctx *A, slang_operation *oper)
|
||||
static slang_ir_node *
|
||||
_slang_gen_return(slang_assemble_ctx * A, slang_operation *oper)
|
||||
{
|
||||
if (oper->num_children == 0 ||
|
||||
(oper->num_children == 1 &&
|
||||
oper->children[0].type == SLANG_OPER_VOID)) {
|
||||
const GLboolean haveReturnValue
|
||||
= (oper->num_children == 1 &&
|
||||
oper->children[0].type != SLANG_OPER_VOID);
|
||||
|
||||
/* error checking */
|
||||
assert(A->CurFunction);
|
||||
if (haveReturnValue &&
|
||||
A->CurFunction->header.type.specifier.type == SLANG_SPEC_VOID) {
|
||||
slang_info_log_error(A->log, "illegal return expression");
|
||||
return NULL;
|
||||
}
|
||||
else if (!haveReturnValue &&
|
||||
A->CurFunction->header.type.specifier.type != SLANG_SPEC_VOID) {
|
||||
slang_info_log_error(A->log, "return statement requires an expression");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!haveReturnValue) {
|
||||
/* Convert from:
|
||||
* return;
|
||||
* To:
|
||||
@@ -1718,7 +1758,6 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper)
|
||||
gotoOp.label = A->curFuncEndLabel;
|
||||
assert(gotoOp.label);
|
||||
|
||||
/* assemble the new code */
|
||||
n = _slang_gen_operation(A, &gotoOp);
|
||||
/* destroy temp code */
|
||||
slang_operation_destruct(&gotoOp);
|
||||
@@ -1743,7 +1782,10 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper)
|
||||
{
|
||||
slang_variable *v
|
||||
= _slang_locate_variable(oper->locals, a_retVal, GL_TRUE);
|
||||
assert(v);
|
||||
if (!v) {
|
||||
/* trying to return a value in a void-valued function */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1843,6 +1885,9 @@ _slang_gen_declaration(slang_assemble_ctx *A, slang_operation *oper)
|
||||
_slang_simplify(v->initializer, &A->space, A->atoms);
|
||||
rhs = _slang_gen_operation(A, v->initializer);
|
||||
#endif
|
||||
if (!rhs)
|
||||
return NULL;
|
||||
|
||||
assert(rhs);
|
||||
init = new_node2(IR_MOVE, var, rhs);
|
||||
/*
|
||||
@@ -2786,6 +2831,8 @@ _slang_codegen_function(slang_assemble_ctx * A, slang_function * fun)
|
||||
assert(A->program->Parameters );
|
||||
assert(A->program->Varying);
|
||||
assert(A->vartable);
|
||||
A->CurLoop = NULL;
|
||||
A->CurFunction = fun;
|
||||
|
||||
/* fold constant expressions, etc. */
|
||||
_slang_simplify(fun->body, &A->space, A->atoms);
|
||||
|
||||
@@ -793,11 +793,12 @@ emit_move(slang_emit_info *emitInfo, slang_ir_node *n)
|
||||
assert(n->Children[1]);
|
||||
inst = emit(emitInfo, n->Children[1]);
|
||||
|
||||
if (!n->Children[1]->Store) {
|
||||
slang_info_log_error(emitInfo->log, "invalid assignment");
|
||||
return NULL;
|
||||
}
|
||||
assert(n->Children[1]->Store->Index >= 0);
|
||||
|
||||
#if 0
|
||||
assert(!n->Store);
|
||||
#endif
|
||||
n->Store = n->Children[0]->Store;
|
||||
|
||||
#if PEEPHOLE_OPTIMIZATIONS
|
||||
|
||||
@@ -64,6 +64,7 @@ typedef struct slang_assemble_ctx_
|
||||
slang_info_log *log;
|
||||
struct slang_label_ *curFuncEndLabel;
|
||||
struct slang_ir_node_ *CurLoop;
|
||||
struct slang_function_ *CurFunction;
|
||||
} slang_assemble_ctx;
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user