diff --git a/gcc/builtins.cc b/gcc/builtins.cc index 85459200a09..57929a42bc4 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -1360,7 +1360,7 @@ expand_builtin_prefetch (tree exp) rtx get_memory_rtx (tree exp, tree len) { - tree orig_exp = exp; + tree orig_exp = exp, base; rtx addr, mem; /* When EXP is not resolved SAVE_EXPR, MEM_ATTRS can be still derived @@ -1391,10 +1391,11 @@ get_memory_rtx (tree exp, tree len) if (is_gimple_mem_ref_addr (TREE_OPERAND (exp, 0))) set_mem_attributes (mem, exp, 0); else if (TREE_CODE (TREE_OPERAND (exp, 0)) == ADDR_EXPR - && (exp = get_base_address (TREE_OPERAND (TREE_OPERAND (exp, 0), - 0)))) + && (base = get_base_address (TREE_OPERAND (TREE_OPERAND (exp, 0), + 0)))) { - exp = build_fold_addr_expr (exp); + unsigned int align = get_pointer_alignment (TREE_OPERAND (exp, 0)); + exp = build_fold_addr_expr (base); exp = fold_build2 (MEM_REF, build_array_type (char_type_node, build_range_type (sizetype, @@ -1402,6 +1403,10 @@ get_memory_rtx (tree exp, tree len) NULL)), exp, build_int_cst (ptr_type_node, 0)); set_mem_attributes (mem, exp, 0); + /* Since we stripped parts make sure the offset is unknown and the + alignment is computed from the original address. */ + clear_mem_offset (mem); + set_mem_align (mem, align); } set_mem_alias_set (mem, 0); return mem; diff --git a/gcc/testsuite/gfortran.dg/pr106331.f90 b/gcc/testsuite/gfortran.dg/pr106331.f90 new file mode 100644 index 00000000000..3873863be48 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr106331.f90 @@ -0,0 +1,7 @@ +! { dg-do run } +! { dg-options "-Og" } + +PROGRAM main + CHARACTER(LEN=24) :: a(2) + a = '' +END PROGRAM