> > OK, revised patch attached. I have manually verified that it yields the
> > expected result for an array of long doubles on 64-bit SPARC.
> >
> >
> > 2019-02-12 Eric Botcazou <ebotca...@adacore.com>
> >
> > * asan.c (asan_expand_mark_ifn): Take into account the alignment of
> > the object to pick the size of stores on strict-alignment platforms.
>
> Ok, thanks.
Glad you insisted in the end, because I have ASAN working on SPARC64/Linux,
but only after fixing another bug on 64-bit strict-alignment platforms:
/* Align base if target is STRICT_ALIGNMENT. */
if (STRICT_ALIGNMENT)
base = expand_binop (Pmode, and_optab, base,
gen_int_mode (-((GET_MODE_ALIGNMENT (SImode)
<< ASAN_SHADOW_SHIFT)
/ BITS_PER_UNIT), Pmode), NULL_RTX,
1, OPTAB_DIRECT);
GET_MODE_ALIGNMENT is unsigned int so this zero-extends to unsigned long...
Tested on 32-bit and 64-bit SPARC/Linux, applied on mainline as obvious.
2019-02-15 Eric Botcazou <ebotca...@adacore.com>
* asan.c (asan_emit_stack_protection): Use full-sized mask to align
the base address on 64-bit strict-alignment platforms.
--
Eric Botcazou
Index: asan.c
===================================================================
--- asan.c (revision 268849)
+++ asan.c (working copy)
@@ -1440,13 +1441,15 @@ asan_emit_stack_protection (rtx base, rt
base_align_bias = ((asan_frame_size + alignb - 1)
& ~(alignb - HOST_WIDE_INT_1)) - asan_frame_size;
}
+
/* Align base if target is STRICT_ALIGNMENT. */
if (STRICT_ALIGNMENT)
- base = expand_binop (Pmode, and_optab, base,
- gen_int_mode (-((GET_MODE_ALIGNMENT (SImode)
- << ASAN_SHADOW_SHIFT)
- / BITS_PER_UNIT), Pmode), NULL_RTX,
- 1, OPTAB_DIRECT);
+ {
+ const HOST_WIDE_INT align
+ = (GET_MODE_ALIGNMENT (SImode) / BITS_PER_UNIT) << ASAN_SHADOW_SHIFT;
+ base = expand_binop (Pmode, and_optab, base, gen_int_mode (-align, Pmode),
+ NULL_RTX, 1, OPTAB_DIRECT);
+ }
if (use_after_return_class == -1 && pbase)
emit_move_insn (pbase, base);
@ -1534,7 +1548,7 @@ asan_emit_stack_protection (rtx base, rt
shadow_mem = gen_rtx_MEM (SImode, shadow_base);
set_mem_alias_set (shadow_mem, asan_shadow_set);
if (STRICT_ALIGNMENT)
- set_mem_align (shadow_mem, (GET_MODE_ALIGNMENT (SImode)));
+ set_mem_align (shadow_mem, GET_MODE_ALIGNMENT (SImode));
prev_offset = base_offset;
asan_redzone_buffer rz_buffer (shadow_mem, prev_offset);