[PATCH 2/2] fix linearization of unreachable switch (with reachable label).

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



An unreachable/inactive switch statement is currently not
linearized. That's is nice because it avoids to create useless
instructions but the body of the statement can contain a label
which can be reachable. In this case, the resulting IR contains
a branch to an unexisting BB. Bad.
For example, code like:
	static int foo(int a)
	{
		goto label;
		switch(a) {
		default:
	label:
			break;
		}
		return 0;
	}

which is just a complicated way to write:
	static int foo(int a)
	{
		return 0;
	}

is linearized as:
	foo:
	.L0:
		<entry-point>
		br          .L1

Fix this by linearizing the statement even if not active.

Note: it seems that none of the other statements are discarded
      if inactive. Good. OTOH, statement expressions can also
      contains (reachable) labels and thus would need the same
      fix (which will need much more work).

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
---
 linearize.c                            | 11 ++++++-----
 validation/linear/unreachable-label0.c |  1 -
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/linearize.c b/linearize.c
index 2e9a56383..76f3b52a9 100644
--- a/linearize.c
+++ b/linearize.c
@@ -2132,13 +2132,14 @@ static pseudo_t linearize_switch(struct entrypoint *ep, struct statement *stmt)
 	struct multijmp *jmp;
 	pseudo_t pseudo;
 
+	if (!expr || !expr->ctype)
+		return VOID;
 	pseudo = linearize_expression(ep, expr);
-	if (pseudo == VOID)
-		return pseudo;
-
 	active = ep->active;
-	if (!bb_reachable(active))
-		return VOID;
+	if (!active) {
+		active = alloc_basic_block(ep, stmt->pos);
+		set_activeblock(ep, active);
+	}
 
 	switch_ins = alloc_typed_instruction(OP_SWITCH, expr->ctype);
 	use_pseudo(switch_ins, pseudo, &switch_ins->cond);
diff --git a/validation/linear/unreachable-label0.c b/validation/linear/unreachable-label0.c
index 568ae588a..695e5cb07 100644
--- a/validation/linear/unreachable-label0.c
+++ b/validation/linear/unreachable-label0.c
@@ -12,7 +12,6 @@ label:
 /*
  * check-name: unreachable-label0
  * check-command: test-linearize $file
- * check-known-to-fail
  *
  * check-output-ignore
  * check-output-contains: ret\\.
-- 
2.18.0




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux