{
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
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);
}
\f
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;
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;
}
{
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
}
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)))
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:
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:
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);
}
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:
: 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)
: "%<__transaction_relaxed %> "
"without transactional memory support enabled"));
+ set_c_expr_source_range (&ret, loc, loc);
+
return ret;
}
{ 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);