On Mon, Feb 11, 2019 at 11:03:41AM +0100, Eric Botcazou wrote:
> asan_expand_mark_ifn does manual store merging but doesn't take into account
> the alignment, so this can break on strict-alignment platforms.
>
> Tested on SPARC/Solaris 11, where this fixes this regression:
>
> FAIL: gcc.dg/asan/use-after-scope-5.c -O0 output pattern test
> FAIL: gcc.dg/asan/use-after-scope-5.c -O1 output pattern test
> FAIL: gcc.dg/asan/use-after-scope-5.c -O2 output pattern test
> FAIL: gcc.dg/asan/use-after-scope-5.c -O3 -fomit-frame-pointer -funroll-
> loops -fpeel-loops -ftracer -finline-functions output pattern test
> FAIL: gcc.dg/asan/use-after-scope-5.c -O3 -g output pattern test
> FAIL: gcc.dg/asan/use-after-scope-5.c -Os output pattern test
> FAIL: gcc.dg/asan/use-after-scope-5.c -O2 -flto -flto-partition=none
> output
> pattern test
> FAIL: gcc.dg/asan/use-after-scope-5.c -O2 -flto output pattern test
>
> OK for mainline?
>
>
> 2019-02-11 Eric Botcazou <[email protected]>
>
> * asan.c (asan_expand_mark_ifn): Always use a size of 1 byte for the
> stores on strict-alignment platforms.
So, wouldn't it be better to check for STRICT_ALIGNMENT
get_pointer_alignment (base_addr) and do this only if that alignment
(shifted right by ASAN_SHADOW_SHIFT) is not sufficient and e.g. if we would
know that the shadow is at least 2 byte aligned but not 4 byte aligned, use
size = 2 instead of always 1? E.g. compute this before the loop as
max_size and for !STRICT_ALIGNMENT use always max_size 4?
> Index: asan.c
> ===================================================================
> --- asan.c (revision 268508)
> +++ asan.c (working copy)
> @@ -3226,10 +3226,13 @@ asan_expand_mark_ifn (gimple_stmt_iterat
> for (unsigned HOST_WIDE_INT offset = 0; offset < shadow_size;)
> {
> unsigned size = 1;
> - if (shadow_size - offset >= 4)
> - size = 4;
> - else if (shadow_size - offset >= 2)
> - size = 2;
> + if (!STRICT_ALIGNMENT)
> + {
> + if (shadow_size - offset >= 4)
> + size = 4;
> + else if (shadow_size - offset >= 2)
> + size = 2;
> + }
>
> unsigned HOST_WIDE_INT last_chunk_size = 0;
> unsigned HOST_WIDE_INT s = (offset + size) * ASAN_SHADOW_GRANULARITY;
Jakub