+2008-09-01 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree.c (protected_set_expr_location): New.
+ * tree.h (protected_set_expr_location): New prototype.
+ * c-tree.h (build_array_ref): Add argument.
+ (parser_build_unary_op): Same.
+ * c-typeck.c (build_indirect_ref): Handle new location argument.
+ (build_array_ref): Same.
+ (parser_build_unary_op): Same.
+ * gimplify.c (gimplify_asm_expr): Set input_location before calling
+ error.
+ * c-omp.c (c_finish_omp_atomic): Pass location when calling
+ build_indirect_ref.
+ * c-common.c (finish_label_address_expr): Handle new location
+ argument.
+ * c-common.h (build_indirect_ref): Add argument.
+ (finish_label_address_expr): Same.
+ * c-parser.c (c_parser_unary_expression): Pass location to build
+ functions.
+ (c_parser_postfix_expression): Same.
+
2008-09-01 Paul Brook <paul@codesourcery.com>
* config/arm/arm.md: Include cortex-r4f.md.
}
/* Finish an expression taking the address of LABEL (an
- IDENTIFIER_NODE). Returns an expression for the address. */
+ IDENTIFIER_NODE). Returns an expression for the address.
+
+ LOC is the location for the expression returned. */
tree
-finish_label_address_expr (tree label)
+finish_label_address_expr (tree label, location_t loc)
{
tree result;
/* The current function in not necessarily uninlinable.
Computed gotos are incompatible with inlining, but the value
here could be used only in a diagnostic, for example. */
+ protected_set_expr_location (result, loc);
}
return result;
extern tree pushdecl_top_level (tree);
extern tree pushdecl (tree);
extern tree build_modify_expr (tree, enum tree_code, tree);
-extern tree build_indirect_ref (tree, const char *);
+extern tree build_indirect_ref (tree, const char *, location_t);
extern int c_expand_decl (tree);
extern tree resolve_overloaded_builtin (tree, tree);
-extern tree finish_label_address_expr (tree);
+extern tree finish_label_address_expr (tree, location_t);
/* Same function prototype, but the C and C++ front ends have
different implementations. Used in c-common.c. */
tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
}
- lhs = build_indirect_ref (addr, NULL);
+ lhs = build_indirect_ref (addr, NULL, EXPR_LOCATION (addr));
/* There are lots of warnings, errors, and conversions that need to happen
in the course of interpreting a statement. Use the normal mechanisms
{
int ext;
struct c_expr ret, op;
+ location_t loc = c_parser_peek_token (parser)->location;
switch (c_parser_peek_token (parser)->type)
{
case CPP_PLUS_PLUS:
c_parser_consume_token (parser);
op = c_parser_cast_expression (parser, NULL);
op = default_function_array_conversion (op);
- return parser_build_unary_op (PREINCREMENT_EXPR, op);
+ return parser_build_unary_op (PREINCREMENT_EXPR, op, loc);
case CPP_MINUS_MINUS:
c_parser_consume_token (parser);
op = c_parser_cast_expression (parser, NULL);
op = default_function_array_conversion (op);
- return parser_build_unary_op (PREDECREMENT_EXPR, op);
+ return parser_build_unary_op (PREDECREMENT_EXPR, op, loc);
case CPP_AND:
c_parser_consume_token (parser);
return parser_build_unary_op (ADDR_EXPR,
- c_parser_cast_expression (parser, NULL));
+ c_parser_cast_expression (parser, NULL),
+ loc);
case CPP_MULT:
c_parser_consume_token (parser);
op = c_parser_cast_expression (parser, NULL);
op = default_function_array_conversion (op);
- ret.value = build_indirect_ref (op.value, "unary *");
+ ret.value = build_indirect_ref (op.value, "unary *", loc);
ret.original_code = ERROR_MARK;
return ret;
case CPP_PLUS:
c_parser_consume_token (parser);
op = c_parser_cast_expression (parser, NULL);
op = default_function_array_conversion (op);
- return parser_build_unary_op (CONVERT_EXPR, op);
+ return parser_build_unary_op (CONVERT_EXPR, op, loc);
case CPP_MINUS:
c_parser_consume_token (parser);
op = c_parser_cast_expression (parser, NULL);
op = default_function_array_conversion (op);
- return parser_build_unary_op (NEGATE_EXPR, op);
+ return parser_build_unary_op (NEGATE_EXPR, op, loc);
case CPP_COMPL:
c_parser_consume_token (parser);
op = c_parser_cast_expression (parser, NULL);
op = default_function_array_conversion (op);
- return parser_build_unary_op (BIT_NOT_EXPR, op);
+ return parser_build_unary_op (BIT_NOT_EXPR, op, loc);
case CPP_NOT:
c_parser_consume_token (parser);
op = c_parser_cast_expression (parser, NULL);
op = default_function_array_conversion (op);
- return parser_build_unary_op (TRUTH_NOT_EXPR, op);
+ return parser_build_unary_op (TRUTH_NOT_EXPR, op, loc);
case CPP_AND_AND:
/* Refer to the address of a label as a pointer. */
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_NAME))
{
ret.value = finish_label_address_expr
- (c_parser_peek_token (parser)->value);
+ (c_parser_peek_token (parser)->value, loc);
c_parser_consume_token (parser);
}
else
c_parser_consume_token (parser);
op = c_parser_cast_expression (parser, NULL);
op = default_function_array_conversion (op);
- return parser_build_unary_op (REALPART_EXPR, op);
+ return parser_build_unary_op (REALPART_EXPR, op, loc);
case RID_IMAGPART:
c_parser_consume_token (parser);
op = c_parser_cast_expression (parser, NULL);
op = default_function_array_conversion (op);
- return parser_build_unary_op (IMAGPART_EXPR, op);
+ return parser_build_unary_op (IMAGPART_EXPR, op, loc);
default:
return c_parser_postfix_expression (parser);
}
else
{
tree idx;
+ loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
idx = c_parser_expression (parser).value;
c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
"expected %<]%>");
- offsetof_ref = build_array_ref (offsetof_ref, idx);
+ offsetof_ref = build_array_ref (offsetof_ref, idx, loc);
}
}
}
struct c_expr expr)
{
tree ident, idx, exprlist;
+ location_t loc = c_parser_peek_token (parser)->location;
while (true)
{
switch (c_parser_peek_token (parser)->type)
{
case CPP_OPEN_SQUARE:
/* Array reference. */
+ loc = c_parser_peek_token (parser)->location;
c_parser_consume_token (parser);
idx = c_parser_expression (parser).value;
c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
"expected %<]%>");
- expr.value = build_array_ref (expr.value, idx);
+ expr.value = build_array_ref (expr.value, idx, loc);
expr.original_code = ERROR_MARK;
break;
case CPP_OPEN_PAREN:
}
c_parser_consume_token (parser);
expr.value = build_component_ref (build_indirect_ref (expr.value,
- "->"), ident);
+ "->", loc),
+ ident);
expr.original_code = ERROR_MARK;
break;
case CPP_PLUS_PLUS:
extern struct c_expr default_function_array_conversion (struct c_expr);
extern tree composite_type (tree, tree);
extern tree build_component_ref (tree, tree);
-extern tree build_array_ref (tree, tree);
+extern tree build_array_ref (tree, tree, location_t);
extern tree build_external_ref (tree, int, location_t);
extern void pop_maybe_used (bool);
extern struct c_expr c_expr_sizeof_expr (struct c_expr);
extern struct c_expr c_expr_sizeof_type (struct c_type_name *);
-extern struct c_expr parser_build_unary_op (enum tree_code, struct c_expr);
+extern struct c_expr parser_build_unary_op (enum tree_code, struct c_expr,
+ location_t);
extern struct c_expr parser_build_binary_op (enum tree_code, struct c_expr,
struct c_expr);
extern tree build_conditional_expr (tree, tree, tree);
\f
/* Given an expression PTR for a pointer, return an expression
for the value pointed to.
- ERRORSTRING is the name of the operator to appear in error messages. */
+ ERRORSTRING is the name of the operator to appear in error messages.
+
+ LOC is the location to use for the generated tree. */
tree
-build_indirect_ref (tree ptr, const char *errorstring)
+build_indirect_ref (tree ptr, const char *errorstring, location_t loc)
{
tree pointer = default_conversion (ptr);
tree type = TREE_TYPE (pointer);
+ tree ref;
if (TREE_CODE (type) == POINTER_TYPE)
{
if (TREE_CODE (pointer) == ADDR_EXPR
&& (TREE_TYPE (TREE_OPERAND (pointer, 0))
== TREE_TYPE (type)))
- return TREE_OPERAND (pointer, 0);
+ {
+ ref = TREE_OPERAND (pointer, 0);
+ protected_set_expr_location (ref, loc);
+ return ref;
+ }
else
{
tree t = TREE_TYPE (type);
- tree ref;
ref = build1 (INDIRECT_REF, t, pointer);
TREE_SIDE_EFFECTS (ref)
= TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer);
TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
+ protected_set_expr_location (ref, loc);
return ref;
}
}
If A is a variable or a member, we generate a primitive ARRAY_REF.
This avoids forcing the array out of registers, and can work on
arrays that are not lvalues (for example, members of structures returned
- by functions). */
+ by functions).
+
+ LOC is the location to use for the returned expression. */
tree
-build_array_ref (tree array, tree index)
+build_array_ref (tree array, tree index, location_t loc)
{
+ tree ret;
bool swapped = false;
if (TREE_TYPE (array) == error_mark_node
|| TREE_TYPE (index) == error_mark_node)
in an inline function.
Hope it doesn't break something else. */
| TREE_THIS_VOLATILE (array));
- return require_complete_type (fold (rval));
+ ret = require_complete_type (fold (rval));
+ protected_set_expr_location (ret, loc);
+ return ret;
}
else
{
gcc_assert (TREE_CODE (TREE_TYPE (TREE_TYPE (ar))) != FUNCTION_TYPE);
return build_indirect_ref (build_binary_op (PLUS_EXPR, ar, index, 0),
- "array indexing");
+ "array indexing", loc);
}
}
\f
/* This is the entry point used by the parser to build unary operators
in the input. CODE, a tree_code, specifies the unary operator, and
ARG is the operand. For unary plus, the C parser currently uses
- CONVERT_EXPR for code. */
+ CONVERT_EXPR for code.
+
+ LOC is the location to use for the tree generated.
+*/
struct c_expr
-parser_build_unary_op (enum tree_code code, struct c_expr arg)
+parser_build_unary_op (enum tree_code code, struct c_expr arg, location_t loc)
{
struct c_expr result;
result.original_code = ERROR_MARK;
result.value = build_unary_op (code, arg.value, 0);
-
+ protected_set_expr_location (result.value, loc);
+
if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
overflow_warning (result.value);
+2008-09-01 Aldy Hernandez <aldyh@redhat.com>
+
+ * typeck.c (build_x_indirect_ref): Add location argument.
+ * class.c (build_base_path): Pass location to build_indirect_ref.
+ * pt.c (tsubst_copy_and_build): Pass location to
+ finish_label_address_expr.
+ * parser.c (cp_parser_unary_expression): Same.
+
2008-08-31 Jason Merrill <jason@redhat.com>
Implement late-specified return type using 'auto'.
{
expr = build_nop (build_pointer_type (target_type), expr);
if (!want_pointer)
- expr = build_indirect_ref (expr, NULL);
+ expr = build_indirect_ref (expr, NULL, EXPR_LOCATION (expr));
return expr;
}
{
tree identifier;
tree expression;
+ location_t loc = cp_lexer_peek_token (parser->lexer)->location;
/* Consume the '&&' token. */
cp_lexer_consume_token (parser->lexer);
/* Look for the identifier. */
identifier = cp_parser_identifier (parser);
/* Create an expression representing the address. */
- expression = finish_label_address_expr (identifier);
+ expression = finish_label_address_expr (identifier, loc);
if (cp_parser_non_integral_constant_expression (parser,
"the address of a label"))
expression = error_mark_node;
op1 = tsubst_non_call_postfix_expression (op1, args, complain,
in_decl);
if (TREE_CODE (op1) == LABEL_DECL)
- return finish_label_address_expr (DECL_NAME (op1));
+ return finish_label_address_expr (DECL_NAME (op1),
+ EXPR_LOCATION (op1));
return build_x_unary_op (ADDR_EXPR, op1, complain);
case PLUS_EXPR:
/* Helper function called from c-common. */
tree
-build_indirect_ref (tree ptr, const char *errorstring)
+build_indirect_ref (tree ptr, const char *errorstring,
+ location_t loc __attribute__ ((__unused__)))
{
return cp_build_indirect_ref (ptr, errorstring, tf_warning_or_error);
}
mark_addressable (TREE_VALUE (link));
if (tret == GS_ERROR)
{
+ if (EXPR_HAS_LOCATION (TREE_VALUE (link)))
+ input_location = EXPR_LOCATION (TREE_VALUE (link));
error ("memory input %d is not directly addressable", i);
ret = tret;
}
+2008-09-01 Aldy Hernandez <aldyh@redhat.com>
+
+ * objc-act.c (build_typed_selector_reference): Pass input_location to
+ build_unary_op calls.
+ (build_selector_reference): Same, but to build_array_ref.
+ (objc_substitute_decl): Same.
+ (build_ivar_reference): Same, but to build_indirect_ref.
+ (get_super_receiver): Same.
+
2008-07-28 Richard Guenther <rguenther@suse.de>
Merge from gimple-tuples-branch.
return_at_index:
expr = build_unary_op (ADDR_EXPR,
build_array_ref (UOBJC_SELECTOR_TABLE_decl,
- build_int_cst (NULL_TREE, index)),
+ build_int_cst (NULL_TREE, index),
+ input_location),
1);
return convert (objc_selector_type, expr);
}
return (flag_next_runtime
? TREE_PURPOSE (*chain)
: build_array_ref (UOBJC_SELECTOR_TABLE_decl,
- build_int_cst (NULL_TREE, index)));
+ build_int_cst (NULL_TREE, index),
+ input_location));
index++;
chain = &TREE_CHAIN (*chain);
return (flag_next_runtime
? expr
: build_array_ref (UOBJC_SELECTOR_TABLE_decl,
- build_int_cst (NULL_TREE, index)));
+ build_int_cst (NULL_TREE, index),
+ input_location));
}
static GTY(()) int class_reference_idx;
return build_array_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
oldexpr,
newexpr),
- TREE_OPERAND (expr, 1));
+ TREE_OPERAND (expr, 1),
+ input_location);
case INDIRECT_REF:
return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
oldexpr,
- newexpr), "->");
+ newexpr), "->",
+ input_location);
default:
return expr;
}
self_decl = convert (objc_instance_type, self_decl); /* cast */
}
- return objc_build_component_ref (build_indirect_ref (self_decl, "->"), id);
+ return objc_build_component_ref (build_indirect_ref (self_decl, "->",
+ input_location), id);
}
\f
/* Compute a hash value for a given method SEL_NAME. */
super_class
= build_indirect_ref
(build_c_cast (build_pointer_type (objc_class_type),
- super_class), "unary *");
+ super_class), "unary *", input_location);
}
else
{
+2008-09-01 Aldy Hernandez <aldyh@redhat.com>
+
+ * gcc.dg/20010516-1.c: Test for columns.
+
2008-09-01 Daniel Kraft <d@domob.eu>
PR fortran/37193
+/* { dg-options "-fshow-column" } */
+
foo()
{
char d;
- __asm volatile ( "" :: "m"(&d)); /* { dg-error "" "non-lvalue" } */
+ __asm volatile ( "" :: "m"(&d)); /* { dg-error "34:" "non-lvalue" } */
}
else
EXPR_CHECK (node)->exp.locus = *loc;
}
+
+/* Like SET_EXPR_LOCATION, but make sure the tree can have a location.
+
+ LOC is the location to use in tree T. */
+
+void protected_set_expr_location (tree t, location_t loc)
+{
+ if (t && t != error_mark_node && CAN_HAVE_LOCATION_P (t))
+ SET_EXPR_LOCATION (t, loc);
+}
\f
/* Return a declaration like DDECL except that its DECL_ATTRIBUTES
is ATTRIBUTE. */
location. */
#define CAN_HAVE_LOCATION_P(NODE) (EXPR_P (NODE))
+extern void protected_set_expr_location (tree, location_t);
+
/* In a TARGET_EXPR node. */
#define TARGET_EXPR_SLOT(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 0)
#define TARGET_EXPR_INITIAL(NODE) TREE_OPERAND_CHECK_CODE (NODE, TARGET_EXPR, 1)