This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: C++ PATCH for c++/39480
Jason Merrill <jason@redhat.com> writes:
> Ian Lance Taylor wrote:
>> The chance of this logic remaining in sync over time seems rather low,
>> especially since the code is in two different directories. I think that
>> on mainline the condition, trivial as it is, ought to move into a
>> function in builtins.c. I'll preapprove the patch to builtins.c.
>
> I was planning to remove the call to builtin_memcpy entirely for
> 4.5. If you still want the separate function, were you thinking
> something like this?
Yes. (Sorry for the slow reply.)
Ian
> commit 2574a0ce946df86e72226840f333f9f9ae227317
> Author: Jason Merrill <jason@redhat.com>
> Date: Wed Apr 15 17:35:11 2009 -0400
>
> diff --git a/gcc/builtins.c b/gcc/builtins.c
> index 9f0f4ac..00ee77a 100644
> --- a/gcc/builtins.c
> +++ b/gcc/builtins.c
> @@ -341,6 +341,16 @@ get_object_alignment (tree exp, unsigned int align, unsigned int max_align)
> return MIN (align, max_align);
> }
>
> +/* Returns true iff we can trust that alignment information has been
> + calculated properly. */
> +
> +bool
> +can_trust_pointer_alignment (void)
> +{
> + /* We rely on TER to compute accurate alignment information. */
> + return (optimize && flag_tree_ter);
> +}
> +
> /* Return the alignment in bits of EXP, a pointer valued expression.
> But don't return more than MAX_ALIGN no matter what.
> The alignment returned is, by default, the alignment of the thing that
> @@ -354,8 +364,7 @@ get_pointer_alignment (tree exp, unsigned int max_align)
> {
> unsigned int align, inner;
>
> - /* We rely on TER to compute accurate alignment information. */
> - if (!(optimize && flag_tree_ter))
> + if (!can_trust_pointer_alignment ())
> return 0;
>
> if (!POINTER_TYPE_P (TREE_TYPE (exp)))
> diff --git a/gcc/cp/call.c b/gcc/cp/call.c
> index ef7c045..0e53095 100644
> --- a/gcc/cp/call.c
> +++ b/gcc/cp/call.c
> @@ -5402,11 +5402,11 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
> arg1 = arg;
> arg0 = cp_build_unary_op (ADDR_EXPR, to, 0, complain);
>
> - if (!(optimize && flag_tree_ter))
> + if (!can_trust_pointer_alignment ())
> {
> - /* When TER is off get_pointer_alignment returns 0, so a call
> + /* If we can't be sure about pointer alignment, a call
> to __builtin_memcpy is expanded as a call to memcpy, which
> - is invalid with identical args. When TER is on it is
> + is invalid with identical args. Otherwise it is
> expanded as a block move, which should be safe. */
> arg0 = save_expr (arg0);
> arg1 = save_expr (arg1);
> diff --git a/gcc/tree.h b/gcc/tree.h
> index b191d43..e1865c2 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -4838,6 +4838,7 @@ extern tree build_va_arg_indirect_ref (tree);
> extern tree build_string_literal (int, const char *);
> extern bool validate_arglist (const_tree, ...);
> extern rtx builtin_memset_read_str (void *, HOST_WIDE_INT, enum machine_mode);
> +extern bool can_trust_pointer_alignment (void);
> extern int get_pointer_alignment (tree, unsigned int);
> extern bool is_builtin_name(const char*);
> extern int get_object_alignment (tree, unsigned int, unsigned int);