aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-03-18 15:42:31 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-03-20 00:52:39 +0100
commite737cc332ccb8f48fb0f1ddefd4a4fba20140c9d (patch)
tree37f64763cc671a5847f059ba303fa9ff349b2eb8
parent326046a5850b2a50769f1c787b293f0ed7564aa9 (diff)
downloadsparse-e737cc332ccb8f48fb0f1ddefd4a4fba20140c9d.tar.gz
add an implicit __builtin_unreachable() for __noreturn
The semantic of a __noreturn function is that ... it doesn't return. So, insert an instruction OP_UNREACH after calls to such functions. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--linearize.c10
-rw-r--r--validation/linear/noreturn-unreachable0.c1
2 files changed, 10 insertions, 1 deletions
diff --git a/linearize.c b/linearize.c
index 8e45f414..a8395bff 100644
--- a/linearize.c
+++ b/linearize.c
@@ -657,6 +657,13 @@ static void add_one_insn(struct entrypoint *ep, struct instruction *insn)
}
}
+static void add_unreachable(struct entrypoint *ep)
+{
+ struct instruction *insn = alloc_instruction(OP_UNREACH, 0);
+ add_one_insn(ep, insn);
+ ep->active = NULL;
+}
+
static void set_activeblock(struct entrypoint *ep, struct basic_block *bb)
{
if (!bb_terminated(ep->active))
@@ -1551,6 +1558,9 @@ static pseudo_t linearize_call_expression(struct entrypoint *ep, struct expressi
add_one_insn(ep, insn);
}
} END_FOR_EACH_PTR(context);
+
+ if (ctype->modifiers & MOD_NORETURN)
+ add_unreachable(ep);
}
return retval;
diff --git a/validation/linear/noreturn-unreachable0.c b/validation/linear/noreturn-unreachable0.c
index 47bd6aa3..9bcd605f 100644
--- a/validation/linear/noreturn-unreachable0.c
+++ b/validation/linear/noreturn-unreachable0.c
@@ -9,7 +9,6 @@ int foo(void)
/*
* check-name: noreturn-unreachable0
* check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
*
* check-output-start
foo: