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  <rguent...@suse.de>

        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; 
+ }

Reply via email to