From: aldyh Date: Mon, 1 Sep 2008 15:02:27 +0000 (+0000) Subject: * tree.c (protected_set_expr_location): New. X-Git-Tag: upstream/4.9.2~39958 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dda49785be1bd34c9f4958f5df686eab2c7264b0;p=platform%2Fupstream%2Flinaro-gcc.git * 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. objc/ * 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. testsuite/ * gcc.dg/20010516-1.c: Test for columns. cp/ * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@139867 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2a38a71..16cb50c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2008-09-01 Aldy Hernandez + + * 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 * config/arm/arm.md: Include cortex-r4f.md. diff --git a/gcc/c-common.c b/gcc/c-common.c index 748ab52..8c9e48c 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -5003,10 +5003,12 @@ c_do_switch_warnings (splay_tree cases, location_t switch_location, } /* 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; @@ -5025,6 +5027,7 @@ finish_label_address_expr (tree label) /* 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; diff --git a/gcc/c-common.h b/gcc/c-common.h index b0abe3e..d6f8d05 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -357,7 +357,7 @@ extern void push_cleanup (tree, tree, bool); 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); @@ -851,7 +851,7 @@ extern tree build_function_call (tree, 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. */ diff --git a/gcc/c-omp.c b/gcc/c-omp.c index 7da659c..6d9d5fa 100644 --- a/gcc/c-omp.c +++ b/gcc/c-omp.c @@ -137,7 +137,7 @@ c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs) 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 diff --git a/gcc/c-parser.c b/gcc/c-parser.c index e69b0a7..b7f3a17 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -4798,27 +4798,29 @@ c_parser_unary_expression (c_parser *parser) { 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: @@ -4829,29 +4831,29 @@ c_parser_unary_expression (c_parser *parser) 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 @@ -4878,12 +4880,12 @@ c_parser_unary_expression (c_parser *parser) 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); } @@ -5273,11 +5275,12 @@ c_parser_postfix_expression (c_parser *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); } } } @@ -5513,17 +5516,19 @@ c_parser_postfix_expression_after_primary (c_parser *parser, 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: @@ -5572,7 +5577,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser, } 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: diff --git a/gcc/c-tree.h b/gcc/c-tree.h index ab8b36b..1329ce3 100644 --- a/gcc/c-tree.h +++ b/gcc/c-tree.h @@ -550,12 +550,13 @@ extern tree c_type_promotes_to (tree); 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); diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 85a9444..2246526 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -1967,13 +1967,16 @@ build_component_ref (tree datum, tree component) /* 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) { @@ -1992,11 +1995,14 @@ build_indirect_ref (tree ptr, const char *errorstring) 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); @@ -2019,6 +2025,7 @@ build_indirect_ref (tree ptr, const char *errorstring) 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; } } @@ -2034,11 +2041,14 @@ build_indirect_ref (tree ptr, const char *errorstring) 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) @@ -2139,7 +2149,9 @@ build_array_ref (tree array, tree index) 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 { @@ -2152,7 +2164,7 @@ build_array_ref (tree array, tree index) 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); } } @@ -2724,16 +2736,20 @@ convert_arguments (int nargs, tree *argarray, /* 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); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 898beb0..67f3f2b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2008-09-01 Aldy Hernandez + + * 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 Implement late-specified return type using 'auto'. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 9e98f1c..5f7d4a2 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -299,7 +299,7 @@ build_base_path (enum tree_code code, { 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; } diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 3d74d6c..4549f8f 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -5457,13 +5457,14 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p) { 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; diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b05c7a0..7c9165c 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11056,7 +11056,8 @@ tsubst_copy_and_build (tree t, 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: diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 336ddcc..d60ddbd 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2405,7 +2405,8 @@ build_x_indirect_ref (tree expr, const char *errorstring, /* 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); } diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 0515aac..c1f5744 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -4762,6 +4762,8 @@ gimplify_asm_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 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; } diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog index 8fa3d3d..8eea3db 100644 --- a/gcc/objc/ChangeLog +++ b/gcc/objc/ChangeLog @@ -1,3 +1,12 @@ +2008-09-01 Aldy Hernandez + + * 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 Merge from gimple-tuples-branch. diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c index 5941fb6..8f95719 100644 --- a/gcc/objc/objc-act.c +++ b/gcc/objc/objc-act.c @@ -2630,7 +2630,8 @@ build_typed_selector_reference (tree ident, tree prototype) 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); } @@ -2648,7 +2649,8 @@ build_selector_reference (tree ident) 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); @@ -2661,7 +2663,8 @@ build_selector_reference (tree ident) 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; @@ -3046,11 +3049,13 @@ objc_substitute_decl (tree expr, tree oldexpr, tree newexpr) 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; } @@ -6713,7 +6718,8 @@ build_ivar_reference (tree id) 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); } /* Compute a hash value for a given method SEL_NAME. */ @@ -8737,7 +8743,7 @@ get_super_receiver (void) super_class = build_indirect_ref (build_c_cast (build_pointer_type (objc_class_type), - super_class), "unary *"); + super_class), "unary *", input_location); } else { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 44b789a..c5a4f5c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2008-09-01 Aldy Hernandez + + * gcc.dg/20010516-1.c: Test for columns. + 2008-09-01 Daniel Kraft PR fortran/37193 diff --git a/gcc/testsuite/gcc.dg/20010516-1.c b/gcc/testsuite/gcc.dg/20010516-1.c index e9b419f..6ddabd0 100644 --- a/gcc/testsuite/gcc.dg/20010516-1.c +++ b/gcc/testsuite/gcc.dg/20010516-1.c @@ -1,5 +1,7 @@ +/* { dg-options "-fshow-column" } */ + foo() { char d; - __asm volatile ( "" :: "m"(&d)); /* { dg-error "" "non-lvalue" } */ + __asm volatile ( "" :: "m"(&d)); /* { dg-error "34:" "non-lvalue" } */ } diff --git a/gcc/tree.c b/gcc/tree.c index 5b92459..95680ba 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -3577,6 +3577,16 @@ set_expr_locus (tree node, source_location *loc) 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); +} /* Return a declaration like DDECL except that its DECL_ATTRIBUTES is ATTRIBUTE. */ diff --git a/gcc/tree.h b/gcc/tree.h index 40cd456..43531e5 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1578,6 +1578,8 @@ struct tree_constructor GTY(()) 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)