http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59821

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org,
                   |                            |jason at gcc dot gnu.org

--- Comment #2 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
For the calls this just happens to work completely by accident, nothing else.
I mean, the default argument expression obviously has location_t from where it
has been defined, i.e. the function/method/ctor definition.  The reason why in
the first case you get the locus of the call is that gimplify_arg sets the
location_t of the arguments to that, but only on the toplevel expression.
Now, in the new case the C++ FE adds an TARGET_EXPR around the default argument
and so during the gimplification it is no longer toplevel expression in the
argument, so gimplify_arg doesn't adjust it.

If you write:
struct Foo
{
  int line;
  Foo (int line = __builtin_LINE () + 1) : line (line) {}
};
int
main ()
{
  if (Foo().line != (new Foo)->line)
    __builtin_abort ();
}

then it will be in both cases the location of the Foo ctor, because the
argument will not be __builtin_LINE() CALL_EXPR as toplevel.

So, IMHO if you want a different behavior, you shouldn't leave this to the
gimplifier, but explicitly change it in the FE.  Say in convert_default_arg or
functions it calls change EXPR_LOCATION of all CALL_EXPRs to the 3 problematic
builtins (I'd argue that only those and nothing else, the expressions really
have locus of where the default argument has been defined and it is desirable
to use that for diagnostic purposes etc.).  convert_default_arg already walks
the expression several times through break_out_target_exprs, so if we e.g.
wanted to
avoid the cost of walking it once again, break_out_target_exprs could have a
flag to tweak location_t of __builtin_{LINE,FILE,FUNCTION}.  Jason, thoughts on
this?  In any case this needs to be documented.  What about other default
locations?  Say if e.g. NSDMI contains __builtin_LINE () call, do we want to
get a value of where the NSDMI is defined, or where the object is constructed?

Reply via email to