https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43486

--- Comment #11 from David Malcolm <dmalcolm at gcc dot gnu.org> ---
Author: dmalcolm
Date: Wed Jan 10 19:40:55 2018
New Revision: 256448

URL: https://gcc.gnu.org/viewcvs?rev=256448&root=gcc&view=rev
Log:
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.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/c-family/ChangeLog
    trunk/gcc/c-family/c-common.c
    trunk/gcc/c-family/c-common.h
    trunk/gcc/c-family/c-format.c
    trunk/gcc/c-family/c-pretty-print.c
    trunk/gcc/c-family/c-warn.c
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/call.c
    trunk/gcc/cp/cp-gimplify.c
    trunk/gcc/cp/cp-lang.c
    trunk/gcc/cp/cp-tree.h
    trunk/gcc/cp/cvt.c
    trunk/gcc/cp/error.c
    trunk/gcc/cp/except.c
    trunk/gcc/cp/mangle.c
    trunk/gcc/cp/parser.c
    trunk/gcc/cp/pt.c
    trunk/gcc/cp/tree.c
    trunk/gcc/cp/typeck.c
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/diagnostic/param-type-mismatch.C
    trunk/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C
    trunk/gcc/testsuite/g++.dg/warn/Wformat-1.C
    trunk/gcc/tree-core.h
    trunk/gcc/tree.c
    trunk/gcc/tree.h

Reply via email to