On Wed, Jan 15, 2020 at 01:18:54PM +0000, Martin Sebor wrote:
> @@ -4099,14 +4122,18 @@ determine_min_objsize (tree dest)
>  
>    init_object_sizes ();
>  
> -  if (compute_builtin_object_size (dest, 2, &size))
> -    return size;
> -
>    /* Try to determine the size of the object through the RHS
>       of the assign statement.  */
>    if (TREE_CODE (dest) == SSA_NAME)
>      {
>        gimple *stmt = SSA_NAME_DEF_STMT (dest);
> +
> +      /* Determine the size of the largest object when DEST refers
> +      to two or more via a PHI, otherwise the smallest.  */
> +      int ostype = gimple_code (stmt) == GIMPLE_PHI ? 0 : 2;
> +      if (compute_builtin_object_size (dest, ostype, &size))
> +     return size;
> +
>        if (!is_gimple_assign (stmt))
>       return HOST_WIDE_INT_M1U;
>  
> @@ -4118,6 +4145,10 @@ determine_min_objsize (tree dest)
>        return determine_min_objsize (dest);
>      }
>  
> +  /* Try to determine the size of the referenced object itself.  */
> +  if (compute_builtin_object_size (dest, 2, &size))
> +    return size;
> +

This looks wrong.  For one, this function is used for two purposes now and
you tweak it for one, but more importantly, whether he initial stmt
you see is a PHI or not can't make a difference, how is that case e.g.
different from _1 = PHI <_3, _4>; _2 = _1 + 1; and asking about _2?
For _1, you'd use (correctly) the maximum, but if called on _2, you'd ask
(wrongly) for minimum instead of maximum.

>    /* The size of a flexible array cannot be determined.  Otherwise,
> -     for arrays with more than one element, return the size of its
> -     type.  GCC itself misuses arrays of both zero and one elements
> -     as flexible array members so they are excluded as well.  */
> +     unless the reference involves a union, for arrays with more than
> +     one element, return the size of its type.  GCC itself misuses
> +     arrays of both zero and one elements as flexible array members
> +     so they are excluded as well.  */
>    if (TREE_CODE (type) != ARRAY_TYPE
> -      || !array_at_struct_end_p (dest))
> +      || (!component_ref_via_union_p (dest)
> +       && !array_at_struct_end_p (dest)))
>      {
>        tree type_size = TYPE_SIZE_UNIT (type);
>        if (type_size && TREE_CODE (type_size) == INTEGER_CST

This also looks like a hack to shut up the particular testcases instead of
really playing with what the IL provides.  Instead of the unions, consider
e.g. C++ placement new, have a pointer to a buffer into which you placement
new one structure, take address of some member in it, pass it to something,
if it doesn't have a destructor do a C++ placement new into the same buffer
but with different structure, take address of a different member with the
same address as the first member, do the str*cmp on it that invokes this
stuff.  SCCVN will (likely) find out that the values of those two pointers
are the same and just use the former pointer in the latter case.

        Jakub

Reply via email to