diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-03-18 15:42:31 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-03-20 00:52:39 +0100 |
commit | e737cc332ccb8f48fb0f1ddefd4a4fba20140c9d (patch) | |
tree | 37f64763cc671a5847f059ba303fa9ff349b2eb8 | |
parent | 326046a5850b2a50769f1c787b293f0ed7564aa9 (diff) | |
download | sparse-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.c | 10 | ||||
-rw-r--r-- | validation/linear/noreturn-unreachable0.c | 1 |
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: |