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
This commit is contained in:
parent
5f0b7c9548
commit
bef08b718f
5 changed files with 213 additions and 39 deletions
|
@ -1,3 +1,19 @@
|
|||
2015-11-17 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* 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 <kirill.yukhin@intel.com>
|
||||
|
||||
* c-parser.c (c_finish_omp_declare_simd): Look for
|
||||
|
|
100
gcc/c/c-parser.c
100
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
2015-11-17 David Malcolm <dmalcolm@redhat.com>
|
||||
|
||||
* 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 <msebor@redhat.com>
|
||||
|
||||
PR c++/68308
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -181,6 +181,8 @@ proc _build_multiline_regex { multiline index } {
|
|||
")" "\\)"
|
||||
"[" "\\["
|
||||
"]" "\\]"
|
||||
"{" "\\{"
|
||||
"}" "\\}"
|
||||
"." "\\."
|
||||
"\\" "\\\\"
|
||||
"?" "\\?"
|
||||
|
|
Loading…
Add table
Reference in a new issue