diff mbox

Fix -fsanitize=address atomic builtin handling (PR sanitizer/79944)

Message ID 20170308172844.GC22703@tucnak
State New
Headers show

Commit Message

Jakub Jelinek March 8, 2017, 5:28 p.m. UTC
Hi!

As reported, we were using often completely bogus access sizes for
atomic builtins, where the access size should be determined purely by their
_{1,2,4,8,16} suffix, not by whatever type the passed pointer points to,
pointer conversions are useless.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-03-08  Jakub Jelinek  <jakub@redhat.com>

	PR sanitizer/79944
	* asan.c (get_mem_refs_of_builtin_call): For BUILT_IN_ATOMIC* and
	BUILT_IN_SYNC*, determine the access type from the size suffix and
	always build a MEM_REF with that type.  Handle forgotten
	BUILT_IN_SYNC_FETCH_AND_NAND_16 and BUILT_IN_SYNC_NAND_AND_FETCH_16.

	* c-c++-common/asan/pr79944.c: New test.


	Jakub

Comments

Richard Biener March 9, 2017, 7:59 a.m. UTC | #1
On Wed, 8 Mar 2017, Jakub Jelinek wrote:

> Hi!
> 
> As reported, we were using often completely bogus access sizes for
> atomic builtins, where the access size should be determined purely by their
> _{1,2,4,8,16} suffix, not by whatever type the passed pointer points to,
> pointer conversions are useless.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Richard.

> 2017-03-08  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR sanitizer/79944
> 	* asan.c (get_mem_refs_of_builtin_call): For BUILT_IN_ATOMIC* and
> 	BUILT_IN_SYNC*, determine the access type from the size suffix and
> 	always build a MEM_REF with that type.  Handle forgotten
> 	BUILT_IN_SYNC_FETCH_AND_NAND_16 and BUILT_IN_SYNC_NAND_AND_FETCH_16.
> 
> 	* c-c++-common/asan/pr79944.c: New test.
> 
> --- gcc/asan.c.jj	2017-03-06 12:32:28.000000000 +0100
> +++ gcc/asan.c	2017-03-08 12:24:11.151353229 +0100
> @@ -603,218 +603,208 @@ get_mem_refs_of_builtin_call (const gcal
>      case BUILT_IN_STRLEN:
>        source0 = gimple_call_arg (call, 0);
>        len = gimple_call_lhs (call);
> -      break ;
> +      break;
>  
>      /* And now the __atomic* and __sync builtins.
>         These are handled differently from the classical memory memory
>         access builtins above.  */
>  
>      case BUILT_IN_ATOMIC_LOAD_1:
> -    case BUILT_IN_ATOMIC_LOAD_2:
> -    case BUILT_IN_ATOMIC_LOAD_4:
> -    case BUILT_IN_ATOMIC_LOAD_8:
> -    case BUILT_IN_ATOMIC_LOAD_16:
>        is_store = false;
> -      /* fall through.  */
> -
> +      /* FALLTHRU */
>      case BUILT_IN_SYNC_FETCH_AND_ADD_1:
> -    case BUILT_IN_SYNC_FETCH_AND_ADD_2:
> -    case BUILT_IN_SYNC_FETCH_AND_ADD_4:
> -    case BUILT_IN_SYNC_FETCH_AND_ADD_8:
> -    case BUILT_IN_SYNC_FETCH_AND_ADD_16:
> -
>      case BUILT_IN_SYNC_FETCH_AND_SUB_1:
> -    case BUILT_IN_SYNC_FETCH_AND_SUB_2:
> -    case BUILT_IN_SYNC_FETCH_AND_SUB_4:
> -    case BUILT_IN_SYNC_FETCH_AND_SUB_8:
> -    case BUILT_IN_SYNC_FETCH_AND_SUB_16:
> -
>      case BUILT_IN_SYNC_FETCH_AND_OR_1:
> -    case BUILT_IN_SYNC_FETCH_AND_OR_2:
> -    case BUILT_IN_SYNC_FETCH_AND_OR_4:
> -    case BUILT_IN_SYNC_FETCH_AND_OR_8:
> -    case BUILT_IN_SYNC_FETCH_AND_OR_16:
> -
>      case BUILT_IN_SYNC_FETCH_AND_AND_1:
> -    case BUILT_IN_SYNC_FETCH_AND_AND_2:
> -    case BUILT_IN_SYNC_FETCH_AND_AND_4:
> -    case BUILT_IN_SYNC_FETCH_AND_AND_8:
> -    case BUILT_IN_SYNC_FETCH_AND_AND_16:
> -
>      case BUILT_IN_SYNC_FETCH_AND_XOR_1:
> -    case BUILT_IN_SYNC_FETCH_AND_XOR_2:
> -    case BUILT_IN_SYNC_FETCH_AND_XOR_4:
> -    case BUILT_IN_SYNC_FETCH_AND_XOR_8:
> -    case BUILT_IN_SYNC_FETCH_AND_XOR_16:
> -
>      case BUILT_IN_SYNC_FETCH_AND_NAND_1:
> -    case BUILT_IN_SYNC_FETCH_AND_NAND_2:
> -    case BUILT_IN_SYNC_FETCH_AND_NAND_4:
> -    case BUILT_IN_SYNC_FETCH_AND_NAND_8:
> -
>      case BUILT_IN_SYNC_ADD_AND_FETCH_1:
> -    case BUILT_IN_SYNC_ADD_AND_FETCH_2:
> -    case BUILT_IN_SYNC_ADD_AND_FETCH_4:
> -    case BUILT_IN_SYNC_ADD_AND_FETCH_8:
> -    case BUILT_IN_SYNC_ADD_AND_FETCH_16:
> -
>      case BUILT_IN_SYNC_SUB_AND_FETCH_1:
> -    case BUILT_IN_SYNC_SUB_AND_FETCH_2:
> -    case BUILT_IN_SYNC_SUB_AND_FETCH_4:
> -    case BUILT_IN_SYNC_SUB_AND_FETCH_8:
> -    case BUILT_IN_SYNC_SUB_AND_FETCH_16:
> -
>      case BUILT_IN_SYNC_OR_AND_FETCH_1:
> -    case BUILT_IN_SYNC_OR_AND_FETCH_2:
> -    case BUILT_IN_SYNC_OR_AND_FETCH_4:
> -    case BUILT_IN_SYNC_OR_AND_FETCH_8:
> -    case BUILT_IN_SYNC_OR_AND_FETCH_16:
> -
>      case BUILT_IN_SYNC_AND_AND_FETCH_1:
> -    case BUILT_IN_SYNC_AND_AND_FETCH_2:
> -    case BUILT_IN_SYNC_AND_AND_FETCH_4:
> -    case BUILT_IN_SYNC_AND_AND_FETCH_8:
> -    case BUILT_IN_SYNC_AND_AND_FETCH_16:
> -
>      case BUILT_IN_SYNC_XOR_AND_FETCH_1:
> -    case BUILT_IN_SYNC_XOR_AND_FETCH_2:
> -    case BUILT_IN_SYNC_XOR_AND_FETCH_4:
> -    case BUILT_IN_SYNC_XOR_AND_FETCH_8:
> -    case BUILT_IN_SYNC_XOR_AND_FETCH_16:
> -
>      case BUILT_IN_SYNC_NAND_AND_FETCH_1:
> -    case BUILT_IN_SYNC_NAND_AND_FETCH_2:
> -    case BUILT_IN_SYNC_NAND_AND_FETCH_4:
> -    case BUILT_IN_SYNC_NAND_AND_FETCH_8:
> -
>      case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1:
> -    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_2:
> -    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4:
> -    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8:
> -    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_16:
> -
>      case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1:
> -    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_2:
> -    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4:
> -    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8:
> -    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_16:
> -
>      case BUILT_IN_SYNC_LOCK_TEST_AND_SET_1:
> -    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_2:
> -    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_4:
> -    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_8:
> -    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_16:
> -
>      case BUILT_IN_SYNC_LOCK_RELEASE_1:
> -    case BUILT_IN_SYNC_LOCK_RELEASE_2:
> -    case BUILT_IN_SYNC_LOCK_RELEASE_4:
> -    case BUILT_IN_SYNC_LOCK_RELEASE_8:
> -    case BUILT_IN_SYNC_LOCK_RELEASE_16:
> -
>      case BUILT_IN_ATOMIC_EXCHANGE_1:
> -    case BUILT_IN_ATOMIC_EXCHANGE_2:
> -    case BUILT_IN_ATOMIC_EXCHANGE_4:
> -    case BUILT_IN_ATOMIC_EXCHANGE_8:
> -    case BUILT_IN_ATOMIC_EXCHANGE_16:
> -
>      case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
> -    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
> -    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
> -    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
> -    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
> -
>      case BUILT_IN_ATOMIC_STORE_1:
> -    case BUILT_IN_ATOMIC_STORE_2:
> -    case BUILT_IN_ATOMIC_STORE_4:
> -    case BUILT_IN_ATOMIC_STORE_8:
> -    case BUILT_IN_ATOMIC_STORE_16:
> -
>      case BUILT_IN_ATOMIC_ADD_FETCH_1:
> -    case BUILT_IN_ATOMIC_ADD_FETCH_2:
> -    case BUILT_IN_ATOMIC_ADD_FETCH_4:
> -    case BUILT_IN_ATOMIC_ADD_FETCH_8:
> -    case BUILT_IN_ATOMIC_ADD_FETCH_16:
> -
>      case BUILT_IN_ATOMIC_SUB_FETCH_1:
> -    case BUILT_IN_ATOMIC_SUB_FETCH_2:
> -    case BUILT_IN_ATOMIC_SUB_FETCH_4:
> -    case BUILT_IN_ATOMIC_SUB_FETCH_8:
> -    case BUILT_IN_ATOMIC_SUB_FETCH_16:
> -
>      case BUILT_IN_ATOMIC_AND_FETCH_1:
> -    case BUILT_IN_ATOMIC_AND_FETCH_2:
> -    case BUILT_IN_ATOMIC_AND_FETCH_4:
> -    case BUILT_IN_ATOMIC_AND_FETCH_8:
> -    case BUILT_IN_ATOMIC_AND_FETCH_16:
> -
>      case BUILT_IN_ATOMIC_NAND_FETCH_1:
> -    case BUILT_IN_ATOMIC_NAND_FETCH_2:
> -    case BUILT_IN_ATOMIC_NAND_FETCH_4:
> -    case BUILT_IN_ATOMIC_NAND_FETCH_8:
> -    case BUILT_IN_ATOMIC_NAND_FETCH_16:
> -
>      case BUILT_IN_ATOMIC_XOR_FETCH_1:
> -    case BUILT_IN_ATOMIC_XOR_FETCH_2:
> -    case BUILT_IN_ATOMIC_XOR_FETCH_4:
> -    case BUILT_IN_ATOMIC_XOR_FETCH_8:
> -    case BUILT_IN_ATOMIC_XOR_FETCH_16:
> -
>      case BUILT_IN_ATOMIC_OR_FETCH_1:
> -    case BUILT_IN_ATOMIC_OR_FETCH_2:
> -    case BUILT_IN_ATOMIC_OR_FETCH_4:
> -    case BUILT_IN_ATOMIC_OR_FETCH_8:
> -    case BUILT_IN_ATOMIC_OR_FETCH_16:
> -
>      case BUILT_IN_ATOMIC_FETCH_ADD_1:
> -    case BUILT_IN_ATOMIC_FETCH_ADD_2:
> -    case BUILT_IN_ATOMIC_FETCH_ADD_4:
> -    case BUILT_IN_ATOMIC_FETCH_ADD_8:
> -    case BUILT_IN_ATOMIC_FETCH_ADD_16:
> -
>      case BUILT_IN_ATOMIC_FETCH_SUB_1:
> -    case BUILT_IN_ATOMIC_FETCH_SUB_2:
> -    case BUILT_IN_ATOMIC_FETCH_SUB_4:
> -    case BUILT_IN_ATOMIC_FETCH_SUB_8:
> -    case BUILT_IN_ATOMIC_FETCH_SUB_16:
> -
>      case BUILT_IN_ATOMIC_FETCH_AND_1:
> -    case BUILT_IN_ATOMIC_FETCH_AND_2:
> -    case BUILT_IN_ATOMIC_FETCH_AND_4:
> -    case BUILT_IN_ATOMIC_FETCH_AND_8:
> -    case BUILT_IN_ATOMIC_FETCH_AND_16:
> -
>      case BUILT_IN_ATOMIC_FETCH_NAND_1:
> -    case BUILT_IN_ATOMIC_FETCH_NAND_2:
> -    case BUILT_IN_ATOMIC_FETCH_NAND_4:
> -    case BUILT_IN_ATOMIC_FETCH_NAND_8:
> -    case BUILT_IN_ATOMIC_FETCH_NAND_16:
> -
>      case BUILT_IN_ATOMIC_FETCH_XOR_1:
> -    case BUILT_IN_ATOMIC_FETCH_XOR_2:
> -    case BUILT_IN_ATOMIC_FETCH_XOR_4:
> -    case BUILT_IN_ATOMIC_FETCH_XOR_8:
> -    case BUILT_IN_ATOMIC_FETCH_XOR_16:
> -
>      case BUILT_IN_ATOMIC_FETCH_OR_1:
> +      access_size = 1;
> +      goto do_atomic;
> +
> +    case BUILT_IN_ATOMIC_LOAD_2:
> +      is_store = false;
> +      /* FALLTHRU */
> +    case BUILT_IN_SYNC_FETCH_AND_ADD_2:
> +    case BUILT_IN_SYNC_FETCH_AND_SUB_2:
> +    case BUILT_IN_SYNC_FETCH_AND_OR_2:
> +    case BUILT_IN_SYNC_FETCH_AND_AND_2:
> +    case BUILT_IN_SYNC_FETCH_AND_XOR_2:
> +    case BUILT_IN_SYNC_FETCH_AND_NAND_2:
> +    case BUILT_IN_SYNC_ADD_AND_FETCH_2:
> +    case BUILT_IN_SYNC_SUB_AND_FETCH_2:
> +    case BUILT_IN_SYNC_OR_AND_FETCH_2:
> +    case BUILT_IN_SYNC_AND_AND_FETCH_2:
> +    case BUILT_IN_SYNC_XOR_AND_FETCH_2:
> +    case BUILT_IN_SYNC_NAND_AND_FETCH_2:
> +    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_2:
> +    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_2:
> +    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_2:
> +    case BUILT_IN_SYNC_LOCK_RELEASE_2:
> +    case BUILT_IN_ATOMIC_EXCHANGE_2:
> +    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
> +    case BUILT_IN_ATOMIC_STORE_2:
> +    case BUILT_IN_ATOMIC_ADD_FETCH_2:
> +    case BUILT_IN_ATOMIC_SUB_FETCH_2:
> +    case BUILT_IN_ATOMIC_AND_FETCH_2:
> +    case BUILT_IN_ATOMIC_NAND_FETCH_2:
> +    case BUILT_IN_ATOMIC_XOR_FETCH_2:
> +    case BUILT_IN_ATOMIC_OR_FETCH_2:
> +    case BUILT_IN_ATOMIC_FETCH_ADD_2:
> +    case BUILT_IN_ATOMIC_FETCH_SUB_2:
> +    case BUILT_IN_ATOMIC_FETCH_AND_2:
> +    case BUILT_IN_ATOMIC_FETCH_NAND_2:
> +    case BUILT_IN_ATOMIC_FETCH_XOR_2:
>      case BUILT_IN_ATOMIC_FETCH_OR_2:
> +      access_size = 2;
> +      goto do_atomic;
> +
> +    case BUILT_IN_ATOMIC_LOAD_4:
> +      is_store = false;
> +      /* FALLTHRU */
> +    case BUILT_IN_SYNC_FETCH_AND_ADD_4:
> +    case BUILT_IN_SYNC_FETCH_AND_SUB_4:
> +    case BUILT_IN_SYNC_FETCH_AND_OR_4:
> +    case BUILT_IN_SYNC_FETCH_AND_AND_4:
> +    case BUILT_IN_SYNC_FETCH_AND_XOR_4:
> +    case BUILT_IN_SYNC_FETCH_AND_NAND_4:
> +    case BUILT_IN_SYNC_ADD_AND_FETCH_4:
> +    case BUILT_IN_SYNC_SUB_AND_FETCH_4:
> +    case BUILT_IN_SYNC_OR_AND_FETCH_4:
> +    case BUILT_IN_SYNC_AND_AND_FETCH_4:
> +    case BUILT_IN_SYNC_XOR_AND_FETCH_4:
> +    case BUILT_IN_SYNC_NAND_AND_FETCH_4:
> +    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4:
> +    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4:
> +    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_4:
> +    case BUILT_IN_SYNC_LOCK_RELEASE_4:
> +    case BUILT_IN_ATOMIC_EXCHANGE_4:
> +    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
> +    case BUILT_IN_ATOMIC_STORE_4:
> +    case BUILT_IN_ATOMIC_ADD_FETCH_4:
> +    case BUILT_IN_ATOMIC_SUB_FETCH_4:
> +    case BUILT_IN_ATOMIC_AND_FETCH_4:
> +    case BUILT_IN_ATOMIC_NAND_FETCH_4:
> +    case BUILT_IN_ATOMIC_XOR_FETCH_4:
> +    case BUILT_IN_ATOMIC_OR_FETCH_4:
> +    case BUILT_IN_ATOMIC_FETCH_ADD_4:
> +    case BUILT_IN_ATOMIC_FETCH_SUB_4:
> +    case BUILT_IN_ATOMIC_FETCH_AND_4:
> +    case BUILT_IN_ATOMIC_FETCH_NAND_4:
> +    case BUILT_IN_ATOMIC_FETCH_XOR_4:
>      case BUILT_IN_ATOMIC_FETCH_OR_4:
> +      access_size = 4;
> +      goto do_atomic;
> +
> +    case BUILT_IN_ATOMIC_LOAD_8:
> +      is_store = false;
> +      /* FALLTHRU */
> +    case BUILT_IN_SYNC_FETCH_AND_ADD_8:
> +    case BUILT_IN_SYNC_FETCH_AND_SUB_8:
> +    case BUILT_IN_SYNC_FETCH_AND_OR_8:
> +    case BUILT_IN_SYNC_FETCH_AND_AND_8:
> +    case BUILT_IN_SYNC_FETCH_AND_XOR_8:
> +    case BUILT_IN_SYNC_FETCH_AND_NAND_8:
> +    case BUILT_IN_SYNC_ADD_AND_FETCH_8:
> +    case BUILT_IN_SYNC_SUB_AND_FETCH_8:
> +    case BUILT_IN_SYNC_OR_AND_FETCH_8:
> +    case BUILT_IN_SYNC_AND_AND_FETCH_8:
> +    case BUILT_IN_SYNC_XOR_AND_FETCH_8:
> +    case BUILT_IN_SYNC_NAND_AND_FETCH_8:
> +    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8:
> +    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8:
> +    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_8:
> +    case BUILT_IN_SYNC_LOCK_RELEASE_8:
> +    case BUILT_IN_ATOMIC_EXCHANGE_8:
> +    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
> +    case BUILT_IN_ATOMIC_STORE_8:
> +    case BUILT_IN_ATOMIC_ADD_FETCH_8:
> +    case BUILT_IN_ATOMIC_SUB_FETCH_8:
> +    case BUILT_IN_ATOMIC_AND_FETCH_8:
> +    case BUILT_IN_ATOMIC_NAND_FETCH_8:
> +    case BUILT_IN_ATOMIC_XOR_FETCH_8:
> +    case BUILT_IN_ATOMIC_OR_FETCH_8:
> +    case BUILT_IN_ATOMIC_FETCH_ADD_8:
> +    case BUILT_IN_ATOMIC_FETCH_SUB_8:
> +    case BUILT_IN_ATOMIC_FETCH_AND_8:
> +    case BUILT_IN_ATOMIC_FETCH_NAND_8:
> +    case BUILT_IN_ATOMIC_FETCH_XOR_8:
>      case BUILT_IN_ATOMIC_FETCH_OR_8:
> +      access_size = 8;
> +      goto do_atomic;
> +
> +    case BUILT_IN_ATOMIC_LOAD_16:
> +      is_store = false;
> +      /* FALLTHRU */
> +    case BUILT_IN_SYNC_FETCH_AND_ADD_16:
> +    case BUILT_IN_SYNC_FETCH_AND_SUB_16:
> +    case BUILT_IN_SYNC_FETCH_AND_OR_16:
> +    case BUILT_IN_SYNC_FETCH_AND_AND_16:
> +    case BUILT_IN_SYNC_FETCH_AND_XOR_16:
> +    case BUILT_IN_SYNC_FETCH_AND_NAND_16:
> +    case BUILT_IN_SYNC_ADD_AND_FETCH_16:
> +    case BUILT_IN_SYNC_SUB_AND_FETCH_16:
> +    case BUILT_IN_SYNC_OR_AND_FETCH_16:
> +    case BUILT_IN_SYNC_AND_AND_FETCH_16:
> +    case BUILT_IN_SYNC_XOR_AND_FETCH_16:
> +    case BUILT_IN_SYNC_NAND_AND_FETCH_16:
> +    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_16:
> +    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_16:
> +    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_16:
> +    case BUILT_IN_SYNC_LOCK_RELEASE_16:
> +    case BUILT_IN_ATOMIC_EXCHANGE_16:
> +    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
> +    case BUILT_IN_ATOMIC_STORE_16:
> +    case BUILT_IN_ATOMIC_ADD_FETCH_16:
> +    case BUILT_IN_ATOMIC_SUB_FETCH_16:
> +    case BUILT_IN_ATOMIC_AND_FETCH_16:
> +    case BUILT_IN_ATOMIC_NAND_FETCH_16:
> +    case BUILT_IN_ATOMIC_XOR_FETCH_16:
> +    case BUILT_IN_ATOMIC_OR_FETCH_16:
> +    case BUILT_IN_ATOMIC_FETCH_ADD_16:
> +    case BUILT_IN_ATOMIC_FETCH_SUB_16:
> +    case BUILT_IN_ATOMIC_FETCH_AND_16:
> +    case BUILT_IN_ATOMIC_FETCH_NAND_16:
> +    case BUILT_IN_ATOMIC_FETCH_XOR_16:
>      case BUILT_IN_ATOMIC_FETCH_OR_16:
> +      access_size = 16;
> +      /* FALLTHRU */
> +    do_atomic:
>        {
>  	dest = gimple_call_arg (call, 0);
>  	/* DEST represents the address of a memory location.
>  	   instrument_derefs wants the memory location, so lets
>  	   dereference the address DEST before handing it to
>  	   instrument_derefs.  */
> -	if (TREE_CODE (dest) == ADDR_EXPR)
> -	  dest = TREE_OPERAND (dest, 0);
> -	else if (TREE_CODE (dest) == SSA_NAME || TREE_CODE (dest) == INTEGER_CST)
> -	  dest = build2 (MEM_REF, TREE_TYPE (TREE_TYPE (dest)),
> -			 dest, build_int_cst (TREE_TYPE (dest), 0));
> -	else
> -	  gcc_unreachable ();
> -
> -	access_size = int_size_in_bytes (TREE_TYPE (dest));
> +	tree type = build_nonstandard_integer_type (access_size
> +						    * BITS_PER_UNIT, 1);
> +	dest = build2 (MEM_REF, type, dest,
> +		       build_int_cst (build_pointer_type (char_type_node), 0));
> +	break;
>        }
>  
>      default:
> --- gcc/testsuite/c-c++-common/asan/pr79944.c.jj	2017-03-08 12:50:40.428617273 +0100
> +++ gcc/testsuite/c-c++-common/asan/pr79944.c	2017-03-08 12:34:47.000000000 +0100
> @@ -0,0 +1,18 @@
> +/* PR sanitizer/79944 */
> +/* { dg-do run } */
> +
> +struct S { int i; char p[1024]; };
> +
> +int
> +main ()
> +{
> +  struct S *p = (struct S *) __builtin_malloc (__builtin_offsetof (struct S, p) + 64);
> +  p->i = 5;
> +  asm volatile ("" : "+r" (p) : : "memory");
> +  __atomic_fetch_add ((int *) p, 5, __ATOMIC_RELAXED);
> +  asm volatile ("" : "+r" (p) : : "memory");
> +  if (p->i != 10)
> +    __builtin_abort ();
> +  __builtin_free (p);
> +  return 0;
> +}
> 
> 	Jakub
> 
>
diff mbox

Patch

--- gcc/asan.c.jj	2017-03-06 12:32:28.000000000 +0100
+++ gcc/asan.c	2017-03-08 12:24:11.151353229 +0100
@@ -603,218 +603,208 @@  get_mem_refs_of_builtin_call (const gcal
     case BUILT_IN_STRLEN:
       source0 = gimple_call_arg (call, 0);
       len = gimple_call_lhs (call);
-      break ;
+      break;
 
     /* And now the __atomic* and __sync builtins.
        These are handled differently from the classical memory memory
        access builtins above.  */
 
     case BUILT_IN_ATOMIC_LOAD_1:
-    case BUILT_IN_ATOMIC_LOAD_2:
-    case BUILT_IN_ATOMIC_LOAD_4:
-    case BUILT_IN_ATOMIC_LOAD_8:
-    case BUILT_IN_ATOMIC_LOAD_16:
       is_store = false;
-      /* fall through.  */
-
+      /* FALLTHRU */
     case BUILT_IN_SYNC_FETCH_AND_ADD_1:
-    case BUILT_IN_SYNC_FETCH_AND_ADD_2:
-    case BUILT_IN_SYNC_FETCH_AND_ADD_4:
-    case BUILT_IN_SYNC_FETCH_AND_ADD_8:
-    case BUILT_IN_SYNC_FETCH_AND_ADD_16:
-
     case BUILT_IN_SYNC_FETCH_AND_SUB_1:
-    case BUILT_IN_SYNC_FETCH_AND_SUB_2:
-    case BUILT_IN_SYNC_FETCH_AND_SUB_4:
-    case BUILT_IN_SYNC_FETCH_AND_SUB_8:
-    case BUILT_IN_SYNC_FETCH_AND_SUB_16:
-
     case BUILT_IN_SYNC_FETCH_AND_OR_1:
-    case BUILT_IN_SYNC_FETCH_AND_OR_2:
-    case BUILT_IN_SYNC_FETCH_AND_OR_4:
-    case BUILT_IN_SYNC_FETCH_AND_OR_8:
-    case BUILT_IN_SYNC_FETCH_AND_OR_16:
-
     case BUILT_IN_SYNC_FETCH_AND_AND_1:
-    case BUILT_IN_SYNC_FETCH_AND_AND_2:
-    case BUILT_IN_SYNC_FETCH_AND_AND_4:
-    case BUILT_IN_SYNC_FETCH_AND_AND_8:
-    case BUILT_IN_SYNC_FETCH_AND_AND_16:
-
     case BUILT_IN_SYNC_FETCH_AND_XOR_1:
-    case BUILT_IN_SYNC_FETCH_AND_XOR_2:
-    case BUILT_IN_SYNC_FETCH_AND_XOR_4:
-    case BUILT_IN_SYNC_FETCH_AND_XOR_8:
-    case BUILT_IN_SYNC_FETCH_AND_XOR_16:
-
     case BUILT_IN_SYNC_FETCH_AND_NAND_1:
-    case BUILT_IN_SYNC_FETCH_AND_NAND_2:
-    case BUILT_IN_SYNC_FETCH_AND_NAND_4:
-    case BUILT_IN_SYNC_FETCH_AND_NAND_8:
-
     case BUILT_IN_SYNC_ADD_AND_FETCH_1:
-    case BUILT_IN_SYNC_ADD_AND_FETCH_2:
-    case BUILT_IN_SYNC_ADD_AND_FETCH_4:
-    case BUILT_IN_SYNC_ADD_AND_FETCH_8:
-    case BUILT_IN_SYNC_ADD_AND_FETCH_16:
-
     case BUILT_IN_SYNC_SUB_AND_FETCH_1:
-    case BUILT_IN_SYNC_SUB_AND_FETCH_2:
-    case BUILT_IN_SYNC_SUB_AND_FETCH_4:
-    case BUILT_IN_SYNC_SUB_AND_FETCH_8:
-    case BUILT_IN_SYNC_SUB_AND_FETCH_16:
-
     case BUILT_IN_SYNC_OR_AND_FETCH_1:
-    case BUILT_IN_SYNC_OR_AND_FETCH_2:
-    case BUILT_IN_SYNC_OR_AND_FETCH_4:
-    case BUILT_IN_SYNC_OR_AND_FETCH_8:
-    case BUILT_IN_SYNC_OR_AND_FETCH_16:
-
     case BUILT_IN_SYNC_AND_AND_FETCH_1:
-    case BUILT_IN_SYNC_AND_AND_FETCH_2:
-    case BUILT_IN_SYNC_AND_AND_FETCH_4:
-    case BUILT_IN_SYNC_AND_AND_FETCH_8:
-    case BUILT_IN_SYNC_AND_AND_FETCH_16:
-
     case BUILT_IN_SYNC_XOR_AND_FETCH_1:
-    case BUILT_IN_SYNC_XOR_AND_FETCH_2:
-    case BUILT_IN_SYNC_XOR_AND_FETCH_4:
-    case BUILT_IN_SYNC_XOR_AND_FETCH_8:
-    case BUILT_IN_SYNC_XOR_AND_FETCH_16:
-
     case BUILT_IN_SYNC_NAND_AND_FETCH_1:
-    case BUILT_IN_SYNC_NAND_AND_FETCH_2:
-    case BUILT_IN_SYNC_NAND_AND_FETCH_4:
-    case BUILT_IN_SYNC_NAND_AND_FETCH_8:
-
     case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_1:
-    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_2:
-    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4:
-    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8:
-    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_16:
-
     case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_1:
-    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_2:
-    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4:
-    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8:
-    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_16:
-
     case BUILT_IN_SYNC_LOCK_TEST_AND_SET_1:
-    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_2:
-    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_4:
-    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_8:
-    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_16:
-
     case BUILT_IN_SYNC_LOCK_RELEASE_1:
-    case BUILT_IN_SYNC_LOCK_RELEASE_2:
-    case BUILT_IN_SYNC_LOCK_RELEASE_4:
-    case BUILT_IN_SYNC_LOCK_RELEASE_8:
-    case BUILT_IN_SYNC_LOCK_RELEASE_16:
-
     case BUILT_IN_ATOMIC_EXCHANGE_1:
-    case BUILT_IN_ATOMIC_EXCHANGE_2:
-    case BUILT_IN_ATOMIC_EXCHANGE_4:
-    case BUILT_IN_ATOMIC_EXCHANGE_8:
-    case BUILT_IN_ATOMIC_EXCHANGE_16:
-
     case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
-    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
-    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
-    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
-    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
-
     case BUILT_IN_ATOMIC_STORE_1:
-    case BUILT_IN_ATOMIC_STORE_2:
-    case BUILT_IN_ATOMIC_STORE_4:
-    case BUILT_IN_ATOMIC_STORE_8:
-    case BUILT_IN_ATOMIC_STORE_16:
-
     case BUILT_IN_ATOMIC_ADD_FETCH_1:
-    case BUILT_IN_ATOMIC_ADD_FETCH_2:
-    case BUILT_IN_ATOMIC_ADD_FETCH_4:
-    case BUILT_IN_ATOMIC_ADD_FETCH_8:
-    case BUILT_IN_ATOMIC_ADD_FETCH_16:
-
     case BUILT_IN_ATOMIC_SUB_FETCH_1:
-    case BUILT_IN_ATOMIC_SUB_FETCH_2:
-    case BUILT_IN_ATOMIC_SUB_FETCH_4:
-    case BUILT_IN_ATOMIC_SUB_FETCH_8:
-    case BUILT_IN_ATOMIC_SUB_FETCH_16:
-
     case BUILT_IN_ATOMIC_AND_FETCH_1:
-    case BUILT_IN_ATOMIC_AND_FETCH_2:
-    case BUILT_IN_ATOMIC_AND_FETCH_4:
-    case BUILT_IN_ATOMIC_AND_FETCH_8:
-    case BUILT_IN_ATOMIC_AND_FETCH_16:
-
     case BUILT_IN_ATOMIC_NAND_FETCH_1:
-    case BUILT_IN_ATOMIC_NAND_FETCH_2:
-    case BUILT_IN_ATOMIC_NAND_FETCH_4:
-    case BUILT_IN_ATOMIC_NAND_FETCH_8:
-    case BUILT_IN_ATOMIC_NAND_FETCH_16:
-
     case BUILT_IN_ATOMIC_XOR_FETCH_1:
-    case BUILT_IN_ATOMIC_XOR_FETCH_2:
-    case BUILT_IN_ATOMIC_XOR_FETCH_4:
-    case BUILT_IN_ATOMIC_XOR_FETCH_8:
-    case BUILT_IN_ATOMIC_XOR_FETCH_16:
-
     case BUILT_IN_ATOMIC_OR_FETCH_1:
-    case BUILT_IN_ATOMIC_OR_FETCH_2:
-    case BUILT_IN_ATOMIC_OR_FETCH_4:
-    case BUILT_IN_ATOMIC_OR_FETCH_8:
-    case BUILT_IN_ATOMIC_OR_FETCH_16:
-
     case BUILT_IN_ATOMIC_FETCH_ADD_1:
-    case BUILT_IN_ATOMIC_FETCH_ADD_2:
-    case BUILT_IN_ATOMIC_FETCH_ADD_4:
-    case BUILT_IN_ATOMIC_FETCH_ADD_8:
-    case BUILT_IN_ATOMIC_FETCH_ADD_16:
-
     case BUILT_IN_ATOMIC_FETCH_SUB_1:
-    case BUILT_IN_ATOMIC_FETCH_SUB_2:
-    case BUILT_IN_ATOMIC_FETCH_SUB_4:
-    case BUILT_IN_ATOMIC_FETCH_SUB_8:
-    case BUILT_IN_ATOMIC_FETCH_SUB_16:
-
     case BUILT_IN_ATOMIC_FETCH_AND_1:
-    case BUILT_IN_ATOMIC_FETCH_AND_2:
-    case BUILT_IN_ATOMIC_FETCH_AND_4:
-    case BUILT_IN_ATOMIC_FETCH_AND_8:
-    case BUILT_IN_ATOMIC_FETCH_AND_16:
-
     case BUILT_IN_ATOMIC_FETCH_NAND_1:
-    case BUILT_IN_ATOMIC_FETCH_NAND_2:
-    case BUILT_IN_ATOMIC_FETCH_NAND_4:
-    case BUILT_IN_ATOMIC_FETCH_NAND_8:
-    case BUILT_IN_ATOMIC_FETCH_NAND_16:
-
     case BUILT_IN_ATOMIC_FETCH_XOR_1:
-    case BUILT_IN_ATOMIC_FETCH_XOR_2:
-    case BUILT_IN_ATOMIC_FETCH_XOR_4:
-    case BUILT_IN_ATOMIC_FETCH_XOR_8:
-    case BUILT_IN_ATOMIC_FETCH_XOR_16:
-
     case BUILT_IN_ATOMIC_FETCH_OR_1:
+      access_size = 1;
+      goto do_atomic;
+
+    case BUILT_IN_ATOMIC_LOAD_2:
+      is_store = false;
+      /* FALLTHRU */
+    case BUILT_IN_SYNC_FETCH_AND_ADD_2:
+    case BUILT_IN_SYNC_FETCH_AND_SUB_2:
+    case BUILT_IN_SYNC_FETCH_AND_OR_2:
+    case BUILT_IN_SYNC_FETCH_AND_AND_2:
+    case BUILT_IN_SYNC_FETCH_AND_XOR_2:
+    case BUILT_IN_SYNC_FETCH_AND_NAND_2:
+    case BUILT_IN_SYNC_ADD_AND_FETCH_2:
+    case BUILT_IN_SYNC_SUB_AND_FETCH_2:
+    case BUILT_IN_SYNC_OR_AND_FETCH_2:
+    case BUILT_IN_SYNC_AND_AND_FETCH_2:
+    case BUILT_IN_SYNC_XOR_AND_FETCH_2:
+    case BUILT_IN_SYNC_NAND_AND_FETCH_2:
+    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_2:
+    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_2:
+    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_2:
+    case BUILT_IN_SYNC_LOCK_RELEASE_2:
+    case BUILT_IN_ATOMIC_EXCHANGE_2:
+    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
+    case BUILT_IN_ATOMIC_STORE_2:
+    case BUILT_IN_ATOMIC_ADD_FETCH_2:
+    case BUILT_IN_ATOMIC_SUB_FETCH_2:
+    case BUILT_IN_ATOMIC_AND_FETCH_2:
+    case BUILT_IN_ATOMIC_NAND_FETCH_2:
+    case BUILT_IN_ATOMIC_XOR_FETCH_2:
+    case BUILT_IN_ATOMIC_OR_FETCH_2:
+    case BUILT_IN_ATOMIC_FETCH_ADD_2:
+    case BUILT_IN_ATOMIC_FETCH_SUB_2:
+    case BUILT_IN_ATOMIC_FETCH_AND_2:
+    case BUILT_IN_ATOMIC_FETCH_NAND_2:
+    case BUILT_IN_ATOMIC_FETCH_XOR_2:
     case BUILT_IN_ATOMIC_FETCH_OR_2:
+      access_size = 2;
+      goto do_atomic;
+
+    case BUILT_IN_ATOMIC_LOAD_4:
+      is_store = false;
+      /* FALLTHRU */
+    case BUILT_IN_SYNC_FETCH_AND_ADD_4:
+    case BUILT_IN_SYNC_FETCH_AND_SUB_4:
+    case BUILT_IN_SYNC_FETCH_AND_OR_4:
+    case BUILT_IN_SYNC_FETCH_AND_AND_4:
+    case BUILT_IN_SYNC_FETCH_AND_XOR_4:
+    case BUILT_IN_SYNC_FETCH_AND_NAND_4:
+    case BUILT_IN_SYNC_ADD_AND_FETCH_4:
+    case BUILT_IN_SYNC_SUB_AND_FETCH_4:
+    case BUILT_IN_SYNC_OR_AND_FETCH_4:
+    case BUILT_IN_SYNC_AND_AND_FETCH_4:
+    case BUILT_IN_SYNC_XOR_AND_FETCH_4:
+    case BUILT_IN_SYNC_NAND_AND_FETCH_4:
+    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_4:
+    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_4:
+    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_4:
+    case BUILT_IN_SYNC_LOCK_RELEASE_4:
+    case BUILT_IN_ATOMIC_EXCHANGE_4:
+    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
+    case BUILT_IN_ATOMIC_STORE_4:
+    case BUILT_IN_ATOMIC_ADD_FETCH_4:
+    case BUILT_IN_ATOMIC_SUB_FETCH_4:
+    case BUILT_IN_ATOMIC_AND_FETCH_4:
+    case BUILT_IN_ATOMIC_NAND_FETCH_4:
+    case BUILT_IN_ATOMIC_XOR_FETCH_4:
+    case BUILT_IN_ATOMIC_OR_FETCH_4:
+    case BUILT_IN_ATOMIC_FETCH_ADD_4:
+    case BUILT_IN_ATOMIC_FETCH_SUB_4:
+    case BUILT_IN_ATOMIC_FETCH_AND_4:
+    case BUILT_IN_ATOMIC_FETCH_NAND_4:
+    case BUILT_IN_ATOMIC_FETCH_XOR_4:
     case BUILT_IN_ATOMIC_FETCH_OR_4:
+      access_size = 4;
+      goto do_atomic;
+
+    case BUILT_IN_ATOMIC_LOAD_8:
+      is_store = false;
+      /* FALLTHRU */
+    case BUILT_IN_SYNC_FETCH_AND_ADD_8:
+    case BUILT_IN_SYNC_FETCH_AND_SUB_8:
+    case BUILT_IN_SYNC_FETCH_AND_OR_8:
+    case BUILT_IN_SYNC_FETCH_AND_AND_8:
+    case BUILT_IN_SYNC_FETCH_AND_XOR_8:
+    case BUILT_IN_SYNC_FETCH_AND_NAND_8:
+    case BUILT_IN_SYNC_ADD_AND_FETCH_8:
+    case BUILT_IN_SYNC_SUB_AND_FETCH_8:
+    case BUILT_IN_SYNC_OR_AND_FETCH_8:
+    case BUILT_IN_SYNC_AND_AND_FETCH_8:
+    case BUILT_IN_SYNC_XOR_AND_FETCH_8:
+    case BUILT_IN_SYNC_NAND_AND_FETCH_8:
+    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_8:
+    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_8:
+    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_8:
+    case BUILT_IN_SYNC_LOCK_RELEASE_8:
+    case BUILT_IN_ATOMIC_EXCHANGE_8:
+    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
+    case BUILT_IN_ATOMIC_STORE_8:
+    case BUILT_IN_ATOMIC_ADD_FETCH_8:
+    case BUILT_IN_ATOMIC_SUB_FETCH_8:
+    case BUILT_IN_ATOMIC_AND_FETCH_8:
+    case BUILT_IN_ATOMIC_NAND_FETCH_8:
+    case BUILT_IN_ATOMIC_XOR_FETCH_8:
+    case BUILT_IN_ATOMIC_OR_FETCH_8:
+    case BUILT_IN_ATOMIC_FETCH_ADD_8:
+    case BUILT_IN_ATOMIC_FETCH_SUB_8:
+    case BUILT_IN_ATOMIC_FETCH_AND_8:
+    case BUILT_IN_ATOMIC_FETCH_NAND_8:
+    case BUILT_IN_ATOMIC_FETCH_XOR_8:
     case BUILT_IN_ATOMIC_FETCH_OR_8:
+      access_size = 8;
+      goto do_atomic;
+
+    case BUILT_IN_ATOMIC_LOAD_16:
+      is_store = false;
+      /* FALLTHRU */
+    case BUILT_IN_SYNC_FETCH_AND_ADD_16:
+    case BUILT_IN_SYNC_FETCH_AND_SUB_16:
+    case BUILT_IN_SYNC_FETCH_AND_OR_16:
+    case BUILT_IN_SYNC_FETCH_AND_AND_16:
+    case BUILT_IN_SYNC_FETCH_AND_XOR_16:
+    case BUILT_IN_SYNC_FETCH_AND_NAND_16:
+    case BUILT_IN_SYNC_ADD_AND_FETCH_16:
+    case BUILT_IN_SYNC_SUB_AND_FETCH_16:
+    case BUILT_IN_SYNC_OR_AND_FETCH_16:
+    case BUILT_IN_SYNC_AND_AND_FETCH_16:
+    case BUILT_IN_SYNC_XOR_AND_FETCH_16:
+    case BUILT_IN_SYNC_NAND_AND_FETCH_16:
+    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_16:
+    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_16:
+    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_16:
+    case BUILT_IN_SYNC_LOCK_RELEASE_16:
+    case BUILT_IN_ATOMIC_EXCHANGE_16:
+    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
+    case BUILT_IN_ATOMIC_STORE_16:
+    case BUILT_IN_ATOMIC_ADD_FETCH_16:
+    case BUILT_IN_ATOMIC_SUB_FETCH_16:
+    case BUILT_IN_ATOMIC_AND_FETCH_16:
+    case BUILT_IN_ATOMIC_NAND_FETCH_16:
+    case BUILT_IN_ATOMIC_XOR_FETCH_16:
+    case BUILT_IN_ATOMIC_OR_FETCH_16:
+    case BUILT_IN_ATOMIC_FETCH_ADD_16:
+    case BUILT_IN_ATOMIC_FETCH_SUB_16:
+    case BUILT_IN_ATOMIC_FETCH_AND_16:
+    case BUILT_IN_ATOMIC_FETCH_NAND_16:
+    case BUILT_IN_ATOMIC_FETCH_XOR_16:
     case BUILT_IN_ATOMIC_FETCH_OR_16:
+      access_size = 16;
+      /* FALLTHRU */
+    do_atomic:
       {
 	dest = gimple_call_arg (call, 0);
 	/* DEST represents the address of a memory location.
 	   instrument_derefs wants the memory location, so lets
 	   dereference the address DEST before handing it to
 	   instrument_derefs.  */
-	if (TREE_CODE (dest) == ADDR_EXPR)
-	  dest = TREE_OPERAND (dest, 0);
-	else if (TREE_CODE (dest) == SSA_NAME || TREE_CODE (dest) == INTEGER_CST)
-	  dest = build2 (MEM_REF, TREE_TYPE (TREE_TYPE (dest)),
-			 dest, build_int_cst (TREE_TYPE (dest), 0));
-	else
-	  gcc_unreachable ();
-
-	access_size = int_size_in_bytes (TREE_TYPE (dest));
+	tree type = build_nonstandard_integer_type (access_size
+						    * BITS_PER_UNIT, 1);
+	dest = build2 (MEM_REF, type, dest,
+		       build_int_cst (build_pointer_type (char_type_node), 0));
+	break;
       }
 
     default:
--- gcc/testsuite/c-c++-common/asan/pr79944.c.jj	2017-03-08 12:50:40.428617273 +0100
+++ gcc/testsuite/c-c++-common/asan/pr79944.c	2017-03-08 12:34:47.000000000 +0100
@@ -0,0 +1,18 @@ 
+/* PR sanitizer/79944 */
+/* { dg-do run } */
+
+struct S { int i; char p[1024]; };
+
+int
+main ()
+{
+  struct S *p = (struct S *) __builtin_malloc (__builtin_offsetof (struct S, p) + 64);
+  p->i = 5;
+  asm volatile ("" : "+r" (p) : : "memory");
+  __atomic_fetch_add ((int *) p, 5, __ATOMIC_RELAXED);
+  asm volatile ("" : "+r" (p) : : "memory");
+  if (p->i != 10)
+    __builtin_abort ();
+  __builtin_free (p);
+  return 0;
+}