diff options
author | David Malcolm <dmalcolm@redhat.com> | 2018-01-10 19:40:55 +0000 |
---|---|---|
committer | David Malcolm <dmalcolm@gcc.gnu.org> | 2018-01-10 19:40:55 +0000 |
commit | 9a004410d9f64d658864a899ab911ae9a31c444c (patch) | |
tree | 74d2d62696c26cee3eb63313868f3150f67c4aa3 /gcc/tree.h | |
parent | 60d87d86163186669af4b0f493be462e2aadca77 (diff) | |
download | gcc-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/tree.h')
-rw-r--r-- | gcc/tree.h | 47 |
1 files changed, 47 insertions, 0 deletions
@@ -483,6 +483,12 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, #define STRIP_USELESS_TYPE_CONVERSION(EXP) \ (EXP) = tree_ssa_strip_useless_type_conversions (EXP) +/* Remove any VIEW_CONVERT_EXPR or NON_LVALUE_EXPR that's purely + in use to provide a location_t. */ + +#define STRIP_ANY_LOCATION_WRAPPER(EXP) \ + (EXP) = tree_strip_any_location_wrapper (CONST_CAST_TREE (EXP)) + /* Nonzero if TYPE represents a vector type. */ #define VECTOR_TYPE_P(TYPE) (TREE_CODE (TYPE) == VECTOR_TYPE) @@ -1180,6 +1186,8 @@ get_expr_source_range (tree expr) extern void protected_set_expr_location (tree, location_t); +extern tree maybe_wrap_with_location (tree, location_t); + /* In a TARGET_EXPR node. */ #define TARGET_EXPR_SLOT(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 0) #define TARGET_EXPR_INITIAL(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 1) @@ -3726,6 +3734,45 @@ valid_vector_subparts_p (poly_uint64 subparts) return true; } +/* In NON_LVALUE_EXPR and VIEW_CONVERT_EXPR, set when this node is merely a + wrapper added to express a location_t on behalf of the node's child + (e.g. by maybe_wrap_with_location). */ + +#define EXPR_LOCATION_WRAPPER_P(NODE) \ + (TREE_CHECK2(NODE, NON_LVALUE_EXPR, VIEW_CONVERT_EXPR)->base.public_flag) + +/* Test if EXP is merely a wrapper node, added to express a location_t + on behalf of the node's child (e.g. by maybe_wrap_with_location). */ + +inline bool +location_wrapper_p (const_tree exp) +{ + /* A wrapper node has code NON_LVALUE_EXPR or VIEW_CONVERT_EXPR, and + the flag EXPR_LOCATION_WRAPPER_P is set. + It normally has the same type as its operand, but it can have a + different one if the type of the operand has changed (e.g. when + merging duplicate decls). + + NON_LVALUE_EXPR is used for wrapping constants, apart from STRING_CST. + VIEW_CONVERT_EXPR is used for wrapping non-constants and STRING_CST. */ + if ((TREE_CODE (exp) == NON_LVALUE_EXPR + || TREE_CODE (exp) == VIEW_CONVERT_EXPR) + && EXPR_LOCATION_WRAPPER_P (exp)) + return true; + return false; +} + +/* Implementation of STRIP_ANY_LOCATION_WRAPPER. */ + +inline tree +tree_strip_any_location_wrapper (tree exp) +{ + if (location_wrapper_p (exp)) + return TREE_OPERAND (exp, 0); + else + return exp; +} + #define error_mark_node global_trees[TI_ERROR_MARK] #define intQI_type_node global_trees[TI_INTQI_TYPE] |