]> git.rm.cloudns.org Git - xonotic/gmqcc.git/commitdiff
-fallow-unreachable-code
authorWolfgang Bumiller <blub@speed.at>
Thu, 20 Dec 2012 13:41:16 +0000 (14:41 +0100)
committerWolfgang Bumiller <blub@speed.at>
Thu, 20 Dec 2012 13:41:16 +0000 (14:41 +0100)
ast.c
ir.c
opts.c
opts.def

diff --git a/ast.c b/ast.c
index 93d2a173f9c4a37686229c223e936ac38f7e94a8..8a70549b59338fa48be68f6e2293211594ac99ad 100644 (file)
--- 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 5e8091d4393a9bcd20cb87a97d7bd8af831fc189..5161108c80dfe6d6600d2831bb7db50bfd5b1364 100644 (file)
--- 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 6a6af173682a507530173c8d9795e43d434eecb3..f1aa937a8cb573d158a69fd45f258955e21b1d5b 100644 (file)
--- 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) {
index 157f80fbf9b471735faf17423df720e8e68252a3..e08b57627fcb4e0d130517416aab0a3d9319e576 100644 (file)
--- 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 */