From 3119a95a89e991e42cd52c8ce2c17ab78542c1c2 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Thu, 20 Dec 2012 14:41:16 +0100 Subject: [PATCH] -fallow-unreachable-code --- ast.c | 2 ++ ir.c | 37 ++++++++++++++++--------------------- opts.c | 1 + opts.def | 1 + 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/ast.c b/ast.c index 93d2a17..8a70549 100644 --- a/ast.c +++ b/ast.c @@ -1570,6 +1570,8 @@ bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_valu { ast_expression_codegen *gen = self->exprs[i]->expression.codegen; if (func->curblock->final && !ast_istype(self->exprs[i], ast_label)) { + if (OPTS_FLAG(ALLOW_UNREACHABLE_CODE)) + continue; compile_error(ast_ctx(self->exprs[i]), "unreachable statement"); return false; } diff --git a/ir.c b/ir.c index 5e8091d..5161108 100644 --- a/ir.c +++ b/ir.c @@ -1360,13 +1360,20 @@ bool ir_values_overlap(const ir_value *a, const ir_value *b) *IR main operations */ +static bool ir_check_unreachable(ir_block *self) +{ + /* The IR should never have to deal with unreachable code */ + if (!self->final/* || OPTS_FLAG(ALLOW_UNREACHABLE_CODE)*/) + return true; + irerror(self->context, "unreachable statement (%s)", self->label); + return false; +} + bool ir_block_create_store_op(ir_block *self, lex_ctx ctx, int op, ir_value *target, ir_value *what) { ir_instr *in; - if (self->final) { - irerror(self->context, "unreachable statement (%s)", self->label); + if (!ir_check_unreachable(self)) return false; - } if (target->store == store_value && (op < INSTR_STOREP_F || op > INSTR_STOREP_FNC)) @@ -1441,10 +1448,8 @@ bool ir_block_create_storep(ir_block *self, lex_ctx ctx, ir_value *target, ir_va bool ir_block_create_return(ir_block *self, lex_ctx ctx, ir_value *v) { ir_instr *in; - if (self->final) { - irerror(self->context, "unreachable statement (%s)", self->label); + if (!ir_check_unreachable(self)) return false; - } self->final = true; self->is_return = true; in = ir_instr_new(ctx, self, INSTR_RETURN); @@ -1464,10 +1469,8 @@ bool ir_block_create_if(ir_block *self, lex_ctx ctx, ir_value *v, ir_block *ontrue, ir_block *onfalse) { ir_instr *in; - if (self->final) { - irerror(self->context, "unreachable statement (%s)", self->label); + if (!ir_check_unreachable(self)) return false; - } self->final = true; /*in = ir_instr_new(ctx, self, (v->vtype == TYPE_STRING ? INSTR_IF_S : INSTR_IF_F));*/ in = ir_instr_new(ctx, self, VINSTR_COND); @@ -1494,10 +1497,8 @@ bool ir_block_create_if(ir_block *self, lex_ctx ctx, ir_value *v, bool ir_block_create_jump(ir_block *self, lex_ctx ctx, ir_block *to) { ir_instr *in; - if (self->final) { - irerror(self->context, "unreachable statement (%s)", self->label); + if (!ir_check_unreachable(self)) return false; - } self->final = true; in = ir_instr_new(ctx, self, VINSTR_JUMP); if (!in) @@ -1514,10 +1515,8 @@ bool ir_block_create_jump(ir_block *self, lex_ctx ctx, ir_block *to) bool ir_block_create_goto(ir_block *self, lex_ctx ctx, ir_block *to) { ir_instr *in; - if (self->final) { - irerror(self->context, "unreachable statement (%s)", self->label); + if (!ir_check_unreachable(self)) return false; - } self->final = true; in = ir_instr_new(ctx, self, INSTR_GOTO); if (!in) @@ -1535,10 +1534,8 @@ ir_instr* ir_block_create_phi(ir_block *self, lex_ctx ctx, const char *label, in { ir_value *out; ir_instr *in; - if (self->final) { - irerror(self->context, "unreachable statement (%s)", self->label); + if (!ir_check_unreachable(self)) return false; - } in = ir_instr_new(ctx, self, VINSTR_PHI); if (!in) return NULL; @@ -1584,10 +1581,8 @@ ir_instr* ir_block_create_call(ir_block *self, lex_ctx ctx, const char *label, i { ir_value *out; ir_instr *in; - if (self->final) { - irerror(self->context, "unreachable statement (%s)", self->label); + if (!ir_check_unreachable(self)) return false; - } in = ir_instr_new(ctx, self, (noreturn ? VINSTR_NRCALL : INSTR_CALL0)); if (!in) return NULL; diff --git a/opts.c b/opts.c index 6a6af17..f1aa937 100644 --- a/opts.c +++ b/opts.c @@ -54,6 +54,7 @@ static void opts_setdefault() { opts_set(opts.flags, ADJUST_VECTOR_FIELDS, true); opts_set(opts.flags, FTEPP, false); opts_set(opts.flags, CORRECT_TERNARY, true); + opts_set(opts.flags, ALLOW_UNREACHABLE_CODE, true); } void opts_init(const char *output, int standard, size_t arraysize) { diff --git a/opts.def b/opts.def index 157f80f..e08b576 100644 --- a/opts.def +++ b/opts.def @@ -40,6 +40,7 @@ GMQCC_DEFINE_FLAG(LNO) GMQCC_DEFINE_FLAG(CORRECT_TERNARY) GMQCC_DEFINE_FLAG(SINGLE_VECTOR_DEFS) + GMQCC_DEFINE_FLAG(ALLOW_UNREACHABLE_CODE) #endif /* warning flags */ -- 2.39.2