The following avoids creating IL that accesses a FUNCTION_DECLs memory
directly rather than indirectly through an address based on it.
Bootstrap and regtest running on x86_64-unknown-linux-gnu, ok for trunk?
Thanks,
Richard.
2016-06-13 Richard Biener
PR c/71514
c-family/
* c-common.c (resolve_overloaded_atomic_exchange): Convert
the pointer and dereference instead of dereferencing and
view-converting.
(resolve_overloaded_atomic_compare_exchange): Likewise.
(resolve_overloaded_atomic_store): Likewise.
* gcc.dg/torture/pr71514.c: New testcase.
Index: gcc/c-family/c-common.c
===
*** gcc/c-family/c-common.c (revision 237372)
--- gcc/c-family/c-common.c (working copy)
*** resolve_overloaded_atomic_exchange (loca
*** 11129,11136
p0 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p0);
(*params)[0] = p0;
/* Convert new value to required type, and dereference it. */
p1 = build_indirect_ref (loc, p1, RO_UNARY_STAR);
- p1 = build1 (VIEW_CONVERT_EXPR, I_type, p1);
(*params)[1] = p1;
/* Move memory model to the 3rd position, and end param list. */
--- 11129,11136
p0 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p0);
(*params)[0] = p0;
/* Convert new value to required type, and dereference it. */
+ p1 = fold_convert_loc (loc, I_type_ptr, p1);
p1 = build_indirect_ref (loc, p1, RO_UNARY_STAR);
(*params)[1] = p1;
/* Move memory model to the 3rd position, and end param list. */
*** resolve_overloaded_atomic_compare_exchan
*** 11209,11216
(*params)[1] = p1;
/* Convert desired value to required type, and dereference it. */
p2 = build_indirect_ref (loc, p2, RO_UNARY_STAR);
- p2 = build1 (VIEW_CONVERT_EXPR, I_type, p2);
(*params)[2] = p2;
/* The rest of the parameters are fine. NULL means no special return value
--- 11209,11216
(*params)[1] = p1;
/* Convert desired value to required type, and dereference it. */
+ p2 = fold_convert_loc (loc, I_type_ptr, p2);
p2 = build_indirect_ref (loc, p2, RO_UNARY_STAR);
(*params)[2] = p2;
/* The rest of the parameters are fine. NULL means no special return value
*** resolve_overloaded_atomic_store (locatio
*** 11329,11336
(*params)[0] = p0;
/* Convert new value to required type, and dereference it. */
p1 = build_indirect_ref (loc, p1, RO_UNARY_STAR);
- p1 = build1 (VIEW_CONVERT_EXPR, I_type, p1);
(*params)[1] = p1;
/* The memory model is in the right spot already. Return is void. */
--- 11329,11336
(*params)[0] = p0;
/* Convert new value to required type, and dereference it. */
+ p1 = fold_convert_loc (loc, I_type_ptr, p1);
p1 = build_indirect_ref (loc, p1, RO_UNARY_STAR);
(*params)[1] = p1;
/* The memory model is in the right spot already. Return is void. */
Index: gcc/testsuite/gcc.dg/torture/pr71514.c
===
*** gcc/testsuite/gcc.dg/torture/pr71514.c (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr71514.c (working copy)
***
*** 0
--- 1,11
+ /* { dg-do compile } */
+
+ void foo () {}
+
+ char a, b;
+
+ int main ()
+ {
+ __atomic_exchange (&a, &foo, &b, __ATOMIC_RELAXED);
+ return 0;
+ }