From bef08b718f9cacd17fb74fab77b125d2c92b7493 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Tue, 17 Nov 2015 20:09:56 +0000 Subject: [PATCH] Fix uninitialized src_range values for c_expr gcc/c/ChangeLog: * c-parser.c (set_c_expr_source_range): Bulletproof both overloaded implementations against NULL expr->value. (c_parser_braced_init): Set src_range for "ret" to a sane pair of values. (c_parser_unary_expression): Likewise when handling addresses of labels. (c_parser_postfix_expression): Likewise for statement expressions, for __FUNCTION__, __PRETTY_FUNCTION_ and __func__ keywords, for __builtin_va_arg, and for __builtin_offset_of. (c_parser_postfix_expression_after_paren_type): Initialize expr's src_range using the range of the braced initializer. (c_parser_transaction_expression): Set src_range for "ret" to a sane pair of values. gcc/testsuite/ChangeLog: * gcc.dg/plugin/diagnostic-test-expressions-1.c (vector): New macro. (test_braced_init): New function. (test_statement_expression): New function. (test_address_of_label): New function. (test_transaction_expressions): New function. (test_keywords): New function. (test_builtin_va_arg): New function. (test_builtin_offsetof): New function. * lib/multiline.exp (_build_multiline_regex): Escape braces. From-SVN: r230497 --- gcc/c/ChangeLog | 16 +++ gcc/c/c-parser.c | 100 +++++++++------ gcc/testsuite/ChangeLog | 13 ++ .../plugin/diagnostic-test-expressions-1.c | 121 ++++++++++++++++++ gcc/testsuite/lib/multiline.exp | 2 + 5 files changed, 213 insertions(+), 39 deletions(-) diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 38687715646..b561fa07cb0 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,19 @@ +2015-11-17 David Malcolm + + * c-parser.c (set_c_expr_source_range): Bulletproof both + overloaded implementations against NULL expr->value. + (c_parser_braced_init): Set src_range for "ret" to a sane pair of + values. + (c_parser_unary_expression): Likewise when handling addresses of + labels. + (c_parser_postfix_expression): Likewise for statement expressions, + for __FUNCTION__, __PRETTY_FUNCTION_ and __func__ keywords, for + __builtin_va_arg, and for __builtin_offset_of. + (c_parser_postfix_expression_after_paren_type): Initialize expr's + src_range using the range of the braced initializer. + (c_parser_transaction_expression): Set src_range for "ret" to a + sane pair of values. + 2015-11-16 Kirill Yukhin * c-parser.c (c_finish_omp_declare_simd): Look for diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index e63148e3330..7b10764a01e 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -65,7 +65,8 @@ set_c_expr_source_range (c_expr *expr, { expr->src_range.m_start = start; expr->src_range.m_finish = finish; - set_source_range (expr->value, start, finish); + if (expr->value) + set_source_range (expr->value, start, finish); } void @@ -73,7 +74,8 @@ set_c_expr_source_range (c_expr *expr, source_range src_range) { expr->src_range = src_range; - set_source_range (expr->value, src_range); + if (expr->value) + set_source_range (expr->value, src_range); } @@ -4268,7 +4270,8 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p) break; } } - if (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE)) + c_token *next_tok = c_parser_peek_token (parser); + if (next_tok->type != CPP_CLOSE_BRACE) { ret.value = error_mark_node; ret.original_code = ERROR_MARK; @@ -4278,9 +4281,11 @@ c_parser_braced_init (c_parser *parser, tree type, bool nested_p) obstack_free (&braced_init_obstack, NULL); return ret; } + location_t close_loc = next_tok->location; c_parser_consume_token (parser); ret = pop_init_level (brace_loc, 0, &braced_init_obstack); obstack_free (&braced_init_obstack, NULL); + set_c_expr_source_range (&ret, brace_loc, close_loc); return ret; } @@ -6723,6 +6728,8 @@ c_parser_unary_expression (c_parser *parser) { ret.value = finish_label_address_expr (c_parser_peek_token (parser)->value, op_loc); + set_c_expr_source_range (&ret, op_loc, + c_parser_peek_token (parser)->get_finish ()); c_parser_consume_token (parser); } else @@ -7366,11 +7373,13 @@ c_parser_postfix_expression (c_parser *parser) } stmt = c_begin_stmt_expr (); c_parser_compound_statement_nostart (parser); + location_t close_loc = c_parser_peek_token (parser)->location; c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); pedwarn (loc, OPT_Wpedantic, "ISO C forbids braced-groups within expressions"); expr.value = c_finish_stmt_expr (brace_loc, stmt); + set_c_expr_source_range (&expr, loc, close_loc); mark_exp_read (expr.value); } else if (c_token_starts_typename (c_parser_peek_2nd_token (parser))) @@ -7421,6 +7430,7 @@ c_parser_postfix_expression (c_parser *parser) expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword, c_parser_peek_token (parser)->value); + set_c_expr_source_range (&expr, loc, loc); c_parser_consume_token (parser); break; case RID_PRETTY_FUNCTION_NAME: @@ -7429,6 +7439,7 @@ c_parser_postfix_expression (c_parser *parser) expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword, c_parser_peek_token (parser)->value); + set_c_expr_source_range (&expr, loc, loc); c_parser_consume_token (parser); break; case RID_C99_FUNCTION_NAME: @@ -7437,45 +7448,51 @@ c_parser_postfix_expression (c_parser *parser) expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword, c_parser_peek_token (parser)->value); + set_c_expr_source_range (&expr, loc, loc); c_parser_consume_token (parser); break; case RID_VA_ARG: - c_parser_consume_token (parser); - if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) - { - expr.value = error_mark_node; - break; - } - e1 = c_parser_expr_no_commas (parser, NULL); - mark_exp_read (e1.value); - e1.value = c_fully_fold (e1.value, false, NULL); - if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) - { - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); - expr.value = error_mark_node; - break; - } - loc = c_parser_peek_token (parser)->location; - t1 = c_parser_type_name (parser); - c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, - "expected %<)%>"); - if (t1 == NULL) - { - expr.value = error_mark_node; - } - else - { - tree type_expr = NULL_TREE; - expr.value = c_build_va_arg (loc, e1.value, - groktypename (t1, &type_expr, NULL)); - if (type_expr) - { - expr.value = build2 (C_MAYBE_CONST_EXPR, - TREE_TYPE (expr.value), type_expr, - expr.value); - C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true; - } - } + { + location_t start_loc = loc; + c_parser_consume_token (parser); + if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) + { + expr.value = error_mark_node; + break; + } + e1 = c_parser_expr_no_commas (parser, NULL); + mark_exp_read (e1.value); + e1.value = c_fully_fold (e1.value, false, NULL); + if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>")) + { + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL); + expr.value = error_mark_node; + break; + } + loc = c_parser_peek_token (parser)->location; + t1 = c_parser_type_name (parser); + location_t end_loc = c_parser_peek_token (parser)->get_finish (); + c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, + "expected %<)%>"); + if (t1 == NULL) + { + expr.value = error_mark_node; + } + else + { + tree type_expr = NULL_TREE; + expr.value = c_build_va_arg (loc, e1.value, + groktypename (t1, &type_expr, NULL)); + if (type_expr) + { + expr.value = build2 (C_MAYBE_CONST_EXPR, + TREE_TYPE (expr.value), type_expr, + expr.value); + C_MAYBE_CONST_EXPR_NON_CONST (expr.value) = true; + } + set_c_expr_source_range (&expr, start_loc, end_loc); + } + } break; case RID_OFFSETOF: c_parser_consume_token (parser); @@ -7561,9 +7578,11 @@ c_parser_postfix_expression (c_parser *parser) } else c_parser_error (parser, "expected identifier"); + location_t end_loc = c_parser_peek_token (parser)->get_finish (); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); expr.value = fold_offsetof (offsetof_ref); + set_c_expr_source_range (&expr, loc, end_loc); } break; case RID_CHOOSE_EXPR: @@ -7951,6 +7970,7 @@ c_parser_postfix_expression_after_paren_type (c_parser *parser, : init.original_code == C_MAYBE_CONST_EXPR); non_const |= !type_expr_const; expr.value = build_compound_literal (start_loc, type, init.value, non_const); + set_c_expr_source_range (&expr, init.src_range); expr.original_code = ERROR_MARK; expr.original_type = NULL; if (type != error_mark_node && type_expr) @@ -17546,6 +17566,8 @@ c_parser_transaction_expression (c_parser *parser, enum rid keyword) : "%<__transaction_relaxed %> " "without transactional memory support enabled")); + set_c_expr_source_range (&ret, loc, loc); + return ret; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 69adb07627e..a1f14587d27 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2015-11-17 David Malcolm + + * gcc.dg/plugin/diagnostic-test-expressions-1.c (vector): New + macro. + (test_braced_init): New function. + (test_statement_expression): New function. + (test_address_of_label): New function. + (test_transaction_expressions): New function. + (test_keywords): New function. + (test_builtin_va_arg): New function. + (test_builtin_offsetof): New function. + * lib/multiline.exp (_build_multiline_regex): Escape braces. + 2015-11-17 Martin Sebor PR c++/68308 diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c index 5485aafec01..0d8c7c5fa10 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c @@ -397,6 +397,127 @@ void test_comma_operator (int a, int b) { dg-end-multiline-output "" } */ } +/* Braced initializers. ***************************************/ + +/* We can't test the ranges of these directly, since the underlying + tree nodes don't retain a location. However, we can test that they + have ranges during parsing by building compound expressions using + them, and verifying the ranges of the compound expressions. */ + +#define vector(elcount, type) \ +__attribute__((vector_size((elcount)*sizeof(type)))) type + +void test_braced_init (void) +{ + /* Verify start of range. */ + __emit_expression_range (0, (vector(4, float)){2., 2., 2., 2.} + 1); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, (vector(4, float)){2., 2., 2., 2.} + 1); + ~~~~~~~~~~~~~~~~~^~~ + { dg-end-multiline-output "" } */ + + /* Verify end of range. */ + __emit_expression_range (0, &(vector(4, float)){2., 2., 2., 2.}); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, &(vector(4, float)){2., 2., 2., 2.}); + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ +} + +/* Statement expressions. ***************************************/ + +void test_statement_expression (void) +{ + __emit_expression_range (0, ({ static int a; a; }) ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, ({ static int a; a; }) ); + ~^~~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ +} + +/* Other expressions. */ + +void test_address_of_label (void) +{ + label: + __emit_expression_range (0, &&label ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, &&label ); + ^~~~~~~ + { dg-end-multiline-output "" } */ +} + +void test_transaction_expressions (void) +{ + int i; + i = __transaction_atomic (42); /* { dg-error "without transactional memory support enabled" } */ +/* { dg-begin-multiline-output "" } + i = __transaction_atomic (42); + ^~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ + i = __transaction_relaxed (42); /* { dg-error "without transactional memory support enabled" } */ +/* { dg-begin-multiline-output "" } + i = __transaction_relaxed (42); + ^~~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ +} + +void test_keywords (int i) +{ + __emit_expression_range (0, __FUNCTION__[i] ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, __FUNCTION__[i] ); + ~~~~~~~~~~~~^~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, __PRETTY_FUNCTION__ ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, __PRETTY_FUNCTION__ ); + ^~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, __func__ ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, __func__ ); + ^~~~~~~~ + { dg-end-multiline-output "" } */ +} + +void test_builtin_va_arg (__builtin_va_list v) +{ + __emit_expression_range (0, __builtin_va_arg (v, int) ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, __builtin_va_arg (v, int) ); + ~~~~~~~~~~~~~~~~~~~~~^~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, __builtin_va_arg (v, int) + 1 ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, __builtin_va_arg (v, int) + 1 ); + ~~~~~~~~~~~~~~~~~~~~~~~~~~^~~ + { dg-end-multiline-output "" } */ +} + +struct s +{ + int f; +}; + +void test_builtin_offsetof (int i) +{ + __emit_expression_range (0, i + __builtin_offsetof (struct s, f) ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, i + __builtin_offsetof (struct s, f) ); + ~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + { dg-end-multiline-output "" } */ + + __emit_expression_range (0, __builtin_offsetof (struct s, f) + i ); /* { dg-warning "range" } */ +/* { dg-begin-multiline-output "" } + __emit_expression_range (0, __builtin_offsetof (struct s, f) + i ); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~ + { dg-end-multiline-output "" } */ +} + /* Examples of non-trivial expressions. ****************************/ extern double sqrt (double x); diff --git a/gcc/testsuite/lib/multiline.exp b/gcc/testsuite/lib/multiline.exp index eb721438b8f..c3d05064d56 100644 --- a/gcc/testsuite/lib/multiline.exp +++ b/gcc/testsuite/lib/multiline.exp @@ -181,6 +181,8 @@ proc _build_multiline_regex { multiline index } { ")" "\\)" "[" "\\[" "]" "\\]" + "{" "\\{" + "}" "\\}" "." "\\." "\\" "\\\\" "?" "\\?" -- 2.30.2