aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2018-12-19 15:15:42 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2018-12-19 15:15:42 +0000
commita14feb3c783fba6af8d66b8138214a3a313be5c5 (patch)
tree8077a5987ffd2b51526c4fb5914a366842927823 /gcc/c
parentdfd7fdca2ac17d8b823a16700525824ca312ade0 (diff)
downloadgcc-a14feb3c783fba6af8d66b8138214a3a313be5c5.zip
gcc-a14feb3c783fba6af8d66b8138214a3a313be5c5.tar.gz
gcc-a14feb3c783fba6af8d66b8138214a3a313be5c5.tar.bz2
C++: improvements to binary operator diagnostics (PR c++/87504)
The C frontend is able (where expression locations are available) to print problems with binary operators in 3-location form, labelling the types of the expressions: arg_0 op arg_1 ~~~~~ ^~ ~~~~~ | | | arg1 type arg0 type The C++ frontend currently just shows the combined location: arg_0 op arg_1 ~~~~~~^~~~~~~~ and fails to highlight where the subexpressions are, or their types. This patch introduces a op_location_t struct for handling the above operator-location vs combined-location split, and a new class binary_op_rich_location for displaying the above, so that the C++ frontend is able to use the more detailed 3-location form for type mismatches in binary operators, and for -Wtautological-compare (where types are not displayed). Both forms can be seen in this example: bad-binary-ops.C:69:20: error: no match for 'operator&&' (operand types are 's' and 't') 69 | return ns_4::foo && ns_4::inner::bar; | ~~~~~~~~~ ^~ ~~~~~~~~~~~~~~~~ | | | | s t bad-binary-ops.C:69:20: note: candidate: 'operator&&(bool, bool)' <built-in> 69 | return ns_4::foo && ns_4::inner::bar; | ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~ The patch also allows for some uses of macros in -Wtautological-compare, where both sides of the comparison have been spelled the same way, e.g.: Wtautological-compare-ranges.c:23:11: warning: self-comparison always evaluates to true [-Wtautological-compare] 23 | if (FOO == FOO); | ^~ gcc/c-family/ChangeLog: PR c++/87504 * c-common.h (warn_tautological_cmp): Convert 1st param from location_t to const op_location_t &. * c-warn.c (find_array_ref_with_const_idx_r): Call fold_for_warn when testing for INTEGER_CST. (warn_tautological_bitwise_comparison): Convert 1st param from location_t to const op_location_t &; use it to build a binary_op_rich_location, and use this. (spelled_the_same_p): New function. (warn_tautological_cmp): Convert 1st param from location_t to const op_location_t &. Warn for macro expansions if spelled_the_same_p. Use binary_op_rich_location. gcc/c/ChangeLog: PR c++/87504 * c-typeck.c (class maybe_range_label_for_tree_type_mismatch): Move from here to gcc-rich-location.h and gcc-rich-location.c. (build_binary_op): Use struct op_location_t and class binary_op_rich_location. gcc/cp/ChangeLog: PR c++/87504 * call.c (op_error): Convert 1st param from location_t to const op_location_t &. Use binary_op_rich_location for binary ops. (build_conditional_expr_1): Convert 1st param from location_t to const op_location_t &. (build_conditional_expr): Likewise. (build_new_op_1): Likewise. (build_new_op): Likewise. * cp-tree.h (build_conditional_expr): Likewise. (build_new_op): Likewise. (build_x_binary_op): Likewise. (cp_build_binary_op): Likewise. * parser.c (cp_parser_primary_expression): Build a location for id-expression nodes. (cp_parser_binary_expression): Use an op_location_t when calling build_x_binary_op. (cp_parser_operator): Build a location for user-defined literals. * typeck.c (build_x_binary_op): Convert 1st param from location_t to const op_location_t &. (cp_build_binary_op): Likewise. Use binary_op_rich_location. gcc/ChangeLog: PR c++/87504 * gcc-rich-location.c (maybe_range_label_for_tree_type_mismatch::get_text): Move here from c/c-typeck.c. (binary_op_rich_location::binary_op_rich_location): New ctor. (binary_op_rich_location::use_operator_loc_p): New function. * gcc-rich-location.h (class maybe_range_label_for_tree_type_mismatch)): Move here from c/c-typeck.c. (struct op_location_t): New forward decl. (class binary_op_rich_location): New class. * tree.h (struct op_location_t): New struct. gcc/testsuite/ChangeLog: * c-c++-common/Wtautological-compare-ranges.c: New test. * g++.dg/cpp0x/pr51420.C: Add -fdiagnostics-show-caret and update expected output. * g++.dg/diagnostic/bad-binary-ops.C: Update expected output from 1-location form to 3-location form, with labelling of ranges with types. Add examples of id-expression nodes with namespaces. * g++.dg/diagnostic/param-type-mismatch-2.C: Likewise. From-SVN: r267273
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog8
-rw-r--r--gcc/c/c-typeck.c41
2 files changed, 11 insertions, 38 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 294442c..3232614 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,11 @@
+2018-12-19 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/87504
+ * c-typeck.c (class maybe_range_label_for_tree_type_mismatch):
+ Move from here to gcc-rich-location.h and gcc-rich-location.c.
+ (build_binary_op): Use struct op_location_t and
+ class binary_op_rich_location.
+
2018-12-11 Jakub Jelinek <jakub@redhat.com>
PR sanitizer/88426
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 1a89727..72ecd46 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -11313,38 +11313,6 @@ build_vec_cmp (tree_code code, tree type,
return build3 (VEC_COND_EXPR, type, cmp, minus_one_vec, zero_vec);
}
-/* Subclass of range_label for labelling the type of EXPR when reporting
- a type mismatch between EXPR and OTHER_EXPR.
- Either or both of EXPR and OTHER_EXPR could be NULL. */
-
-class maybe_range_label_for_tree_type_mismatch : public range_label
-{
- public:
- maybe_range_label_for_tree_type_mismatch (tree expr, tree other_expr)
- : m_expr (expr), m_other_expr (other_expr)
- {
- }
-
- label_text get_text (unsigned range_idx) const FINAL OVERRIDE
- {
- if (m_expr == NULL_TREE
- || !EXPR_P (m_expr))
- return label_text (NULL, false);
- tree expr_type = TREE_TYPE (m_expr);
-
- tree other_type = NULL_TREE;
- if (m_other_expr && EXPR_P (m_other_expr))
- other_type = TREE_TYPE (m_other_expr);
-
- range_label_for_type_mismatch inner (expr_type, other_type);
- return inner.get_text (range_idx);
- }
-
- private:
- tree m_expr;
- tree m_other_expr;
-};
-
/* Build a binary-operation expression without default conversions.
CODE is the kind of expression to build.
LOCATION is the operator's location.
@@ -12475,12 +12443,9 @@ build_binary_op (location_t location, enum tree_code code,
if (!result_type)
{
- gcc_rich_location richloc (location);
- maybe_range_label_for_tree_type_mismatch
- label_for_op0 (orig_op0, orig_op1),
- label_for_op1 (orig_op1, orig_op0);
- richloc.maybe_add_expr (orig_op0, &label_for_op0);
- richloc.maybe_add_expr (orig_op1, &label_for_op1);
+ /* Favor showing any expression locations that are available. */
+ op_location_t oploc (location, UNKNOWN_LOCATION);
+ binary_op_rich_location richloc (oploc, orig_op0, orig_op1, true);
binary_op_error (&richloc, code, TREE_TYPE (op0), TREE_TYPE (op1));
return error_mark_node;
}