On Thu, Mar 26, 2020 at 07:55:39PM -0600, Martin Sebor via Gcc-patches wrote:
> --- a/gcc/c-family/c-attribs.c
> +++ b/gcc/c-family/c-attribs.c
> @@ -2526,17 +2526,21 @@ handle_copy_attribute (tree *node, tree name, tree 
> args,
>        && !FUNCTION_POINTER_TYPE_P (TREE_TYPE (ref)))
>      ref = TREE_TYPE (ref);
>  
> +  tree reftype = DECL_P (ref) || EXPR_P (ref) ? TREE_TYPE (ref) : ref;

Perhaps
  tree reftype = TYPE_P (ref) ? ref : TREE_TYPE (ref);
would be shorter and easier to read?

>    if (DECL_P (decl))
>      {
>        if ((VAR_P (decl)
>          && (TREE_CODE (ref) == FUNCTION_DECL
>              || (EXPR_P (ref)
> -                && POINTER_TYPE_P (TREE_TYPE (ref))
> -                && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (ref))))))
> +                && POINTER_TYPE_P (reftype)
> +                && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (reftype)))))
>         || (TREE_CODE (decl) == FUNCTION_DECL
>             && (VAR_P (ref)
>                 || (EXPR_P (ref)
> -                   && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (ref))))))
> +                   && !FUNC_OR_METHOD_TYPE_P (reftype)
> +                   && (!POINTER_TYPE_P (reftype)
> +                       || !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (reftype)))))))
>       {
>         /* It makes no sense to try to copy function attributes
>            to a variable, or variable attributes to a function.  */
> @@ -2606,15 +2610,11 @@ handle_copy_attribute (tree *node, tree name, tree 
> args,
>  
>    /* Similarly, a function declared with attribute noreturn has it
>       attached on to it, but a C11 _Noreturn function does not.  */
> -  tree reftype = ref;
>    if (DECL_P (ref)
>        && TREE_THIS_VOLATILE (ref)
> -      && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (reftype)))
> +      && FUNC_OR_METHOD_TYPE_P (reftype))
>      TREE_THIS_VOLATILE (decl) = true;
>  
> -  if (DECL_P (ref) || EXPR_P (ref))
> -    reftype = TREE_TYPE (ref);
> -
>    if (POINTER_TYPE_P (reftype))
>      reftype = TREE_TYPE (reftype);
> 

The above changes are certainly a good cleanup.
 
> @@ -2623,9 +2623,10 @@ handle_copy_attribute (tree *node, tree name, tree 
> args,
>  
>    tree attrs = TYPE_ATTRIBUTES (reftype);
>  
> -  /* Copy type attributes from REF to DECL.  */
> +  /* Copy type attributes from REF to DECL.  Pass in REF if it's a DECL
> +     or a type but not if it's an expression.  */
>    for (tree at = attrs; at; at = TREE_CHAIN (at))
> -    decl_attributes (node, at, flags, ref);
> +    decl_attributes (node, at, flags, EXPR_P (ref) ? NULL_TREE : ref);
>  
>    return NULL_TREE;
>  }

This one really depends on what exactly the copy attribute should do.
The current state where it tries to determine a decl from which to copy
attributes is something that is IMHO very hard to be documented:

  /* Consider address-of expressions in the attribute argument
     as requests to copy from the referenced entity.  */
  if (TREE_CODE (ref) == ADDR_EXPR)
    ref = TREE_OPERAND (ref, 0);

  do
    {
      /* Drill down into references to find the referenced decl.  */
      tree_code refcode = TREE_CODE (ref);
      if (refcode == ARRAY_REF
          || refcode == INDIRECT_REF)
        ref = TREE_OPERAND (ref, 0);
      else if (refcode == COMPONENT_REF)
        ref = TREE_OPERAND (ref, 1);
      else
        break;
    } while (!DECL_P (ref));

but my point in the PR was that if you do it this way, COMPOUND_EXPRs should
be taken into account as well.
Because, right now you e.g. diagnose
  copy (1)
but don't diagnose
  copy (bar (), 1)
which appart from some side-effects first is the same thing.
Similarly, if you have
  copy (&decl)
it will behave differently from
  copy (bar (), &decl)
or
  copy (&whatever.field)
from
  copy (bar (), &whatever.field)
Yes, the comma expression isn't lvalue in C (but is in C++), but it doesn't
seem the current code would differentiate between what is an lvalue or
rvalue.  But it is something that can come either from the user, or e.g.
from sanitizers if they need to evaluate something before evaluating some
expression, or from slight differentiations on how we deal with the
COMPOUND_EXPRs elsewhere in the FE (see the PR94339 change).
>From the user POV, it would be better if there was separate syntax in which
case to extract the attributes from the type vs. when extract it from
much more limited set of expressions (basically, only decls or
COMPONENT_REFs) and error on anything else.

        Jakub

Reply via email to