aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-family
diff options
context:
space:
mode:
authorDavid Malcolm <dmalcolm@redhat.com>2018-01-10 19:40:55 +0000
committerDavid Malcolm <dmalcolm@gcc.gnu.org>2018-01-10 19:40:55 +0000
commit9a004410d9f64d658864a899ab911ae9a31c444c (patch)
tree74d2d62696c26cee3eb63313868f3150f67c4aa3 /gcc/c-family
parent60d87d86163186669af4b0f493be462e2aadca77 (diff)
downloadgcc-9a004410d9f64d658864a899ab911ae9a31c444c.zip
gcc-9a004410d9f64d658864a899ab911ae9a31c444c.tar.gz
gcc-9a004410d9f64d658864a899ab911ae9a31c444c.tar.bz2
Preserving locations for variable-uses and constants (PR c++/43486)
This patch implements location wrapper nodes, preserving source locations of the uses of variables and constants in various places in the C++ frontend: at the arguments at callsites, and for typeid, alignof, sizeof, and offsetof. For example, it allows the C++ FE to underline the pertinent argument for mismatching calls, for such expressions, improving: extern int callee (int one, const char *two, float three); int caller (int first, int second, float third) { return callee (first, second, third); } from test.cc: In function 'int caller(int, int, float)': test.cc:5:38: error: invalid conversion from 'int' to 'const char*' [-fpermissive] return callee (first, second, third); ^ test.cc:1:41: note: initializing argument 2 of 'int callee(int, const char*, float)' extern int callee (int one, const char *two, float three); ~~~~~~~~~~~~^~~ to: test.cc: In function 'int caller(int, int, float)': test.cc:5:25: error: invalid conversion from 'int' to 'const char*' [-fpermissive] return callee (first, second, third); ^~~~~~ test.cc:1:41: note: initializing argument 2 of 'int callee(int, const char*, float)' extern int callee (int one, const char *two, float three); ~~~~~~~~~~~~^~~ This is the combination of the following patches: "[PATCH 01/14] C++: preserve locations within build_address" https://gcc.gnu.org/ml/gcc-patches/2017-11/msg00883.html "[PATCH v2.4 of 02/14] Support for adding and stripping location_t wrapper nodes" https://gcc.gnu.org/ml/gcc-patches/2018-01/msg00591.html "[PATCH] Eliminate location wrappers in tree_nop_conversion/STRIP_NOPS" https://gcc.gnu.org/ml/gcc-patches/2017-12/msg01330.html "[PATCH v4 of 03/14] C++: add location_t wrapper nodes during parsing (minimal impl)" https://gcc.gnu.org/ml/gcc-patches/2018-01/msg00660.html "[PATCH 04/14] Update testsuite to show improvements" https://gcc.gnu.org/ml/gcc-patches/2017-11/msg00891.html "[v3 of 05/14] C++: handle locations wrappers when calling warn_for_memset" https://gcc.gnu.org/ml/gcc-patches/2017-12/msg01378.html "[PATCH 07/14] reject_gcc_builtin: strip any location wrappers" https://gcc.gnu.org/ml/gcc-patches/2017-11/msg00886.html "[v3 of PATCH 08/14] cp/tree.c: strip location wrappers in lvalue_kind" https://gcc.gnu.org/ml/gcc-patches/2017-12/msg01433.html "[PATCH 09/14] Strip location wrappers in null_ptr_cst_p" https://gcc.gnu.org/ml/gcc-patches/2017-11/msg00888.html "[PATCH 11/14] Handle location wrappers in string_conv_p" https://gcc.gnu.org/ml/gcc-patches/2017-11/msg00890.html "[PATCH 12/14] C++: introduce null_node_p" https://gcc.gnu.org/ml/gcc-patches/2017-11/msg00894.html "[v3 of PATCH 13/14] c-format.c: handle location wrappers" https://gcc.gnu.org/ml/gcc-patches/2017-12/msg01494.html "[PATCH 14/14] pp_c_cast_expression: don't print casts for location wrappers" https://gcc.gnu.org/ml/gcc-patches/2017-11/msg00893.html "[v3 of PATCH 15/14] Use fold_for_warn in get_atomic_generic_size" https://gcc.gnu.org/ml/gcc-patches/2017-12/msg01380.html "[PATCH] Add selftest for "fold_for_warn (error_mark_node)"" https://gcc.gnu.org/ml/gcc-patches/2017-12/msg01385.html gcc/c-family/ChangeLog: PR c++/43486 * c-common.c: Include "selftest.h". (get_atomic_generic_size): Perform the test for integral type before the range test for any integer constant, fixing indentation of braces. Call fold_for_warn before testing for an INTEGER_CST. (reject_gcc_builtin): Strip any location wrapper from EXPR. (selftest::test_fold_for_warn): New function. (selftest::c_common_c_tests): New function. (selftest::c_family_tests): Call it, and selftest::c_pretty_print_c_tests. * c-common.h (selftest::c_pretty_print_c_tests): New decl. * c-format.c (check_format_arg): Convert VAR_P check to a fold_for_warn. * c-pretty-print.c: Include "selftest.h". (pp_c_cast_expression): Don't print casts for location wrappers. (selftest::assert_c_pretty_printer_output): New function. (ASSERT_C_PRETTY_PRINTER_OUTPUT): New macro. (selftest::test_location_wrappers): New function. (selftest::c_pretty_print_c_tests): New function. * c-warn.c (warn_for_memset): Call fold_for_warn on the arguments. gcc/cp/ChangeLog: PR c++/43486 * call.c (null_ptr_cst_p): Strip location wrappers when converting from '0' to a pointer type in C++11 onwards. (conversion_null_warnings): Replace comparison with null_node with call to null_node_p. (build_over_call): Likewise. * cp-gimplify.c (cp_fold): Remove the early bailout when processing_template_decl. * cp-lang.c (selftest::run_cp_tests): Call selftest::cp_pt_c_tests and selftest::cp_tree_c_tests. * cp-tree.h (cp_expr::maybe_add_location_wrapper): New method. (selftest::run_cp_tests): Move decl to bottom of file. (null_node_p): New inline function. (selftest::cp_pt_c_tests): New decl. (selftest::cp_tree_c_tests): New decl. * cvt.c (build_expr_type_conversion): Replace comparison with null_node with call to null_node_p. * error.c (args_to_string): Likewise. * except.c (build_throw): Likewise. * mangle.c (write_expression): Skip location wrapper nodes. * parser.c (literal_integer_zerop): New function. (cp_parser_postfix_expression): Call maybe_add_location_wrapper on the result for RID_TYPEID. Pass true for new "wrap_locations_p" param of cp_parser_parenthesized_expression_list. When calling warn_for_memset, replace integer_zerop calls with literal_integer_zerop, eliminating the double logical negation cast to bool. Eliminate the special-casing for CONST_DECL in favor of the fold_for_warn within warn_for_memset. (cp_parser_parenthesized_expression_list): Add "wrap_locations_p" param, defaulting to false. Convert "expr" to a cp_expr, and call maybe_add_location_wrapper on it when wrap_locations_p is true. (cp_parser_unary_expression): Call maybe_add_location_wrapper on the result for RID_ALIGNOF and RID_SIZEOF. (cp_parser_builtin_offsetof): Likewise. * pt.c: Include "selftest.h". (tsubst_copy): Handle location wrappers. (tsubst_copy_and_build): Likewise. (build_non_dependent_expr): Likewise. (selftest::test_build_non_dependent_expr): New function. (selftest::cp_pt_c_tests): New function. * tree.c: Include "selftest.h". (lvalue_kind): Handle VIEW_CONVERT_EXPR location wrapper nodes. (selftest::test_lvalue_kind): New function. (selftest::cp_tree_c_tests): New function. * typeck.c (string_conv_p): Strip any location wrapper from "exp". (cp_build_binary_op): Replace comparison with null_node with call to null_node_p. (build_address): Use location of operand when building address expression. gcc/testsuite/ChangeLog: PR c++/43486 * g++.dg/diagnostic/param-type-mismatch.C: Update expected results to reflect that the arguments are correctly underlined. * g++.dg/plugin/diagnostic-test-expressions-1.C: Add test coverage for globals, params, locals and literals. (test_sizeof): Directly test the location of "sizeof", rather than when used in compound expressions. (test_alignof): Likewise for "alignof". (test_string_literals): Likewise for string literals. (test_numeric_literals): Likewise for numeric literals. (test_builtin_offsetof): Likewise for "__builtin_offsetof". (test_typeid): Likewise for typeid. (test_unary_plus): New. * g++.dg/warn/Wformat-1.C: Add tests of pointer arithmetic on format strings. gcc/ChangeLog: PR c++/43486 * tree-core.h: Document EXPR_LOCATION_WRAPPER_P's usage of "public_flag". * tree.c (tree_nop_conversion): Return true for location wrapper nodes. (maybe_wrap_with_location): New function. (selftest::check_strip_nops): New function. (selftest::test_location_wrappers): New function. (selftest::tree_c_tests): Call it. * tree.h (STRIP_ANY_LOCATION_WRAPPER): New macro. (maybe_wrap_with_location): New decl. (EXPR_LOCATION_WRAPPER_P): New macro. (location_wrapper_p): New inline function. (tree_strip_any_location_wrapper): New inline function. From-SVN: r256448
Diffstat (limited to 'gcc/c-family')
-rw-r--r--gcc/c-family/ChangeLog23
-rw-r--r--gcc/c-family/c-common.c39
-rw-r--r--gcc/c-family/c-common.h1
-rw-r--r--gcc/c-family/c-format.c10
-rw-r--r--gcc/c-family/c-pretty-print.c66
-rw-r--r--gcc/c-family/c-warn.c3
6 files changed, 126 insertions, 16 deletions
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index e79d985..d6b6085 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,26 @@
+2018-01-10 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/43486
+ * c-common.c: Include "selftest.h".
+ (get_atomic_generic_size): Perform the test for integral type
+ before the range test for any integer constant, fixing indentation
+ of braces. Call fold_for_warn before testing for an INTEGER_CST.
+ (reject_gcc_builtin): Strip any location wrapper from EXPR.
+ (selftest::test_fold_for_warn): New function.
+ (selftest::c_common_c_tests): New function.
+ (selftest::c_family_tests): Call it, and
+ selftest::c_pretty_print_c_tests.
+ * c-common.h (selftest::c_pretty_print_c_tests): New decl.
+ * c-format.c (check_format_arg): Convert VAR_P check to a
+ fold_for_warn.
+ * c-pretty-print.c: Include "selftest.h".
+ (pp_c_cast_expression): Don't print casts for location wrappers.
+ (selftest::assert_c_pretty_printer_output): New function.
+ (ASSERT_C_PRETTY_PRINTER_OUTPUT): New macro.
+ (selftest::test_location_wrappers): New function.
+ (selftest::c_pretty_print_c_tests): New function.
+ * c-warn.c (warn_for_memset): Call fold_for_warn on the arguments.
+
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 87bd326..097d192 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimplify.h"
#include "substring-locations.h"
#include "spellcheck.h"
+#include "selftest.h"
cpp_reader *parse_in; /* Declared in c-pragma.h. */
@@ -6737,8 +6738,15 @@ get_atomic_generic_size (location_t loc, tree function,
for (x = n_param - n_model ; x < n_param; x++)
{
tree p = (*params)[x];
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (p)))
+ {
+ error_at (loc, "non-integer memory model argument %d of %qE", x + 1,
+ function);
+ return 0;
+ }
+ p = fold_for_warn (p);
if (TREE_CODE (p) == INTEGER_CST)
- {
+ {
/* memmodel_base masks the low 16 bits, thus ignore any bits above
it by using TREE_INT_CST_LOW instead of tree_to_*hwi. Those high
bits will be checked later during expansion in target specific
@@ -6748,14 +6756,7 @@ get_atomic_generic_size (location_t loc, tree function,
"invalid memory model argument %d of %qE", x + 1,
function);
}
- else
- if (!INTEGRAL_TYPE_P (TREE_TYPE (p)))
- {
- error_at (loc, "non-integer memory model argument %d of %qE", x + 1,
- function);
- return 0;
- }
- }
+ }
return size_0;
}
@@ -7846,6 +7847,8 @@ reject_gcc_builtin (const_tree expr, location_t loc /* = UNKNOWN_LOCATION */)
if (TREE_CODE (expr) == ADDR_EXPR)
expr = TREE_OPERAND (expr, 0);
+ STRIP_ANY_LOCATION_WRAPPER (expr);
+
if (TREE_TYPE (expr)
&& TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE
&& TREE_CODE (expr) == FUNCTION_DECL
@@ -8187,12 +8190,30 @@ maybe_suggest_missing_token_insertion (rich_location *richloc,
namespace selftest {
+/* Verify that fold_for_warn on error_mark_node is safe. */
+
+static void
+test_fold_for_warn ()
+{
+ ASSERT_EQ (error_mark_node, fold_for_warn (error_mark_node));
+}
+
+/* Run all of the selftests within this file. */
+
+static void
+c_common_c_tests ()
+{
+ test_fold_for_warn ();
+}
+
/* Run all of the tests within c-family. */
void
c_family_tests (void)
{
+ c_common_c_tests ();
c_format_c_tests ();
+ c_pretty_print_c_tests ();
c_spellcheck_cc_tests ();
}
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 00bfe59..d090881 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -1450,6 +1450,7 @@ namespace selftest {
/* Declarations for specific families of tests within c-family,
by source file, in alphabetical order. */
extern void c_format_c_tests (void);
+ extern void c_pretty_print_c_tests (void);
extern void c_spellcheck_cc_tests (void);
/* The entrypoint for running all of the above tests. */
diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index e071145..7a69d5a 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -1536,12 +1536,10 @@ check_format_arg (void *ctx, tree format_tree,
location_t fmt_param_loc = EXPR_LOC_OR_LOC (format_tree, input_location);
- if (VAR_P (format_tree))
- {
- /* Pull out a constant value if the front end didn't. */
- format_tree = decl_constant_value (format_tree);
- STRIP_NOPS (format_tree);
- }
+ /* Pull out a constant value if the front end didn't, and handle location
+ wrappers. */
+ format_tree = fold_for_warn (format_tree);
+ STRIP_NOPS (format_tree);
if (integer_zerop (format_tree))
{
diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index 6e4f85c..c9dd8ae 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/gcc/c-family/c-pretty-print.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "attribs.h"
#include "intl.h"
#include "tree-pretty-print.h"
+#include "selftest.h"
/* The pretty-printer code is primarily designed to closely follow
(GNU) C and C++ grammars. That is to be contrasted with spaghetti
@@ -1809,7 +1810,8 @@ pp_c_cast_expression (c_pretty_printer *pp, tree e)
case FIX_TRUNC_EXPR:
CASE_CONVERT:
case VIEW_CONVERT_EXPR:
- pp_c_type_cast (pp, TREE_TYPE (e));
+ if (!location_wrapper_p (e))
+ pp_c_type_cast (pp, TREE_TYPE (e));
pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
break;
@@ -2400,3 +2402,65 @@ pp_c_tree_decl_identifier (c_pretty_printer *pp, tree t)
pp_c_identifier (pp, name);
}
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* Selftests for pretty-printing trees. */
+
+/* Verify that EXPR printed by c_pretty_printer is EXPECTED, using
+ LOC as the effective location for any failures. */
+
+static void
+assert_c_pretty_printer_output (const location &loc, const char *expected,
+ tree expr)
+{
+ c_pretty_printer pp;
+ pp.expression (expr);
+ ASSERT_STREQ_AT (loc, expected, pp_formatted_text (&pp));
+}
+
+/* Helper function for calling assert_c_pretty_printer_output.
+ This is to avoid having to write SELFTEST_LOCATION. */
+
+#define ASSERT_C_PRETTY_PRINTER_OUTPUT(EXPECTED, EXPR) \
+ SELFTEST_BEGIN_STMT \
+ assert_c_pretty_printer_output ((SELFTEST_LOCATION), \
+ (EXPECTED), \
+ (EXPR)); \
+ SELFTEST_END_STMT
+
+/* Verify that location wrappers don't show up in pretty-printed output. */
+
+static void
+test_location_wrappers ()
+{
+ /* VAR_DECL. */
+ tree id = get_identifier ("foo");
+ tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, id,
+ integer_type_node);
+ tree wrapped_decl = maybe_wrap_with_location (decl, BUILTINS_LOCATION);
+ ASSERT_NE (wrapped_decl, decl);
+ ASSERT_C_PRETTY_PRINTER_OUTPUT ("foo", decl);
+ ASSERT_C_PRETTY_PRINTER_OUTPUT ("foo", wrapped_decl);
+
+ /* INTEGER_CST. */
+ tree int_cst = build_int_cst (integer_type_node, 42);
+ tree wrapped_cst = maybe_wrap_with_location (int_cst, BUILTINS_LOCATION);
+ ASSERT_NE (wrapped_cst, int_cst);
+ ASSERT_C_PRETTY_PRINTER_OUTPUT ("42", int_cst);
+ ASSERT_C_PRETTY_PRINTER_OUTPUT ("42", wrapped_cst);
+}
+
+/* Run all of the selftests within this file. */
+
+void
+c_pretty_print_c_tests ()
+{
+ test_location_wrappers ();
+}
+
+} // namespace selftest
+
+#endif /* CHECKING_P */
diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c
index 33cae8b..7d87c45 100644
--- a/gcc/c-family/c-warn.c
+++ b/gcc/c-family/c-warn.c
@@ -1868,6 +1868,9 @@ void
warn_for_memset (location_t loc, tree arg0, tree arg2,
int literal_zero_mask)
{
+ arg0 = fold_for_warn (arg0);
+ arg2 = fold_for_warn (arg2);
+
if (warn_memset_transposed_args
&& integer_zerop (arg2)
&& (literal_zero_mask & (1 << 2)) != 0