aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/omp-low.c2
-rw-r--r--gcc/tree-cfg.c25
-rw-r--r--libgomp/ChangeLog6
-rw-r--r--libgomp/testsuite/libgomp.c/pr81687-1.c23
-rw-r--r--libgomp/testsuite/libgomp.c/pr81687-2.c27
6 files changed, 92 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 251b0f6..1b02925 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2017-08-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/81687
+ * omp-low.c (omp_copy_decl): Don't remap FORCED_LABEL or DECL_NONLOCAL
+ LABEL_DECLs.
+ * tree-cfg.c (move_stmt_op): Don't adjust DECL_CONTEXT of FORCED_LABEL
+ or DECL_NONLOCAL labels.
+ (move_stmt_r) <case GIMPLE_LABEL>: Adjust DECL_CONTEXT of FORCED_LABEL
+ or DECL_NONLOCAL labels here.
+
2017-08-09 Will Schmidt <will_schmidt@vnet.ibm.com>
* config/rs6000/rs6000.c (rs6000_option_override_internal): Add blurb
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 3df6056..dffdb77 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -798,6 +798,8 @@ omp_copy_decl (tree var, copy_body_data *cb)
if (TREE_CODE (var) == LABEL_DECL)
{
+ if (FORCED_LABEL (var) || DECL_NONLOCAL (var))
+ return var;
new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
DECL_CONTEXT (new_var) = current_function_decl;
insert_decl_map (&ctx->cb, var, new_var);
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 733c92f..f26b12f 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -6718,7 +6718,15 @@ move_stmt_op (tree *tp, int *walk_subtrees, void *data)
*tp = t = out->to;
}
- DECL_CONTEXT (t) = p->to_context;
+ /* For FORCED_LABELs we can end up with references from other
+ functions if some SESE regions are outlined. It is UB to
+ jump in between them, but they could be used just for printing
+ addresses etc. In that case, DECL_CONTEXT on the label should
+ be the function containing the glabel stmt with that LABEL_DECL,
+ rather than whatever function a reference to the label was seen
+ last time. */
+ if (!FORCED_LABEL (t) && !DECL_NONLOCAL (t))
+ DECL_CONTEXT (t) = p->to_context;
}
else if (p->remap_decls_p)
{
@@ -6836,6 +6844,21 @@ move_stmt_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
case GIMPLE_OMP_RETURN:
case GIMPLE_OMP_CONTINUE:
break;
+
+ case GIMPLE_LABEL:
+ {
+ /* For FORCED_LABEL, move_stmt_op doesn't adjust DECL_CONTEXT,
+ so that such labels can be referenced from other regions.
+ Make sure to update it when seeing a GIMPLE_LABEL though,
+ that is the owner of the label. */
+ walk_gimple_op (stmt, move_stmt_op, wi);
+ *handled_ops_p = true;
+ tree label = gimple_label_label (as_a <glabel *> (stmt));
+ if (FORCED_LABEL (label) || DECL_NONLOCAL (label))
+ DECL_CONTEXT (label) = p->to_context;
+ }
+ break;
+
default:
if (is_gimple_omp (stmt))
{
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index f17a17b..434cca7 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,9 @@
+2017-08-09 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/81687
+ * testsuite/libgomp.c/pr81687-1.c: New test.
+ * testsuite/libgomp.c/pr81687-2.c: New test.
+
2017-08-07 Jakub Jelinek <jakub@redhat.com>
PR c/69389
diff --git a/libgomp/testsuite/libgomp.c/pr81687-1.c b/libgomp/testsuite/libgomp.c/pr81687-1.c
new file mode 100644
index 0000000..768ec44
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/pr81687-1.c
@@ -0,0 +1,23 @@
+/* PR c/81687 */
+/* { dg-do link } */
+/* { dg-additional-options "-O2" } */
+
+extern int printf (const char *, ...);
+
+int
+main ()
+{
+ #pragma omp parallel
+ {
+ lab1:
+ printf ("lab1=%p\n", (void *)(&&lab1));
+ }
+ lab2:
+ #pragma omp parallel
+ {
+ lab3:
+ printf ("lab2=%p\n", (void *)(&&lab2));
+ }
+ printf ("lab3=%p\n", (void *)(&&lab3));
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/pr81687-2.c b/libgomp/testsuite/libgomp.c/pr81687-2.c
new file mode 100644
index 0000000..e819f76
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/pr81687-2.c
@@ -0,0 +1,27 @@
+/* PR c/81687 */
+/* { dg-do link } */
+/* { dg-additional-options "-O2" } */
+
+int
+main ()
+{
+ __label__ lab4, lab5, lab6;
+ volatile int l = 0;
+ int m = l;
+ void foo (int x) { if (x == 1) goto lab4; }
+ void bar (int x) { if (x == 2) goto lab5; }
+ void baz (int x) { if (x == 3) goto lab6; }
+ #pragma omp parallel
+ {
+ foo (m + 1);
+ lab4:;
+ }
+ #pragma omp task
+ {
+ bar (m + 2);
+ lab5:;
+ }
+ baz (m + 3);
+ lab6:;
+ return 0;
+}