On 11/21/20 1:01 AM, Jakub Jelinek wrote:
On Fri, Nov 20, 2020 at 03:44:01PM -0700, Martin Sebor via Gcc-patches wrote:
So that likely means you are doing it too early.

The bounds are added to attribute "arg spec" for each param in
push_parm_decl.  I think that's both as early and (except maybe
in function definitions) as late as can be.  After that point,
the association between a VLA parameter and its most significant
bound is lost.

If the most significant bound is lost, why don't you save in the attribute
early only the most significant bound before it is lost

The other bounds are a part of the type so saving them in the attribute
isn't essential.  I save all of them because it simplifies their lookup.
With only the most significant bound in the attribute argument, looking
up the other bounds (e.g., when checking function redeclarations for
mismatches) will, in addition to doing what's done for the most
significant bound, involve scanning the declarations' argument lists,
extracting the bounds from the SAVE_EXPRs, before comparing them.
As an example, in

  void f (int A[m][n]);

the attribute has the chain (VAR_DECL(m), VAR_DECL(n)) as arguments
and comparing them with another declaration of f is as simple as
traversing the chain and comparing each node value.

With the change you suggest, the attribute will only have VAR_DECL(m)
and the least significant bound will have to be extracted from A[m]'s
type's size which is:

  MULT (NOP (bitsizetype, NOP (sizetype, SAVE (VAR (n)))), 32)

It's possible to do but not without some additional complexity and
cost.

and for the other
bounds just refer to the SAVE_EXPRs in the FUNCTION_TYPE's TYPE_ARG_TYPES
ARRAY_TYPEs?  And for function definitions, even the outermost bounds
aren't really lost, the FE for
int bar ();
int baz ();

int
foo (int n, int x[bar () + 4][baz () + 2])
{
   return sizeof (x[0]);
}
emits all the side-effects, though not sure if it creates a SAVE_EXPR for
that.  But for the definitions you really want to use the same SAVE_EXPR
as the function evaluates.

It does create a SAVE_EXPR.  I found the code in grokdeclarator.
The SAVE_EXPR is available to callers so I can use it instead.

I'm still not sure I understand why using the SAVE_EXPR of the bound
in the attribute argument where it isn't evaluated is preferable to
saving the unshared bound as the argument instead.  Can you explain
the problem with doing that?

Thanks
Martin

Reply via email to