diff mbox

Fix PR78383 middle-end ICE

Message ID alpine.LSU.2.11.1611171317120.5294@t29.fhfr.qr
State New
Headers show

Commit Message

Richard Biener Nov. 17, 2016, 12:24 p.m. UTC
The following fixes the ICE part of PR78383.  We ICE when trying to
turn a computed goto to a CFG edge when we know the label but that
label is in another function (IPA propagation exposed this knowledge).

The transform shows that we miss a DECL_NONLOCAL on the label because
we happily miscompile the testcase by moving the label freely before
the call to the lambda.  This results in

_ZZ4mainENKUlPvE_clES_.isra.0.constprop.1:
main:
        call    _ZZ4mainENKUlPvE_clES_.isra.0.constprop.1

where you can see the goto has been optimized somehow on RTL as well.
Final GIMPLE is

main()::<lambda(void*)> ()
{
  <bb 2>:
  goto &label;

}

int main() ()
{
label:
  main()::<lambda(void*)>::_ZZ4mainENKUlPvE_clES_.isra.0.constprop ();

}

and initial RTL is already broken:

;; goto &label;

(insn 5 4 6 (set (reg:DI 87)
        (label_ref/v:DI 0)) "t.ii":3 -1
     (nil))

(jump_insn 6 5 7 (set (pc)
        (reg:DI 87)) "t.ii":3 -1
     (nil))

looks like it might be a bad idea to freely allow LABEL_DECL address
propagation but in the end it works fine for DECL_NONLOCAL labels
so I think this is what we miss (the label is not marked DECL_NONLOCAL).

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Will commit w/o the testcase (because that is still miscompiled).

Richard.

2016-11-17  Richard Biener  <rguenther@suse.de>

	PR middle-end/78383
	* tree-cfgcleanup.c (cleanup_control_flow_bb): Do not turn
	non-local goto into CFG.
diff mbox

Patch

diff --git a/gcc/testsuite/g++.dg/torture/pr78383.C b/gcc/testsuite/g++.dg/torture/pr78383.C
new file mode 100644
index 0000000..2b35bc7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr78383.C
@@ -0,0 +1,11 @@ 
+// { dg-do run }
+
+int main()
+{
+  auto f = [](void* ptr) { goto *ptr; };
+
+  f(&&label);
+
+label:
+  return 0;
+}
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index 21873f8..fe22ed3 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -230,6 +230,8 @@  cleanup_control_flow_bb (basic_block bb, bool first_p)
 	 edges which do not go to the right block.  For the one
 	 edge which goes to the right block, fix up its flags.  */
       label = TREE_OPERAND (gimple_goto_dest (stmt), 0);
+      if (DECL_CONTEXT (label) != cfun->decl)
+	return retval;
       target_block = label_to_block (label);
       for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
 	{