diff options
author | Jakub Jelinek <jakub@redhat.com> | 2020-03-19 12:22:47 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2020-04-07 20:55:10 +0200 |
commit | 484206967f958fc47827a71654fe52a98adc95cb (patch) | |
tree | d135d759f0a25c4c26d14a219d9632999e8e4f22 | |
parent | phiopt: Avoid -fcompare-debug bug in phiopt [PR94211] (diff) |
c++: Fix up handling of captured vars in lambdas in OpenMP clauses [PR93931]
Without the parser.c change we were ICEing on the testcase, because while the
uses of the captured vars inside of the constructs were replaced with capture
proxy decls, we didn't do that for decls in OpenMP clauses.
With that fixed, we don't ICE anymore, but the testcase is miscompiled and FAILs
at runtime. This is because the capture proxy decls have DECL_VALUE_EXPR and
during gimplification we were gimplifying those to their DECL_VALUE_EXPRs.
That is fine for shared vars, but for privatized ones we must not do that.
So that is what the cp-gimplify.c changes do. Had to add a DECL_CONTEXT check
before calling is_capture_proxy because some VAR_DECLs don't have DECL_CONTEXT
set (yet) and is_capture_proxy relies on that being non-NULL always.
2020-03-19 Jakub Jelinek <jakub@redhat.com>
PR c++/93931
* parser.c (cp_parser_omp_var_list_no_open): Call process_outer_var_ref
on outer_automatic_var_p decls.
* cp-gimplify.c (cxx_omp_disregard_value_expr): Return true also for
capture proxy decls.
* testsuite/libgomp.c++/pr93931.C: New test.
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 17 | ||||
-rw-r--r-- | gcc/cp/parser.c | 2 | ||||
-rw-r--r-- | libgomp/ChangeLog | 8 | ||||
-rw-r--r-- | libgomp/testsuite/libgomp.c++/pr93931.C | 120 |
5 files changed, 149 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8afe6aca339f..d11c4c62ddf3 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog | |||
@@ -1,6 +1,14 @@ | |||
1 | 2020-04-07 Jakub Jelinek <jakub@redhat.com> | 1 | 2020-04-07 Jakub Jelinek <jakub@redhat.com> |
2 | 2 | ||
3 | Backported from mainline | 3 | Backported from mainline |
4 | 2020-03-19 Jakub Jelinek <jakub@redhat.com> | ||
5 | |||
6 | PR c++/93931 | ||
7 | * parser.c (cp_parser_omp_var_list_no_open): Call process_outer_var_ref | ||
8 | on outer_automatic_var_p decls. | ||
9 | * cp-gimplify.c (cxx_omp_disregard_value_expr): Return true also for | ||
10 | capture proxy decls. | ||
11 | |||
4 | 2020-03-17 Jakub Jelinek <jakub@redhat.com> | 12 | 2020-03-17 Jakub Jelinek <jakub@redhat.com> |
5 | 13 | ||
6 | PR c++/90995 | 14 | PR c++/90995 |
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index 4be45abca88e..0e15b1c81475 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c | |||
@@ -2192,12 +2192,17 @@ cxx_omp_finish_clause (tree c, gimple_seq *) | |||
2192 | bool | 2192 | bool |
2193 | cxx_omp_disregard_value_expr (tree decl, bool shared) | 2193 | cxx_omp_disregard_value_expr (tree decl, bool shared) |
2194 | { | 2194 | { |
2195 | return !shared | 2195 | if (shared) |
2196 | && VAR_P (decl) | 2196 | return false; |
2197 | && DECL_HAS_VALUE_EXPR_P (decl) | 2197 | if (VAR_P (decl) |
2198 | && DECL_ARTIFICIAL (decl) | 2198 | && DECL_HAS_VALUE_EXPR_P (decl) |
2199 | && DECL_LANG_SPECIFIC (decl) | 2199 | && DECL_ARTIFICIAL (decl) |
2200 | && DECL_OMP_PRIVATIZED_MEMBER (decl); | 2200 | && DECL_LANG_SPECIFIC (decl) |
2201 | && DECL_OMP_PRIVATIZED_MEMBER (decl)) | ||
2202 | return true; | ||
2203 | if (VAR_P (decl) && DECL_CONTEXT (decl) && is_capture_proxy (decl)) | ||
2204 | return true; | ||
2205 | return false; | ||
2201 | } | 2206 | } |
2202 | 2207 | ||
2203 | /* Fold expression X which is used as an rvalue if RVAL is true. */ | 2208 | /* Fold expression X which is used as an rvalue if RVAL is true. */ |
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 0219920be8f5..00e950d2e937 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c | |||
@@ -32563,6 +32563,8 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind, | |||
32563 | token->location); | 32563 | token->location); |
32564 | } | 32564 | } |
32565 | } | 32565 | } |
32566 | if (outer_automatic_var_p (decl)) | ||
32567 | decl = process_outer_var_ref (decl, tf_warning_or_error); | ||
32566 | if (decl == error_mark_node) | 32568 | if (decl == error_mark_node) |
32567 | ; | 32569 | ; |
32568 | else if (kind != 0) | 32570 | else if (kind != 0) |
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index f4aa8c63481b..ee18a9945909 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog | |||
@@ -1,3 +1,11 @@ | |||
1 | 2020-04-07 Jakub Jelinek <jakub@redhat.com> | ||
2 | |||
3 | Backported from mainline | ||
4 | 2020-03-19 Jakub Jelinek <jakub@redhat.com> | ||
5 | |||
6 | PR c++/93931 | ||
7 | * testsuite/libgomp.c++/pr93931.C: New test. | ||
8 | |||
1 | 2020-03-17 Jakub Jelinek <jakub@redhat.com> | 9 | 2020-03-17 Jakub Jelinek <jakub@redhat.com> |
2 | 10 | ||
3 | Backported from mainline | 11 | Backported from mainline |
diff --git a/libgomp/testsuite/libgomp.c++/pr93931.C b/libgomp/testsuite/libgomp.c++/pr93931.C new file mode 100644 index 000000000000..4d4232ef3405 --- /dev/null +++ b/libgomp/testsuite/libgomp.c++/pr93931.C | |||
@@ -0,0 +1,120 @@ | |||
1 | // PR c++/93931 | ||
2 | // { dg-do run } | ||
3 | // { dg-options "-O2 -std=c++14" } | ||
4 | |||
5 | extern "C" void abort (); | ||
6 | |||
7 | void | ||
8 | sink (int &x) | ||
9 | { | ||
10 | int *volatile p; | ||
11 | p = &x; | ||
12 | (*p)++; | ||
13 | } | ||
14 | |||
15 | int | ||
16 | foo () | ||
17 | { | ||
18 | int r = 0; | ||
19 | [&r] () { | ||
20 | #pragma omp parallel for reduction(+ : r) | ||
21 | for (int i = 0; i < 1024; ++i) | ||
22 | r += i; | ||
23 | } (); | ||
24 | return r; | ||
25 | } | ||
26 | |||
27 | int | ||
28 | bar () | ||
29 | { | ||
30 | int l = 0; | ||
31 | [&l] () { | ||
32 | #pragma omp parallel for lastprivate (l) | ||
33 | for (int i = 0; i < 1024; ++i) | ||
34 | l = i; | ||
35 | } (); | ||
36 | return l; | ||
37 | } | ||
38 | |||
39 | void | ||
40 | baz () | ||
41 | { | ||
42 | int f = 18; | ||
43 | [&f] () { | ||
44 | #pragma omp parallel for firstprivate (f) | ||
45 | for (int i = 0; i < 1024; ++i) | ||
46 | { | ||
47 | sink (f); | ||
48 | f += 3; | ||
49 | sink (f); | ||
50 | if (f != 23) | ||
51 | abort (); | ||
52 | sink (f); | ||
53 | f -= 7; | ||
54 | sink (f); | ||
55 | } | ||
56 | } (); | ||
57 | if (f != 18) | ||
58 | abort (); | ||
59 | } | ||
60 | |||
61 | int | ||
62 | qux () | ||
63 | { | ||
64 | int r = 0; | ||
65 | [&] () { | ||
66 | #pragma omp parallel for reduction(+ : r) | ||
67 | for (int i = 0; i < 1024; ++i) | ||
68 | r += i; | ||
69 | } (); | ||
70 | return r; | ||
71 | } | ||
72 | |||
73 | int | ||
74 | corge () | ||
75 | { | ||
76 | int l = 0; | ||
77 | [&] () { | ||
78 | #pragma omp parallel for lastprivate (l) | ||
79 | for (int i = 0; i < 1024; ++i) | ||
80 | l = i; | ||
81 | } (); | ||
82 | return l; | ||
83 | } | ||
84 | |||
85 | void | ||
86 | garply () | ||
87 | { | ||
88 | int f = 18; | ||
89 | [&] () { | ||
90 | #pragma omp parallel for firstprivate (f) | ||
91 | for (int i = 0; i < 1024; ++i) | ||
92 | { | ||
93 | sink (f); | ||
94 | f += 3; | ||
95 | sink (f); | ||
96 | if (f != 23) | ||
97 | abort (); | ||
98 | sink (f); | ||
99 | f -= 7; | ||
100 | sink (f); | ||
101 | } | ||
102 | } (); | ||
103 | if (f != 18) | ||
104 | abort (); | ||
105 | } | ||
106 | |||
107 | int | ||
108 | main () | ||
109 | { | ||
110 | if (foo () != 1024 * 1023 / 2) | ||
111 | abort (); | ||
112 | if (bar () != 1023) | ||
113 | abort (); | ||
114 | baz (); | ||
115 | if (qux () != 1024 * 1023 / 2) | ||
116 | abort (); | ||
117 | if (corge () != 1023) | ||
118 | abort (); | ||
119 | garply (); | ||
120 | } | ||