From 0a1ab2b78887ae62c303340a136f11e7ebb3a71d Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 1 Dec 2015 14:27:11 -0500 Subject: [PATCH 17/20] FIXME: handle functional casts --- gcc/convert.c | 9 +++--- gcc/cp/parser.c | 34 ++++++++++++++++++---- .../g++.dg/plugin/diagnostic-test-expressions-1.C | 23 +++++++++++++++ 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/gcc/convert.c b/gcc/convert.c index e27a6fe..8fb8624 100644 --- a/gcc/convert.c +++ b/gcc/convert.c @@ -362,10 +362,11 @@ convert_to_real_1 (tree type, tree expr, bool fold_p) case REAL_TYPE: /* Ignore the conversion if we don't need to store intermediate results and neither type is a decimal float. */ - return build1 ((flag_float_store - || DECIMAL_FLOAT_TYPE_P (type) - || DECIMAL_FLOAT_TYPE_P (itype)) - ? CONVERT_EXPR : NOP_EXPR, type, expr); + return build1_loc (loc, + (flag_float_store + || DECIMAL_FLOAT_TYPE_P (type) + || DECIMAL_FLOAT_TYPE_P (itype)) + ? CONVERT_EXPR : NOP_EXPR, type, expr); case INTEGER_TYPE: case ENUMERAL_TYPE: diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 6f74c03..1af12ef 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -2437,7 +2437,7 @@ static void cp_parser_perform_template_parameter_access_checks (vec *); static tree cp_parser_single_declaration (cp_parser *, vec *, bool, bool, bool *); -static tree cp_parser_functional_cast +static cp_expr cp_parser_functional_cast (cp_parser *, tree); static tree cp_parser_save_member_function_body (cp_parser *, cp_decl_specifier_seq *, cp_declarator *, tree, bool); @@ -25487,14 +25487,16 @@ cp_parser_simple_cast_expression (cp_parser *parser) /* Parse a functional cast to TYPE. Returns an expression representing the cast. */ -static tree +static cp_expr cp_parser_functional_cast (cp_parser* parser, tree type) { vec *vec; tree expression_list; - tree cast; + cp_expr cast; bool nonconst_p; + location_t start_loc = input_location; + if (!type) type = error_mark_node; @@ -25506,9 +25508,21 @@ cp_parser_functional_cast (cp_parser* parser, tree type) CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1; if (TREE_CODE (type) == TYPE_DECL) type = TREE_TYPE (type); - return finish_compound_literal (type, expression_list, + + cast = finish_compound_literal (type, expression_list, tf_warning_or_error); - } + /* Create a location of the form: + type_name{i, f} + ^~~~~~~~~~~~~~~ + with caret == start at the start of the type name, + finishing at the closing brace. */ + location_t finish_loc + = get_finish (cp_lexer_previous_token (parser->lexer)->location); + location_t combined_loc = make_location (start_loc, start_loc, + finish_loc); + cast.set_location (combined_loc); + return cast; + } vec = cp_parser_parenthesized_expression_list (parser, non_attr, @@ -25534,6 +25548,16 @@ cp_parser_functional_cast (cp_parser* parser, tree type) && cp_parser_non_integral_constant_expression (parser, NIC_CONSTRUCTOR)) return error_mark_node; + + /* Create a location of the form: + float(i) + ^~~~~~~~ + with caret == start at the start of the type name, + finishing at the closing paren. */ + location_t finish_loc + = get_finish (cp_lexer_previous_token (parser->lexer)->location); + location_t combined_loc = make_location (start_loc, start_loc, finish_loc); + cast.set_location (combined_loc); return cast; } diff --git a/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C b/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C index 264beb7..b94e982 100644 --- a/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C +++ b/gcc/testsuite/g++.dg/plugin/diagnostic-test-expressions-1.C @@ -535,6 +535,29 @@ void test_cp_casts (base *ptr) { dg-end-multiline-output "" } */ } +struct s { int i; float f; }; + +void test_functional_casts (int i, float f) +{ + __emit_expression_range (0, float(i)); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, float(i)); + ^~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, int(f)); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, int(f)); + ^~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, s{i, f}); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, s{i, f}); + ^~~~~~~ + { dg-end-multiline-output "" } */ +} + void test_new (void) { __emit_expression_range (0, ::new base); /* { dg-warning "range" } */ -- 1.8.5.3