Commit 745e411d by David Malcolm Committed by David Malcolm

C and C++ FE: fix source ranges for binary ops

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.

From-SVN: r231884
parent 7c154ecc
2015-12-21 David Malcolm <dmalcolm@redhat.com>
* 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 *.
2015-12-16 David Malcolm <dmalcolm@redhat.com>
* c-common.h (conflict_marker_get_final_tok_kind): New prototype.
......
......@@ -3795,10 +3795,21 @@ c_register_builtin_type (tree type, const char* name)
/* Print an error message for invalid operands to arith operation
CODE with TYPE0 for operand 0, and TYPE1 for operand 1.
LOCATION is the location of the message. */
RICHLOC is a rich location for the message, containing either
three separate locations for each of the operator and operands
lhs op rhs
~~~ ^~ ~~~
(C FE), or one location ranging over all over them
lhs op rhs
~~~~^~~~~~
(C++ FE). */
void
binary_op_error (location_t location, enum tree_code code,
binary_op_error (rich_location *richloc, enum tree_code code,
tree type0, tree type1)
{
const char *opname;
......@@ -3850,9 +3861,9 @@ binary_op_error (location_t location, enum tree_code code,
default:
gcc_unreachable ();
}
error_at (location,
"invalid operands to binary %s (have %qT and %qT)", opname,
type0, type1);
error_at_rich_loc (richloc,
"invalid operands to binary %s (have %qT and %qT)",
opname, type0, type1);
}
/* Given an expression as a tree, return its original type. Do this
......
......@@ -817,7 +817,7 @@ extern tree c_sizeof_or_alignof_type (location_t, tree, bool, bool, int);
extern tree c_alignof_expr (location_t, tree);
/* Print an error message for invalid operands to arith operation CODE.
NOP_EXPR is used as a special case (see truthvalue_conversion). */
extern void binary_op_error (location_t, enum tree_code, tree, tree);
extern void binary_op_error (rich_location *, enum tree_code, tree, tree);
extern tree fix_string_type (tree);
extern void constant_expression_warning (tree);
extern void constant_expression_error (tree);
......
2015-12-21 David Malcolm <dmalcolm@redhat.com>
* 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.
2015-12-16 David Malcolm <dmalcolm@redhat.com>
* c-parser.c (c_parser_statement_after_labels): When calling
......
......@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "cilk.h"
#include "gomp-constants.h"
#include "spellcheck.h"
#include "gcc-rich-location.h"
/* Possible cases of implicit bad conversions. Used to select
diagnostic messages in convert_for_assignment. */
......@@ -11202,7 +11203,10 @@ build_binary_op (location_t location, enum tree_code code,
&& (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))
|| !vector_types_compatible_elements_p (type0, type1)))
{
binary_op_error (location, code, type0, type1);
gcc_rich_location richloc (location);
richloc.maybe_add_expr (orig_op0);
richloc.maybe_add_expr (orig_op1);
binary_op_error (&richloc, code, type0, type1);
return error_mark_node;
}
......@@ -11441,7 +11445,10 @@ build_binary_op (location_t location, enum tree_code code,
if (!result_type)
{
binary_op_error (location, code, TREE_TYPE (op0), TREE_TYPE (op1));
gcc_rich_location richloc (location);
richloc.maybe_add_expr (orig_op0);
richloc.maybe_add_expr (orig_op1);
binary_op_error (&richloc, code, TREE_TYPE (op0), TREE_TYPE (op1));
return error_mark_node;
}
......
2015-12-21 David Malcolm <dmalcolm@redhat.com>
* 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.
2015-12-20 Jason Merrill <jason@redhat.com>
PR c++/67411
......
......@@ -4908,7 +4908,13 @@ cp_build_binary_op (location_t location,
|| !vector_types_compatible_elements_p (type0, type1))
{
if (complain & tf_error)
binary_op_error (location, code, type0, type1);
{
/* "location" already embeds the locations of the
operands, so we don't need to add them separately
to richloc. */
rich_location richloc (line_table, location);
binary_op_error (&richloc, code, type0, type1);
}
return error_mark_node;
}
arithmetic_types_p = 1;
......@@ -4931,8 +4937,9 @@ cp_build_binary_op (location_t location,
if (!result_type)
{
if (complain & tf_error)
error ("invalid operands of types %qT and %qT to binary %qO",
TREE_TYPE (orig_op0), TREE_TYPE (orig_op1), code);
error_at (location,
"invalid operands of types %qT and %qT to binary %qO",
TREE_TYPE (orig_op0), TREE_TYPE (orig_op1), code);
return error_mark_node;
}
......
2015-12-21 David Malcolm <dmalcolm@redhat.com>
* 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.
2015-12-21 Claudiu Zissulescu <claziss@synopsys.com>
* gcc.target/arc/builtin_general.c: New test.
......
// { dg-options "-fdiagnostics-show-caret" }
// Adapted from https://gcc.gnu.org/wiki/ClangDiagnosticsComparison
typedef float __m128;
void test_1 ()
{
__m128 myvec[2];
int const *ptr;
myvec[1] / ptr; // { dg-error "invalid operands" }
/* { dg-begin-multiline-output "" }
myvec[1] / ptr;
~~~~~~~~~^~~~~
{ dg-end-multiline-output "" } */
}
struct s {};
struct t {};
extern struct s some_function (void);
extern struct t some_other_function (void);
int test_2 (void)
{
return (some_function ()
+ some_other_function ()); // { dg-error "no match for .operator" }
/* { dg-begin-multiline-output "" }
return (some_function ()
~~~~~~~~~~~~~~~~
+ some_other_function ());
^~~~~~~~~~~~~~~~~~~~~~~~
{ dg-end-multiline-output "" } */
}
int test_3 (struct s param_s, struct t param_t)
{
return param_s && param_t; // { dg-error "no match for .operator" }
/* { dg-begin-multiline-output "" }
return param_s && param_t;
~~~~~~~~^~~~~~~~~~
{ dg-end-multiline-output "" } */
}
/* { dg-options "-fdiagnostics-show-caret" } */
/* Adapted from https://gcc.gnu.org/wiki/ClangDiagnosticsComparison */
typedef float __m128;
void test_1 ()
{
__m128 myvec[2];
int const *ptr;
myvec[1]/ptr; /* { dg-error "invalid operands to binary /" } */
/* TODO: ideally we'd underline "ptr" as well.
{ dg-begin-multiline-output "" }
myvec[1]/ptr;
~~~~~~~~^
{ dg-end-multiline-output "" } */
}
struct s {};
struct t {};
extern struct s some_function (void);
extern struct t some_other_function (void);
int test_2 (void)
{
return (some_function ()
+ some_other_function ()); /* { dg-error "invalid operands to binary \+" } */
/* { dg-begin-multiline-output "" }
return (some_function ()
~~~~~~~~~~~~~~~~
+ some_other_function ());
^ ~~~~~~~~~~~~~~~~~~~~~~
{ dg-end-multiline-output "" } */
}
int test_3 (struct s param_s, struct t param_t)
{
return param_s + param_t; // { dg-error "invalid operands to binary \+" }
/* { dg-begin-multiline-output "" }
return param_s + param_t;
^
{ dg-end-multiline-output "" } */
/* TODO: ideally we'd underline both params here. */
}
......@@ -32,50 +32,6 @@
#include "gcc-rich-location.h"
#include "print-tree.h"
/*
Hack: fails with linker error:
./diagnostic_plugin_show_trees.so: undefined symbol: _ZN17gcc_rich_location8add_exprEP9tree_node
since nothing in the tree is using gcc_rich_location::add_expr yet.
I've tried various workarounds (adding DEBUG_FUNCTION to the
method, taking its address), but can't seem to fix it that way.
So as a nasty workaround, the following material is copied&pasted
from gcc-rich-location.c: */
static bool
get_range_for_expr (tree expr, location_range *r)
{
if (EXPR_HAS_RANGE (expr))
{
source_range sr = EXPR_LOCATION_RANGE (expr);
/* Do we have meaningful data? */
if (sr.m_start && sr.m_finish)
{
r->m_start = expand_location (sr.m_start);
r->m_finish = expand_location (sr.m_finish);
return true;
}
}
return false;
}
/* Add a range to the rich_location, covering expression EXPR. */
void
gcc_rich_location::add_expr (tree expr)
{
gcc_assert (expr);
location_range r;
r.m_show_caret_p = false;
if (get_range_for_expr (expr, &r))
add_range (&r);
}
/* FIXME: end of material taken from gcc-rich-location.c */
int plugin_is_GPL_compatible;
static void
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment