This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[gomp4.5] Fix checking ICE with atomic in a template
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 29 Oct 2015 18:56:46 +0100
- Subject: [gomp4.5] Fix checking ICE with atomic in a template
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
This patch fixes an ICE, where c_finish_omp_atomic is called on
a template for diagnostics purposes because the expressions aren't type
dependent, but still calling save_expr on C++ trees is harmful
(e.g. SCOPE_REF contains a type as one of the arguments, rather than
expression).
2015-10-29 Jakub Jelinek <jakub@redhat.com>
gcc/c-family/
* c-common.h (c_finish_omp_atomic): Add TEST argument.
* c-omp.c (c_finish_omp_atomic): Likewise. Don't call
save_expr or create_tmp_var* if TEST is true.
gcc/cp/
* semantics.c (finish_omp_atomic): Adjust c_finish_omp_atomic
caller.
gcc/testsuite/
* g++.dg/gomp/atomic-17.C: New test.
--- gcc/c-family/c-common.h.jj 2015-10-19 15:04:58.000000000 +0200
+++ gcc/c-family/c-common.h 2015-10-29 16:31:52.132631191 +0100
@@ -1262,7 +1262,8 @@ extern tree c_finish_omp_critical (locat
extern tree c_finish_omp_ordered (location_t, tree, tree);
extern void c_finish_omp_barrier (location_t);
extern tree c_finish_omp_atomic (location_t, enum tree_code, enum tree_code,
- tree, tree, tree, tree, tree, bool, bool);
+ tree, tree, tree, tree, tree, bool, bool,
+ bool = false);
extern void c_finish_omp_flush (location_t);
extern void c_finish_omp_taskwait (location_t);
extern void c_finish_omp_taskyield (location_t);
--- gcc/c-family/c-omp.c.jj 2015-10-27 12:27:26.000000000 +0100
+++ gcc/c-family/c-omp.c 2015-10-29 16:31:28.736966176 +0100
@@ -175,12 +175,14 @@ c_finish_omp_taskyield (location_t loc)
LOC is the location of the atomic statement. The value returned
is either error_mark_node (if the construct was erroneous) or an
OMP_ATOMIC* node which should be added to the current statement
- tree with add_stmt. */
+ tree with add_stmt. If TEST is set, avoid calling save_expr
+ or create_tmp_var*. */
tree
c_finish_omp_atomic (location_t loc, enum tree_code code,
enum tree_code opcode, tree lhs, tree rhs,
- tree v, tree lhs1, tree rhs1, bool swapped, bool seq_cst)
+ tree v, tree lhs1, tree rhs1, bool swapped, bool seq_cst,
+ bool test)
{
tree x, type, addr, pre = NULL_TREE;
@@ -212,8 +214,10 @@ c_finish_omp_atomic (location_t loc, enu
addr = build_unary_op (loc, ADDR_EXPR, lhs, 0);
if (addr == error_mark_node)
return error_mark_node;
- addr = save_expr (addr);
- if (TREE_CODE (addr) != SAVE_EXPR
+ if (!test)
+ addr = save_expr (addr);
+ if (!test
+ && TREE_CODE (addr) != SAVE_EXPR
&& (TREE_CODE (addr) != ADDR_EXPR
|| !VAR_P (TREE_OPERAND (addr, 0))))
{
@@ -269,12 +273,15 @@ c_finish_omp_atomic (location_t loc, enu
if (rhs1
&& VAR_P (rhs1)
&& VAR_P (lhs)
- && rhs1 != lhs)
+ && rhs1 != lhs
+ && !test)
{
if (code == OMP_ATOMIC)
- error_at (loc, "%<#pragma omp atomic update%> uses two different variables for memory");
+ error_at (loc, "%<#pragma omp atomic update%> uses two different "
+ "variables for memory");
else
- error_at (loc, "%<#pragma omp atomic capture%> uses two different variables for memory");
+ error_at (loc, "%<#pragma omp atomic capture%> uses two different "
+ "variables for memory");
return error_mark_node;
}
@@ -284,9 +291,10 @@ c_finish_omp_atomic (location_t loc, enu
location, just diagnose different variables. */
if (lhs1 && VAR_P (lhs1) && VAR_P (lhs))
{
- if (lhs1 != lhs)
+ if (lhs1 != lhs && !test)
{
- error_at (loc, "%<#pragma omp atomic capture%> uses two different variables for memory");
+ error_at (loc, "%<#pragma omp atomic capture%> uses two "
+ "different variables for memory");
return error_mark_node;
}
}
@@ -308,7 +316,8 @@ c_finish_omp_atomic (location_t loc, enu
x = omit_one_operand_loc (loc, type, x, lhs1addr);
else
{
- x = save_expr (x);
+ if (!test)
+ x = save_expr (x);
x = omit_two_operands_loc (loc, type, x, x, lhs1addr);
}
}
--- gcc/cp/semantics.c.jj 2015-10-29 14:07:44.000000000 +0100
+++ gcc/cp/semantics.c 2015-10-29 16:32:42.415911221 +0100
@@ -8159,7 +8159,8 @@ finish_omp_atomic (enum tree_code code,
return;
}
stmt = c_finish_omp_atomic (input_location, code, opcode, lhs, rhs,
- v, lhs1, rhs1, swapped, seq_cst);
+ v, lhs1, rhs1, swapped, seq_cst,
+ processing_template_decl != 0);
if (stmt == error_mark_node)
return;
}
--- gcc/testsuite/g++.dg/gomp/atomic-17.C.jj 2015-10-29 16:35:23.014611725 +0100
+++ gcc/testsuite/g++.dg/gomp/atomic-17.C 2015-10-29 16:11:36.000000000 +0100
@@ -0,0 +1,12 @@
+template <typename T>
+struct A { int foo (); int c; };
+
+template <typename T>
+int
+A<T>::foo ()
+{
+ int j;
+ #pragma omp atomic read
+ j = A::c;
+ return j;
+}
Jakub