On 12/16/2015 11:04 AM, David Malcolm wrote:
Currently trunk emits range information for most bad binary operations
in the C++ frontend; but not in the C frontend.

The helper function binary_op_error shared by C and C++ takes a
location_t.  In the C++ frontend, a location_t containing the range
has already been built, so we get the underline when it later validates
the expression: e.g. this example from:
    https://gcc.gnu.org/wiki/ClangDiagnosticsComparison

t.cc:9:19: error: no match for ‘operator+’ (operand types are ‘int’ and ‘foo’)
    return P->bar() + *P;
           ~~~~~~~~~^~~~

In the C frontend, the "full" location_t is only built
after type-checking, so if type-checking fails, we get a caret/range
covering just the operator so e.g. for:

    return (some_function ()
     + some_other_function ());

we get just:

gcc.dg/bad-binary-ops.c:29:4: error: invalid operands to binary + (have 'struct 
s' and 'struct t')
     + some_other_function ());
     ^

The following patch updates binary_op_error to accept a rich_location *.
For the C++ frontend we populate it with just the location_t as before,
but for the C frontend we can add locations for the operands, giving
this underlining for the example above:

bad-binary-ops.c:29:4: error: invalid operands to binary + (have 'struct s' and 
'struct t')
    return (some_function ()
            ~~~~~~~~~~~~~~~~
     + some_other_function ());
     ^ ~~~~~~~~~~~~~~~~~~~~~~

Additionally, in the C++ frontend, cp_build_binary_op has an "error"
call, which implicitly uses input_location, giving this reduced
information for another test case from
https://gcc.gnu.org/wiki/ClangDiagnosticsComparison:

bad-binary-ops.C:10:14: error: invalid operands of types '__m128 {aka float}' 
and 'const int*' to binary 'operator/'
    myvec[1] / ptr;
               ^~~

The patch updates it to use error_at with the location_t provided,
fixing the above to become:

bad-binary-ops.C:10:12: error: invalid operands of types '__m128 {aka float}' 
and 'const int*' to binary 'operator/'
    myvec[1] / ptr;
    ~~~~~~~~~^~~~~

Finally, since this patch adds a usage of
gcc_rich_location::maybe_add_expr to cc1, we can drop the hacked-in
copy of gcc_rich_location::add_expr from
gcc.dg/plugin/diagnostic_plugin_show_trees.c.

Successfully bootstrapped&regrtested on x86_64-pc-linux-gnu;
adds 15 new PASS results in g++.sum and 7 new PASS results in gcc.sum

OK for trunk in stage 3?

gcc/c-family/ChangeLog:
        * c-common.c (binary_op_error): Convert first param from
        location_t to rich_location * and use it when emitting an error.
        * c-common.h (binary_op_error): Convert first param from
        location_t to rich_location *.

gcc/c/ChangeLog:
        * c-typeck.c: Include "gcc-rich-location.h".
        (build_binary_op): In the two places that call binary_op_error,
        create a gcc_rich_location and populate it with the location of
        the binary op and its two operands.

gcc/cp/ChangeLog:
        * typeck.c (cp_build_binary_op): Update for change in signature
        of build_binary_op.  Use error_at to replace an implicit use
        of input_location with param "location" in "invalid operands"
        error.
        (cp_build_binary_op): Replace an error with an error_at, using
        "location", rather than implicitly using input_location.

gcc/testsuite/ChangeLog:
        * g++.dg/diagnostic/bad-binary-ops.C: New test case.
        * gcc.dg/bad-binary-ops.c: New test case.
        gcc.dg/plugin/diagnostic_plugin_show_trees.c (get_range_for_expr):
        Remove material copied from gcc-rich-location.c
        (gcc_rich_location::add_expr): Likewise.
So I'm of a mixed mind here.

We're well into stage3 and I can't see a reasonable way to call this a bugfix, but I see the value here at the end user level and it looks to be quite safe.

I'll tentatively approve -- give other maintainers 48hrs to object on the grounds this isn't a bugfix before committing.

Jeff

Reply via email to