aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2017-09-16 18:38:53 +0000
committerJakub Jelinek <jakub@redhat.com>2017-09-16 18:38:53 +0000
commit120806811f68b9b399a58e02c685f246faef9805 (patch)
tree13435af3716a34c3205676c42d0c154853c1d388
parent5c03bda5ed6d8f76b70bcc13657778733b2bf36b (diff)
Backported from mainline
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. * testsuite/libgomp.c/pr81687-1.c: New test. * testsuite/libgomp.c/pr81687-2.c: New test. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcc-5-branch@252885 138bc75d-0d04-0410-961f-82ee72b054a4
-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 3ecc00f6e5c..60a389b781a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,16 @@
2017-09-16 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
+ 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-08 Richard Biener <rguenther@suse.de>
PR middle-end/81766
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index c1147c63d11..220e9eb73f9 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -1370,6 +1370,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 2a76c41ebf9..ab0c91c4ee6 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -6467,7 +6467,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)
{
@@ -6586,6 +6594,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 8304dda7fbb..9c045ba079f 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,6 +1,12 @@
2017-09-16 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
+ 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-07-27 Jakub Jelinek <jakub@redhat.com>
PR c/45784
diff --git a/libgomp/testsuite/libgomp.c/pr81687-1.c b/libgomp/testsuite/libgomp.c/pr81687-1.c
new file mode 100644
index 00000000000..768ec4484d4
--- /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 00000000000..e819f762032
--- /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;
+}