* [patch] location for unary operators
@ 2008-09-30 21:52 Aldy Hernandez
2008-10-06 22:26 ` Andrew Pinski
[not found] ` <48E2B158.5080401@redhat.com>
0 siblings, 2 replies; 4+ messages in thread
From: Aldy Hernandez @ 2008-09-30 21:52 UTC (permalink / raw)
To: rth, gcc-patches
Well, the main goal was adding location to unary operators, but there
were some supporting things that needed to be fixed and cleaned up.
As an aside, now build_unary_op and build_binary_op set the
EXPR_LCOATION so the caller doesn't have to.
Nothing major here, just the usual fixes for locations.
Tested on x86-64 Linux. GCC tests done. GDB tests are still going.
OK pending GDB tests?
Aldy
----
objc/
* objc-act.c (objc_build_string_object): Pass location to
build_unary_op.
(init_def_list): Same.
(init_objc_symtab): Same.
(init_module_descriptor): Same.
(build_module_initializer_routine): Same.
(generate_static_references): Same.
(build_typed_selector_reference): Same.
(add_objc_string): Same.
(objc_substitute_decl): Same.
(objc_build_ivar_assignment): Same.
(objc_build_global_assignment): Same.
(objc_build_strong_cast_assignment): Same.
(generate_protocols): Same.
(build_protocol_initializer): Same.
(build_dispatch_table_initializer): Same.
(generate_protocol_list): Same.
(build_category_initializer): Same.
(build_shared_structure_initializer): Same.
(generate_shared_structures): Same.
(objc_build_protocol_expr): Same.
(build_ivar_reference): Same.
(get_super_receiver): Same.
build_modify_expr.
gcc/
* c-decl.c (finish_decl): Pass input_location to build_unary_op.
* c-typeck.c (array_to_pointer_conversion): Pass location to
build_unary_op.
(function_to_pointer_conversion): Use error_at and warning_at.
(build_indirect_ref): Same.
(build_array_ref): Pass location to build_binary_op.
(parser_build_unary_op): Do not set location after calling
build_unary_op.
(build_unary_op): Add location argument. Use it throughout. Set
EXPR_LOCATION before returning new tree.
(build_modify_expr): Same.
(build_binary_op): Use location throughout. Set EXPR_LOCATION before
returning node.
* c-omp.c (c_finish_omp_atomic): Pass location to build_unary_op,
build_indirect_ref, build_modify_expr.
(c_finish_omp_for): Same. Use error_at instead of error.
* c-common.c (c_common_truthvalue_conversion): Pass location to
build_unary_op.
(warn_for_div_by_zero): Add location argument.
* c-common.h: Add argument to build_modify_expr, build_indirect_ref,
build_unary_op, warn_for_div_by_zero.
* c-parser.c (c_parser_typeof_specifier): Use
protected_set_expr_location.
(c_parser_statement_after_labels): Same.
(c_parser_condition): Same.
(c_parser_expr_no_commas): Pass correct location to build_modify_expr.
(c_parser_conditional_expression): Use protected_set_expr_location.
(c_parser_unary_expression): Pass location to build_indirect_ref.
(c_parser_postfix_expression_after_primary): Pass location to
build_indirect_ref, build_unary_op.
(c_parser_omp_for_loop): Set the increment expression's EXPR_LOCATION.
testsuite/
* gcc.dg/gomp/for-1.c: Test column.
* gcc.dg/misc-column.c: Add column tests for unary arguments.
cp/
* typeck.c (build_x_indirect_ref): Add location argument.
(cp_build_binary_op): Pass location to warn_for_div_by_zero.
(cp_build_unary_op): Add location argument.
(cp_build_modify_expr): Same.
* class.c (build_base_path): Pass location to build_indirect_ref.
* semantics.c (handle_omp_for_class_iterator): Pass elocus to
build_modify_expr.
Index: objc/objc-act.c
===================================================================
--- objc/objc-act.c (revision 140798)
+++ objc/objc-act.c (working copy)
@@ -1940,10 +1940,12 @@ objc_build_string_object (tree string)
initlist
= build_tree_list (fields,
flag_next_runtime
- ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
+ ? build_unary_op (input_location,
+ ADDR_EXPR, string_class_decl, 0)
: build_int_cst (NULL_TREE, 0));
fields = TREE_CHAIN (fields);
- initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
+ initlist = tree_cons (fields, build_unary_op (input_location,
+ ADDR_EXPR, string, 1),
initlist);
fields = TREE_CHAIN (fields);
initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
@@ -1966,7 +1968,8 @@ objc_build_string_object (tree string)
}
addr = convert (build_pointer_type (constant_string_type),
- build_unary_op (ADDR_EXPR, desc->constructor, 1));
+ build_unary_op (input_location,
+ ADDR_EXPR, desc->constructor, 1));
return addr;
}
@@ -2104,7 +2107,8 @@ init_def_list (tree type)
{
if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
{
- expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, impent->class_decl, 0);
initlist = tree_cons (NULL_TREE, expr, initlist);
}
}
@@ -2114,7 +2118,8 @@ init_def_list (tree type)
{
if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
{
- expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, impent->class_decl, 0);
initlist = tree_cons (NULL_TREE, expr, initlist);
}
}
@@ -2125,7 +2130,8 @@ init_def_list (tree type)
tree expr;
if (static_instances_decl)
- expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, static_instances_decl, 0);
else
expr = build_int_cst (NULL_TREE, 0);
@@ -2155,7 +2161,7 @@ init_objc_symtab (tree type)
initlist
= tree_cons (NULL_TREE,
convert (build_pointer_type (objc_selector_type),
- build_unary_op (ADDR_EXPR,
+ build_unary_op (input_location, ADDR_EXPR,
UOBJC_SELECTOR_TABLE_decl, 1)),
initlist);
@@ -2262,7 +2268,8 @@ init_module_descriptor (tree type)
/* symtab = { ..., _OBJC_SYMBOLS, ... } */
if (UOBJC_SYMBOLS_decl)
- expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
else
expr = build_int_cst (NULL_TREE, 0);
initlist = tree_cons (NULL_TREE, expr, initlist);
@@ -2345,7 +2352,7 @@ build_module_initializer_routine (void)
(execclass_decl,
build_tree_list
(NULL_TREE,
- build_unary_op (ADDR_EXPR,
+ build_unary_op (input_location, ADDR_EXPR,
UOBJC_MODULES_decl, 0))));
add_stmt (c_end_compound_stmt (body, true));
@@ -2440,13 +2447,15 @@ generate_static_references (void)
klass = TREE_VALUE (cl_chain);
class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
initlist = build_tree_list (NULL_TREE,
- build_unary_op (ADDR_EXPR, class_name, 1));
+ build_unary_op (input_location,
+ ADDR_EXPR, class_name, 1));
/* Output {..., instance, ...}. */
for (in_chain = TREE_PURPOSE (cl_chain);
in_chain; in_chain = TREE_CHAIN (in_chain))
{
- expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, TREE_VALUE (in_chain), 1);
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -2456,7 +2465,8 @@ generate_static_references (void)
expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
finish_var_decl (decl, expr);
decls
- = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
+ = tree_cons (NULL_TREE, build_unary_op (input_location,
+ ADDR_EXPR, decl, 1), decls);
}
decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
@@ -2628,7 +2638,7 @@ build_typed_selector_reference (tree ide
*chain = tree_cons (prototype, ident, NULL_TREE);
return_at_index:
- expr = build_unary_op (ADDR_EXPR,
+ expr = build_unary_op (input_location, ADDR_EXPR,
build_array_ref (UOBJC_SELECTOR_TABLE_decl,
build_int_cst (NULL_TREE, index),
input_location),
@@ -2801,7 +2811,8 @@ add_objc_string (tree ident, enum string
{
if (TREE_VALUE (*chain) == ident)
return convert (string_type_node,
- build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
+ build_unary_op (input_location,
+ ADDR_EXPR, TREE_PURPOSE (*chain), 1));
chain = &TREE_CHAIN (*chain);
}
@@ -2820,7 +2831,8 @@ add_objc_string (tree ident, enum string
*chain = tree_cons (decl, ident, NULL_TREE);
- return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
+ return convert (string_type_node, build_unary_op (input_location,
+ ADDR_EXPR, decl, 1));
}
static GTY(()) int class_names_idx;
@@ -3052,10 +3064,10 @@ objc_substitute_decl (tree expr, tree ol
TREE_OPERAND (expr, 1),
input_location);
case INDIRECT_REF:
- return build_indirect_ref (objc_substitute_decl (TREE_OPERAND (expr, 0),
+ return build_indirect_ref (input_location,
+ objc_substitute_decl (TREE_OPERAND (expr, 0),
oldexpr,
- newexpr), "->",
- input_location);
+ newexpr), "->");
default:
return expr;
}
@@ -3077,7 +3089,8 @@ objc_build_ivar_assignment (tree outerva
? objc_assign_ivar_fast_decl
: objc_assign_ivar_decl);
- offs = convert (integer_type_node, build_unary_op (ADDR_EXPR, offs, 0));
+ offs = convert (integer_type_node, build_unary_op (input_location,
+ ADDR_EXPR, offs, 0));
offs = fold (offs);
func_params = tree_cons (NULL_TREE,
convert (objc_object_type, rhs),
@@ -3095,7 +3108,7 @@ objc_build_global_assignment (tree lhs,
tree func_params = tree_cons (NULL_TREE,
convert (objc_object_type, rhs),
tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
- build_unary_op (ADDR_EXPR, lhs, 0)),
+ build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
NULL_TREE));
assemble_external (objc_assign_global_decl);
@@ -3108,7 +3121,7 @@ objc_build_strong_cast_assignment (tree
tree func_params = tree_cons (NULL_TREE,
convert (objc_object_type, rhs),
tree_cons (NULL_TREE, convert (build_pointer_type (objc_object_type),
- build_unary_op (ADDR_EXPR, lhs, 0)),
+ build_unary_op (input_location, ADDR_EXPR, lhs, 0)),
NULL_TREE));
assemble_external (objc_assign_strong_cast_decl);
@@ -4672,7 +4685,8 @@ generate_protocols (void)
if (refs_decl)
refs_expr = convert (build_pointer_type (build_pointer_type
(objc_protocol_template)),
- build_unary_op (ADDR_EXPR, refs_decl, 0));
+ build_unary_op (input_location,
+ ADDR_EXPR, refs_decl, 0));
else
refs_expr = build_int_cst (NULL_TREE, 0);
@@ -4709,7 +4723,8 @@ build_protocol_initializer (tree type, t
else
{
expr = convert (objc_method_proto_list_ptr,
- build_unary_op (ADDR_EXPR, instance_methods, 0));
+ build_unary_op (input_location,
+ ADDR_EXPR, instance_methods, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -4718,7 +4733,8 @@ build_protocol_initializer (tree type, t
else
{
expr = convert (objc_method_proto_list_ptr,
- build_unary_op (ADDR_EXPR, class_methods, 0));
+ build_unary_op (input_location,
+ ADDR_EXPR, class_methods, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -5287,7 +5303,7 @@ build_dispatch_table_initializer (tree t
elemlist
= tree_cons (NULL_TREE,
convert (ptr_type_node,
- build_unary_op (ADDR_EXPR,
+ build_unary_op (input_location, ADDR_EXPR,
METHOD_DEFINITION (entries), 1)),
elemlist);
@@ -5471,7 +5487,8 @@ generate_protocol_list (tree i_or_p)
if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
&& PROTOCOL_FORWARD_DECL (pval))
{
- e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
+ e = build_unary_op (input_location, ADDR_EXPR,
+ PROTOCOL_FORWARD_DECL (pval), 0);
initlist = tree_cons (NULL_TREE, e, initlist);
}
}
@@ -5514,7 +5531,8 @@ build_category_initializer (tree type, t
else
{
expr = convert (objc_method_list_ptr,
- build_unary_op (ADDR_EXPR, instance_methods, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ instance_methods, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
if (!class_methods)
@@ -5522,7 +5540,8 @@ build_category_initializer (tree type, t
else
{
expr = convert (objc_method_list_ptr,
- build_unary_op (ADDR_EXPR, class_methods, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ class_methods, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -5534,7 +5553,8 @@ build_category_initializer (tree type, t
expr = convert (build_pointer_type
(build_pointer_type
(objc_protocol_template)),
- build_unary_op (ADDR_EXPR, protocol_list, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ protocol_list, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -5599,7 +5619,8 @@ build_shared_structure_initializer (tree
else
{
expr = convert (objc_ivar_list_ptr,
- build_unary_op (ADDR_EXPR, ivar_list, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ ivar_list, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -5609,7 +5630,8 @@ build_shared_structure_initializer (tree
else
{
expr = convert (objc_method_list_ptr,
- build_unary_op (ADDR_EXPR, dispatch_table, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ dispatch_table, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -5636,7 +5658,8 @@ build_shared_structure_initializer (tree
expr = convert (build_pointer_type
(build_pointer_type
(objc_protocol_template)),
- build_unary_op (ADDR_EXPR, protocol_list, 0));
+ build_unary_op (input_location, ADDR_EXPR,
+ protocol_list, 0));
initlist = tree_cons (NULL_TREE, expr, initlist);
}
@@ -5790,7 +5813,7 @@ generate_shared_structures (int cls_flag
initlist
= build_shared_structure_initializer
(TREE_TYPE (decl),
- build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
+ build_unary_op (input_location, ADDR_EXPR, UOBJC_METACLASS_decl, 0),
super_expr, name_expr,
convert (integer_type_node,
TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
@@ -6582,7 +6605,8 @@ objc_build_protocol_expr (tree protoname
if (!PROTOCOL_FORWARD_DECL (p))
build_protocol_reference (p);
- expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
+ expr = build_unary_op (input_location,
+ ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
/* ??? Ideally we'd build the reference with objc_protocol_type directly,
if we have it, rather than converting it here. */
@@ -6720,8 +6744,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, "->",
- input_location), id);
+ return objc_build_component_ref (build_indirect_ref (input_location,
+ self_decl, "->"), id);
}
\f
/* Compute a hash value for a given method SEL_NAME. */
@@ -8701,7 +8725,8 @@ get_super_receiver (void)
/* Set receiver to self. */
super_expr = objc_build_component_ref (UOBJC_SUPER_decl, self_id);
- super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
+ super_expr = build_modify_expr (input_location,
+ super_expr, NOP_EXPR, self_decl);
super_expr_list = super_expr;
/* Set class to begin searching. */
@@ -8713,7 +8738,7 @@ get_super_receiver (void)
/* [_cls, __cls]Super are "pre-built" in
synth_forward_declarations. */
- super_expr = build_modify_expr (super_expr, NOP_EXPR,
+ super_expr = build_modify_expr (input_location, super_expr, NOP_EXPR,
((TREE_CODE (objc_method_context)
== INSTANCE_METHOD_DECL)
? ucls_super_ref
@@ -8744,8 +8769,9 @@ get_super_receiver (void)
"isa" is the first ivar in a class (which it must be). */
super_class
= build_indirect_ref
- (build_c_cast (build_pointer_type (objc_class_type),
- super_class), "unary *", input_location);
+ (input_location,
+ build_c_cast (build_pointer_type (objc_class_type),
+ super_class), "unary *");
}
else
{
@@ -8764,14 +8790,15 @@ get_super_receiver (void)
}
super_expr
- = build_modify_expr (super_expr, NOP_EXPR,
+ = build_modify_expr (input_location, super_expr, NOP_EXPR,
build_c_cast (TREE_TYPE (super_expr),
super_class));
}
super_expr_list = build_compound_expr (super_expr_list, super_expr);
- super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
+ super_expr = build_unary_op (input_location,
+ ADDR_EXPR, UOBJC_SUPER_decl, 0);
super_expr_list = build_compound_expr (super_expr_list, super_expr);
return super_expr_list;
Index: testsuite/gcc.dg/gomp/for-1.c
===================================================================
--- testsuite/gcc.dg/gomp/for-1.c (revision 140798)
+++ testsuite/gcc.dg/gomp/for-1.c (working copy)
@@ -44,6 +44,6 @@ void foo (int j, int k)
baz (i);
#pragma omp for
- for (i = 0; i < 10; i-=3, j+=2) /* { dg-error "invalid increment expression" } */
+ for (i = 0; i < 10; i-=3, j+=2) /* { dg-error "23:invalid increment expression" } */
baz (i);
}
Index: testsuite/gcc.dg/misc-column.c
===================================================================
--- testsuite/gcc.dg/misc-column.c (revision 140798)
+++ testsuite/gcc.dg/misc-column.c (working copy)
@@ -1,5 +1,6 @@
/* { dg-options "-fshow-column -Wall -Wfloat-equal -pedantic" } */
+int i, j;
float a, b;
int *p;
@@ -26,4 +27,14 @@ void foo (void)
if (p < 0) /* { dg-warning "9:ordered comparison of pointer with" } */
bar();
+
+ -q; /* { dg-error "3:wrong type argument to unary" } */
+
+ ~q; /* { dg-error "3:wrong type argument to bit" } */
+
+ ++*q; /* { dg-error "3:wrong type argument to increment" } */
+
+ i = j / 0; /* { dg-warning "9:division by zero" } */
+
+ i /= 0; /* { dg-warning "5:division by zero" } */
}
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (revision 140798)
+++ cp/typeck.c (working copy)
@@ -2405,8 +2405,8 @@ build_x_indirect_ref (tree expr, const c
/* Helper function called from c-common. */
tree
-build_indirect_ref (tree ptr, const char *errorstring,
- location_t loc __attribute__ ((__unused__)))
+build_indirect_ref (location_t loc __attribute__ ((__unused__)),
+ tree ptr, const char *errorstring)
{
return cp_build_indirect_ref (ptr, errorstring, tf_warning_or_error);
}
@@ -3349,7 +3349,7 @@ cp_build_binary_op (location_t location,
{
enum tree_code tcode0 = code0, tcode1 = code1;
- warn_for_div_by_zero (op1);
+ warn_for_div_by_zero (location, op1);
if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
@@ -3385,7 +3385,7 @@ cp_build_binary_op (location_t location,
case TRUNC_MOD_EXPR:
case FLOOR_MOD_EXPR:
- warn_for_div_by_zero (op1);
+ warn_for_div_by_zero (location, op1);
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
@@ -4642,7 +4642,8 @@ cp_build_unary_op (enum tree_code code,
/* Hook for the c-common bits that build a unary op. */
tree
-build_unary_op (enum tree_code code, tree xarg, int noconvert)
+build_unary_op (location_t location ATTRIBUTE_UNUSED,
+ enum tree_code code, tree xarg, int noconvert)
{
return cp_build_unary_op (code, xarg, noconvert, tf_warning_or_error);
}
@@ -5757,7 +5758,8 @@ cp_build_c_cast (tree type, tree expr, t
\f
/* For use from the C common bits. */
tree
-build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
+build_modify_expr (location_t location ATTRIBUTE_UNUSED,
+ tree lhs, enum tree_code modifycode, tree rhs)
{
return cp_build_modify_expr (lhs, modifycode, rhs, tf_warning_or_error);
}
@@ -5940,7 +5942,7 @@ cp_build_modify_expr (tree lhs, enum tre
|| MAYBE_CLASS_TYPE_P (lhstype)));
lhs = stabilize_reference (lhs);
- newrhs = cp_build_binary_op (EXPR_LOCATION (lhs),
+ newrhs = cp_build_binary_op (input_location,
modifycode, lhs, rhs,
complain);
if (newrhs == error_mark_node)
Index: cp/class.c
===================================================================
--- cp/class.c (revision 140798)
+++ cp/class.c (working copy)
@@ -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_LOCATION (expr));
+ expr = build_indirect_ref (EXPR_LOCATION (expr), expr, NULL);
return expr;
}
Index: cp/semantics.c
===================================================================
--- cp/semantics.c (revision 140798)
+++ cp/semantics.c (working copy)
@@ -4109,7 +4109,7 @@ handle_omp_for_class_iterator (int i, lo
cond = cp_build_binary_op (elocus,
TREE_CODE (cond), decl, diff,
tf_warning_or_error);
- incr = build_modify_expr (decl, PLUS_EXPR, incr);
+ incr = build_modify_expr (elocus, decl, PLUS_EXPR, incr);
orig_body = *body;
*body = push_stmt_list ();
Index: c-decl.c
===================================================================
--- c-decl.c (revision 140798)
+++ c-decl.c (working copy)
@@ -3650,7 +3650,7 @@ finish_decl (tree decl, tree init, tree
tree cleanup;
/* Build "cleanup(&decl)" for the destructor. */
- cleanup = build_unary_op (ADDR_EXPR, decl, 0);
+ cleanup = build_unary_op (input_location, ADDR_EXPR, decl, 0);
cleanup = build_tree_list (NULL_TREE, cleanup);
cleanup = build_function_call (cleanup_decl, cleanup);
Index: c-typeck.c
===================================================================
--- c-typeck.c (revision 140798)
+++ c-typeck.c (working copy)
@@ -1618,7 +1618,7 @@ array_to_pointer_conversion (tree exp)
/* This way is better for a COMPONENT_REF since it can
simplify the offset for a component. */
- adr = build_unary_op (ADDR_EXPR, exp, 1);
+ adr = build_unary_op (EXPR_LOCATION (exp), ADDR_EXPR, exp, 1);
return convert (ptrtype, adr);
}
@@ -1635,7 +1635,7 @@ function_to_pointer_conversion (tree exp
if (TREE_NO_WARNING (orig_exp))
TREE_NO_WARNING (exp) = 1;
- return build_unary_op (ADDR_EXPR, exp, 0);
+ return build_unary_op (EXPR_LOCATION (exp), ADDR_EXPR, exp, 0);
}
/* Perform the default conversion of arrays and functions to pointers.
@@ -1972,7 +1972,7 @@ build_component_ref (tree datum, tree co
LOC is the location to use for the generated tree. */
tree
-build_indirect_ref (tree ptr, const char *errorstring, location_t loc)
+build_indirect_ref (location_t loc, tree ptr, const char *errorstring)
{
tree pointer = default_conversion (ptr);
tree type = TREE_TYPE (pointer);
@@ -2008,11 +2008,11 @@ build_indirect_ref (tree ptr, const char
if (!COMPLETE_OR_VOID_TYPE_P (t) && TREE_CODE (t) != ARRAY_TYPE)
{
- error ("dereferencing pointer to incomplete type");
+ error_at (loc, "dereferencing pointer to incomplete type");
return error_mark_node;
}
if (VOID_TYPE_P (t) && skip_evaluation == 0)
- warning (0, "dereferencing %<void *%> pointer");
+ warning_at (loc, 0, "dereferencing %<void *%> pointer");
/* We *must* set TREE_READONLY when dereferencing a pointer to const,
so that we get the proper error message if the result is used
@@ -2030,7 +2030,8 @@ build_indirect_ref (tree ptr, const char
}
}
else if (TREE_CODE (pointer) != ERROR_MARK)
- error ("invalid type argument of %qs (have %qT)", errorstring, type);
+ error_at (loc,
+ "invalid type argument of %qs (have %qT)", errorstring, type);
return error_mark_node;
}
@@ -2164,8 +2165,8 @@ 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 (loc, PLUS_EXPR, ar, index, 0),
- "array indexing", loc);
+ (loc, build_binary_op (loc, PLUS_EXPR, ar, index, 0),
+ "array indexing");
}
}
\f
@@ -2748,8 +2749,7 @@ parser_build_unary_op (enum tree_code co
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);
+ result.value = build_unary_op (loc, code, arg.value, 0);
if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
overflow_warning (result.value);
@@ -2901,16 +2901,20 @@ pointer_diff (tree op0, tree op1)
the default promotions (such as from short to int).
For ADDR_EXPR, the default promotions are not applied; FLAG nonzero
allows non-lvalues; this is only used to handle conversion of non-lvalue
- arrays to pointers in C99. */
+ arrays to pointers in C99.
+
+ LOCATION is the location of the operator. */
tree
-build_unary_op (enum tree_code code, tree xarg, int flag)
+build_unary_op (location_t location,
+ enum tree_code code, tree xarg, int flag)
{
/* No default_conversion here. It causes trouble for ADDR_EXPR. */
tree arg = xarg;
tree argtype = 0;
enum tree_code typecode;
tree val;
+ tree ret = error_mark_node;
int noconvert = flag;
const char *invalid_op_diag;
@@ -2926,7 +2930,7 @@ build_unary_op (enum tree_code code, tre
if ((invalid_op_diag
= targetm.invalid_unary_op (code, TREE_TYPE (xarg))))
{
- error (invalid_op_diag);
+ error_at (location, invalid_op_diag);
return error_mark_node;
}
@@ -2940,7 +2944,7 @@ build_unary_op (enum tree_code code, tre
|| typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE
|| typecode == VECTOR_TYPE))
{
- error ("wrong type argument to unary plus");
+ error_at (location, "wrong type argument to unary plus");
return error_mark_node;
}
else if (!noconvert)
@@ -2953,7 +2957,7 @@ build_unary_op (enum tree_code code, tre
|| typecode == FIXED_POINT_TYPE || typecode == COMPLEX_TYPE
|| typecode == VECTOR_TYPE))
{
- error ("wrong type argument to unary minus");
+ error_at (location, "wrong type argument to unary minus");
return error_mark_node;
}
else if (!noconvert)
@@ -2972,14 +2976,14 @@ build_unary_op (enum tree_code code, tre
else if (typecode == COMPLEX_TYPE)
{
code = CONJ_EXPR;
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (location, OPT_pedantic,
"ISO C does not support %<~%> for complex conjugation");
if (!noconvert)
arg = default_conversion (arg);
}
else
{
- error ("wrong type argument to bit-complement");
+ error_at (location, "wrong type argument to bit-complement");
return error_mark_node;
}
break;
@@ -2987,7 +2991,7 @@ build_unary_op (enum tree_code code, tre
case ABS_EXPR:
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE))
{
- error ("wrong type argument to abs");
+ error_at (location, "wrong type argument to abs");
return error_mark_node;
}
else if (!noconvert)
@@ -2999,7 +3003,7 @@ build_unary_op (enum tree_code code, tre
if (!(typecode == INTEGER_TYPE || typecode == REAL_TYPE
|| typecode == COMPLEX_TYPE))
{
- error ("wrong type argument to conjugation");
+ error_at (location, "wrong type argument to conjugation");
return error_mark_node;
}
else if (!noconvert)
@@ -3011,27 +3015,31 @@ build_unary_op (enum tree_code code, tre
&& typecode != REAL_TYPE && typecode != POINTER_TYPE
&& typecode != COMPLEX_TYPE)
{
- error ("wrong type argument to unary exclamation mark");
+ error_at (location,
+ "wrong type argument to unary exclamation mark");
return error_mark_node;
}
- arg = c_objc_common_truthvalue_conversion (input_location, arg);
- return invert_truthvalue (arg);
+ arg = c_objc_common_truthvalue_conversion (location, arg);
+ ret = invert_truthvalue (arg);
+ goto return_build_unary_op;
case REALPART_EXPR:
if (TREE_CODE (arg) == COMPLEX_CST)
- return TREE_REALPART (arg);
+ ret = TREE_REALPART (arg);
else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
- return fold_build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
+ ret = fold_build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
else
- return arg;
+ ret = arg;
+ goto return_build_unary_op;
case IMAGPART_EXPR:
if (TREE_CODE (arg) == COMPLEX_CST)
- return TREE_IMAGPART (arg);
+ ret = TREE_IMAGPART (arg);
else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE)
- return fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
+ ret = fold_build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg);
else
- return convert (TREE_TYPE (arg), integer_zero_node);
+ ret = convert (TREE_TYPE (arg), integer_zero_node);
+ goto return_build_unary_op;
case PREINCREMENT_EXPR:
case POSTINCREMENT_EXPR:
@@ -3044,17 +3052,18 @@ build_unary_op (enum tree_code code, tre
{
tree real, imag;
- pedwarn (input_location, OPT_pedantic,
+ pedwarn (location, OPT_pedantic,
"ISO C does not support %<++%> and %<--%> on complex types");
arg = stabilize_reference (arg);
- real = build_unary_op (REALPART_EXPR, arg, 1);
- imag = build_unary_op (IMAGPART_EXPR, arg, 1);
- real = build_unary_op (code, real, 1);
+ real = build_unary_op (EXPR_LOCATION (arg), REALPART_EXPR, arg, 1);
+ imag = build_unary_op (EXPR_LOCATION (arg), IMAGPART_EXPR, arg, 1);
+ real = build_unary_op (EXPR_LOCATION (arg), code, real, 1);
if (real == error_mark_node || imag == error_mark_node)
return error_mark_node;
- return build2 (COMPLEX_EXPR, TREE_TYPE (arg),
- real, imag);
+ ret = build2 (COMPLEX_EXPR, TREE_TYPE (arg),
+ real, imag);
+ goto return_build_unary_op;
}
/* Report invalid types. */
@@ -3063,9 +3072,9 @@ build_unary_op (enum tree_code code, tre
&& typecode != INTEGER_TYPE && typecode != REAL_TYPE)
{
if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
- error ("wrong type argument to increment");
+ error_at (location, "wrong type argument to increment");
else
- error ("wrong type argument to decrement");
+ error_at (location, "wrong type argument to decrement");
return error_mark_node;
}
@@ -3086,18 +3095,20 @@ build_unary_op (enum tree_code code, tre
if (!COMPLETE_OR_VOID_TYPE_P (TREE_TYPE (result_type)))
{
if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
- error ("increment of pointer to unknown structure");
+ error_at (location,
+ "increment of pointer to unknown structure");
else
- error ("decrement of pointer to unknown structure");
+ error_at (location,
+ "decrement of pointer to unknown structure");
}
else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
{
if (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR)
- pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ pedwarn (location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
"wrong type argument to increment");
else
- pedwarn (input_location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
+ pedwarn (location, pedantic ? OPT_pedantic : OPT_Wpointer_arith,
"wrong type argument to decrement");
}
@@ -3154,7 +3165,8 @@ build_unary_op (enum tree_code code, tre
val = convert (result_type, val);
if (TREE_CODE (val) != code)
TREE_NO_WARNING (val) = 1;
- return val;
+ ret = val;
+ goto return_build_unary_op;
}
case ADDR_EXPR:
@@ -3166,7 +3178,8 @@ build_unary_op (enum tree_code code, tre
/* Don't let this be an lvalue. */
if (lvalue_p (TREE_OPERAND (arg, 0)))
return non_lvalue (TREE_OPERAND (arg, 0));
- return TREE_OPERAND (arg, 0);
+ ret = TREE_OPERAND (arg, 0);
+ goto return_build_unary_op;
}
/* For &x[y], return x+y */
@@ -3175,7 +3188,7 @@ build_unary_op (enum tree_code code, tre
tree op0 = TREE_OPERAND (arg, 0);
if (!c_mark_addressable (op0))
return error_mark_node;
- return build_binary_op (EXPR_LOCATION (xarg), PLUS_EXPR,
+ return build_binary_op (location, PLUS_EXPR,
(TREE_CODE (TREE_TYPE (op0)) == ARRAY_TYPE
? array_to_pointer_conversion (op0)
: op0),
@@ -3218,12 +3231,14 @@ build_unary_op (enum tree_code code, tre
tree op0 = fold_convert (sizetype, fold_offsetof (arg, val)), op1;
op1 = fold_convert (argtype, TREE_OPERAND (val, 0));
- return fold_build2 (POINTER_PLUS_EXPR, argtype, op1, op0);
+ ret = fold_build2 (POINTER_PLUS_EXPR, argtype, op1, op0);
+ goto return_build_unary_op;
}
val = build1 (ADDR_EXPR, argtype, arg);
- return val;
+ ret = val;
+ goto return_build_unary_op;
default:
gcc_unreachable ();
@@ -3231,8 +3246,12 @@ build_unary_op (enum tree_code code, tre
if (argtype == 0)
argtype = TREE_TYPE (arg);
- return require_constant_value ? fold_build1_initializer (code, argtype, arg)
- : fold_build1 (code, argtype, arg);
+ ret = require_constant_value ? fold_build1_initializer (code, argtype, arg)
+ : fold_build1 (code, argtype, arg);
+ return_build_unary_op:
+ gcc_assert (ret != error_mark_node);
+ protected_set_expr_location (ret, location);
+ return ret;
}
/* Return nonzero if REF is an lvalue valid for this language.
@@ -3837,10 +3856,13 @@ c_cast_expr (struct c_type_name *type_na
/* Build an assignment expression of lvalue LHS from value RHS.
MODIFYCODE is the code for a binary operator that we use
to combine the old value of LHS with RHS to get the new value.
- Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment. */
+ Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment.
+
+ LOCATION is the location of the MODIFYCODE operator. */
tree
-build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs)
+build_modify_expr (location_t location,
+ tree lhs, enum tree_code modifycode, tree rhs)
{
tree result;
tree newrhs;
@@ -3867,7 +3889,7 @@ build_modify_expr (tree lhs, enum tree_c
if (modifycode != NOP_EXPR)
{
lhs = stabilize_reference (lhs);
- newrhs = build_binary_op (EXPR_LOCATION (lhs),
+ newrhs = build_binary_op (location,
modifycode, lhs, rhs, 1);
}
@@ -3915,13 +3937,17 @@ build_modify_expr (tree lhs, enum tree_c
{
result = objc_generate_write_barrier (lhs, modifycode, newrhs);
if (result)
- return result;
+ {
+ protected_set_expr_location (result, location);
+ return result;
+ }
}
/* Scan operands. */
result = build2 (MODIFY_EXPR, lhstype, lhs, newrhs);
TREE_SIDE_EFFECTS (result) = 1;
+ protected_set_expr_location (result, location);
/* If we got the LHS in a different type for storing in,
convert the result back to the nominal type of LHS
@@ -3930,8 +3956,11 @@ build_modify_expr (tree lhs, enum tree_c
if (olhstype == TREE_TYPE (result))
return result;
- return convert_for_assignment (olhstype, result, ic_assign,
- NULL_TREE, NULL_TREE, 0);
+
+ result = convert_for_assignment (olhstype, result, ic_assign,
+ NULL_TREE, NULL_TREE, 0);
+ protected_set_expr_location (result, location);
+ return result;
}
\f
/* Convert value RHS to type TYPE as preparation for an assignment
@@ -7942,6 +7971,7 @@ build_binary_op (location_t location, en
tree type0, type1;
enum tree_code code0, code1;
tree op0, op1;
+ tree ret = error_mark_node;
const char *invalid_op_diag;
/* Expression code to give to the expression when it is built.
@@ -8035,9 +8065,15 @@ build_binary_op (location_t location, en
case PLUS_EXPR:
/* Handle the pointer + int case. */
if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
- return pointer_int_sum (PLUS_EXPR, op0, op1);
+ {
+ ret = pointer_int_sum (PLUS_EXPR, op0, op1);
+ goto return_build_binary_op;
+ }
else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE)
- return pointer_int_sum (PLUS_EXPR, op1, op0);
+ {
+ ret = pointer_int_sum (PLUS_EXPR, op1, op0);
+ goto return_build_binary_op;
+ }
else
common = 1;
break;
@@ -8047,10 +8083,16 @@ build_binary_op (location_t location, en
We must subtract them as integers, then divide by object size. */
if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
&& comp_target_types (type0, type1))
- return pointer_diff (op0, op1);
+ {
+ ret = pointer_diff (op0, op1);
+ goto return_build_binary_op;
+ }
/* Handle pointer minus int. Just like pointer plus int. */
else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE)
- return pointer_int_sum (MINUS_EXPR, op0, op1);
+ {
+ ret = pointer_int_sum (MINUS_EXPR, op0, op1);
+ goto return_build_binary_op;
+ }
else
common = 1;
break;
@@ -8064,7 +8106,7 @@ build_binary_op (location_t location, en
case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
- warn_for_div_by_zero (op1);
+ warn_for_div_by_zero (location, op1);
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
|| code0 == FIXED_POINT_TYPE
@@ -8111,7 +8153,7 @@ build_binary_op (location_t location, en
case TRUNC_MOD_EXPR:
case FLOOR_MOD_EXPR:
- warn_for_div_by_zero (op1);
+ warn_for_div_by_zero (location, op1);
if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
@@ -8435,7 +8477,10 @@ build_binary_op (location_t location, en
= shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode);
if (val != 0)
- return val;
+ {
+ ret = val;
+ goto return_build_binary_op;
+ }
op0 = xop0, op1 = xop1;
converted = 1;
@@ -8477,18 +8522,19 @@ build_binary_op (location_t location, en
if (build_type == NULL_TREE)
build_type = result_type;
- {
- /* Treat expressions in initializers specially as they can't trap. */
- tree result = require_constant_value ? fold_build2_initializer (resultcode,
- build_type,
- op0, op1)
- : fold_build2 (resultcode, build_type,
- op0, op1);
-
- if (final_type != 0)
- result = convert (final_type, result);
- return result;
- }
+ /* Treat expressions in initializers specially as they can't trap. */
+ ret = require_constant_value ? fold_build2_initializer (resultcode,
+ build_type,
+ op0, op1)
+ : fold_build2 (resultcode, build_type,
+ op0, op1);
+ if (final_type != 0)
+ ret = convert (final_type, ret);
+
+ return_build_binary_op:
+ gcc_assert (ret != error_mark_node);
+ protected_set_expr_location (ret, location);
+ return ret;
}
Index: c-omp.c
===================================================================
--- c-omp.c (revision 140798)
+++ c-omp.c (working copy)
@@ -124,7 +124,7 @@ c_finish_omp_atomic (enum tree_code code
/* Take and save the address of the lhs. From then on we'll reference it
via indirection. */
- addr = build_unary_op (ADDR_EXPR, lhs, 0);
+ addr = build_unary_op (input_location, ADDR_EXPR, lhs, 0);
if (addr == error_mark_node)
return error_mark_node;
addr = save_expr (addr);
@@ -137,12 +137,12 @@ c_finish_omp_atomic (enum tree_code code
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, EXPR_LOCATION (addr));
+ lhs = build_indirect_ref (input_location, addr, NULL);
/* There are lots of warnings, errors, and conversions that need to happen
in the course of interpreting a statement. Use the normal mechanisms
to do this, and then take it apart again. */
- x = build_modify_expr (lhs, code, rhs);
+ x = build_modify_expr (input_location, lhs, code, rhs);
if (x == error_mark_node)
return error_mark_node;
gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
@@ -242,7 +242,7 @@ c_finish_omp_for (location_t locus, tree
if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
&& TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
{
- error ("%Hinvalid type for iteration variable %qE", &elocus, decl);
+ error_at (elocus, "invalid type for iteration variable %qE", decl);
fail = true;
}
@@ -255,20 +255,19 @@ c_finish_omp_for (location_t locus, tree
init = DECL_INITIAL (decl);
if (init == NULL)
{
- error ("%H%qE is not initialized", &elocus, decl);
+ error_at (elocus, "%qE is not initialized", decl);
init = integer_zero_node;
fail = true;
}
- init = build_modify_expr (decl, NOP_EXPR, init);
- SET_EXPR_LOCATION (init, elocus);
+ init = build_modify_expr (elocus, decl, NOP_EXPR, init);
}
gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
gcc_assert (TREE_OPERAND (init, 0) == decl);
if (cond == NULL_TREE)
{
- error ("%Hmissing controlling predicate", &elocus);
+ error_at (elocus, "missing controlling predicate");
fail = true;
}
else
@@ -329,14 +328,14 @@ c_finish_omp_for (location_t locus, tree
if (!cond_ok)
{
- error ("%Hinvalid controlling predicate", &elocus);
+ error_at (elocus, "invalid controlling predicate");
fail = true;
}
}
if (incr == NULL_TREE)
{
- error ("%Hmissing increment expression", &elocus);
+ error_at (elocus, "missing increment expression");
fail = true;
}
else
@@ -402,7 +401,7 @@ c_finish_omp_for (location_t locus, tree
}
if (!incr_ok)
{
- error ("%Hinvalid increment expression", &elocus);
+ error_at (elocus, "invalid increment expression");
fail = true;
}
}
Index: c-common.c
===================================================================
--- c-common.c (revision 140798)
+++ c-common.c (working copy)
@@ -3411,7 +3411,7 @@ c_common_truthvalue_conversion (location
: truthvalue_false_node;
case FUNCTION_DECL:
- expr = build_unary_op (ADDR_EXPR, expr, 0);
+ expr = build_unary_op (location, ADDR_EXPR, expr, 0);
/* Fall through. */
case ADDR_EXPR:
@@ -3514,10 +3514,12 @@ c_common_truthvalue_conversion (location
(EXPR_LOCATION (expr),
(TREE_SIDE_EFFECTS (expr)
? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR),
- c_common_truthvalue_conversion (location,
- build_unary_op (REALPART_EXPR, t, 0)),
- c_common_truthvalue_conversion (location,
- build_unary_op (IMAGPART_EXPR, t, 0)),
+ c_common_truthvalue_conversion
+ (location,
+ build_unary_op (location, REALPART_EXPR, t, 0)),
+ c_common_truthvalue_conversion
+ (location,
+ build_unary_op (location, IMAGPART_EXPR, t, 0)),
0));
}
@@ -8182,10 +8184,11 @@ warn_for_unused_label (tree label)
struct gcc_targetcm targetcm = TARGETCM_INITIALIZER;
#endif
-/* Warn for division by zero according to the value of DIVISOR. */
+/* Warn for division by zero according to the value of DIVISOR. LOC
+ is the location of the division operator. */
void
-warn_for_div_by_zero (tree divisor)
+warn_for_div_by_zero (location_t loc, tree divisor)
{
/* If DIVISOR is zero, and has integral or fixed-point type, issue a warning
about division by zero. Do not issue a warning if DIVISOR has a
@@ -8193,7 +8196,7 @@ warn_for_div_by_zero (tree divisor)
generating a NaN. */
if (skip_evaluation == 0
&& (integer_zerop (divisor) || fixed_zerop (divisor)))
- warning (OPT_Wdiv_by_zero, "division by zero");
+ warning_at (loc, OPT_Wdiv_by_zero, "division by zero");
}
/* Subroutine of build_binary_op. Give warnings for comparisons
Index: c-common.h
===================================================================
--- c-common.h (revision 140798)
+++ c-common.h (working copy)
@@ -356,8 +356,8 @@ extern tree add_stmt (tree);
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 *, location_t);
+extern tree build_modify_expr (location_t, tree, enum tree_code, tree);
+extern tree build_indirect_ref (location_t, tree, const char *);
extern int c_expand_decl (tree);
@@ -815,7 +815,7 @@ extern tree build_case_label (tree, tree
/* These functions must be defined by each front-end which implements
a variant of the C language. They are used in c-common.c. */
-extern tree build_unary_op (enum tree_code, tree, int);
+extern tree build_unary_op (location_t, enum tree_code, tree, int);
extern tree build_binary_op (location_t, enum tree_code, tree, tree, int);
extern tree perform_integral_promotions (tree);
@@ -915,7 +915,7 @@ extern void warn_array_subscript_with_ty
extern void warn_about_parentheses (enum tree_code, enum tree_code,
enum tree_code);
extern void warn_for_unused_label (tree label);
-extern void warn_for_div_by_zero (tree divisor);
+extern void warn_for_div_by_zero (location_t, tree divisor);
extern void warn_for_sign_compare (location_t,
tree orig_op0, tree orig_op1,
tree op0, tree op1,
Index: c-parser.c
===================================================================
--- c-parser.c (revision 140798)
+++ c-parser.c (working copy)
@@ -2098,8 +2098,7 @@ c_parser_typeof_specifier (c_parser *par
if (DECL_P (e) || CONSTANT_CLASS_P (e))
e = build1 (NOP_EXPR, void_type_node, e);
- if (CAN_HAVE_LOCATION_P (e))
- SET_EXPR_LOCATION (e, here);
+ protected_set_expr_location (e, here);
add_stmt (e);
}
@@ -3789,8 +3788,7 @@ c_parser_statement_after_labels (c_parse
(recursively) all of the component statements should already have
line numbers assigned. ??? Can we discard no-op statements
earlier? */
- if (stmt && CAN_HAVE_LOCATION_P (stmt))
- SET_EXPR_LOCATION (stmt, loc);
+ protected_set_expr_location (stmt, loc);
parser->in_if_block = in_if_block;
}
@@ -3805,8 +3803,7 @@ c_parser_condition (c_parser *parser)
loc = c_parser_peek_token (parser)->location;
cond = c_objc_common_truthvalue_conversion
(loc, c_parser_expression_conv (parser).value);
- if (CAN_HAVE_LOCATION_P (cond))
- SET_EXPR_LOCATION (cond, loc);
+ protected_set_expr_location (cond, loc);
if (warn_sequence_point)
verify_sequence_points (cond);
return cond;
@@ -4361,8 +4358,10 @@ c_parser_expr_no_commas (c_parser *parse
{
struct c_expr lhs, rhs, ret;
enum tree_code code;
+ location_t op_location;
gcc_assert (!after || c_dialect_objc ());
lhs = c_parser_conditional_expression (parser, after);
+ op_location = c_parser_peek_token (parser)->location;
switch (c_parser_peek_token (parser)->type)
{
case CPP_EQ:
@@ -4404,7 +4403,7 @@ c_parser_expr_no_commas (c_parser *parse
c_parser_consume_token (parser);
rhs = c_parser_expr_no_commas (parser, NULL);
rhs = default_function_array_conversion (rhs);
- ret.value = build_modify_expr (lhs.value, code, rhs.value);
+ ret.value = build_modify_expr (op_location, lhs.value, code, rhs.value);
if (code == NOP_EXPR)
ret.original_code = MODIFY_EXPR;
else
@@ -4439,6 +4438,7 @@ c_parser_conditional_expression (c_parse
cond_loc = c_parser_peek_token (parser)->location;
cond = c_parser_binary_expression (parser, after);
+ protected_set_expr_location (cond.value, cond_loc);
if (c_parser_next_token_is_not (parser, CPP_QUERY))
return cond;
@@ -4836,7 +4836,7 @@ c_parser_unary_expression (c_parser *par
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 *", loc);
+ ret.value = build_indirect_ref (loc, op.value, "unary *");
ret.original_code = ERROR_MARK;
return ret;
case CPP_PLUS:
@@ -5594,8 +5594,9 @@ c_parser_postfix_expression_after_primar
return expr;
}
c_parser_consume_token (parser);
- expr.value = build_component_ref (build_indirect_ref (expr.value,
- "->", loc),
+ expr.value = build_component_ref (build_indirect_ref (loc,
+ expr.value,
+ "->"),
ident);
expr.original_code = ERROR_MARK;
break;
@@ -5603,14 +5604,16 @@ c_parser_postfix_expression_after_primar
/* Postincrement. */
c_parser_consume_token (parser);
expr = default_function_array_conversion (expr);
- expr.value = build_unary_op (POSTINCREMENT_EXPR, expr.value, 0);
+ expr.value = build_unary_op (loc,
+ POSTINCREMENT_EXPR, expr.value, 0);
expr.original_code = ERROR_MARK;
break;
case CPP_MINUS_MINUS:
/* Postdecrement. */
c_parser_consume_token (parser);
expr = default_function_array_conversion (expr);
- expr.value = build_unary_op (POSTDECREMENT_EXPR, expr.value, 0);
+ expr.value = build_unary_op (loc,
+ POSTDECREMENT_EXPR, expr.value, 0);
expr.original_code = ERROR_MARK;
break;
default:
@@ -7594,14 +7597,17 @@ c_parser_omp_for_loop (c_parser *parser,
&& c_parser_peek_2nd_token (parser)->type == CPP_EQ)
{
struct c_expr init_exp;
+ location_t init_loc;
decl = c_parser_postfix_expression (parser).value;
c_parser_require (parser, CPP_EQ, "expected %<=%>");
+ init_loc = c_parser_peek_token (parser)->location;
init_exp = c_parser_expr_no_commas (parser, NULL);
init_exp = default_function_array_conversion (init_exp);
- init = build_modify_expr (decl, NOP_EXPR, init_exp.value);
+ init = build_modify_expr (init_loc,
+ decl, NOP_EXPR, init_exp.value);
init = c_process_expr_stmt (init);
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
@@ -7625,15 +7631,19 @@ c_parser_omp_for_loop (c_parser *parser,
cond = c_parser_expression_conv (parser).value;
cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
- if (CAN_HAVE_LOCATION_P (cond))
- SET_EXPR_LOCATION (cond, cond_loc);
+ protected_set_expr_location (cond, cond_loc);
}
c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
/* Parse the increment expression. */
incr = NULL_TREE;
if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
- incr = c_process_expr_stmt (c_parser_expression (parser).value);
+ {
+ location_t incr_loc = c_parser_peek_token (parser)->location;
+
+ incr = c_process_expr_stmt (c_parser_expression (parser).value);
+ protected_set_expr_location (incr, incr_loc);
+ }
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
if (decl == NULL || decl == error_mark_node || init == error_mark_node)
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [patch] location for unary operators
2008-09-30 21:52 [patch] location for unary operators Aldy Hernandez
@ 2008-10-06 22:26 ` Andrew Pinski
2008-10-06 22:50 ` Aldy Hernandez
[not found] ` <48E2B158.5080401@redhat.com>
1 sibling, 1 reply; 4+ messages in thread
From: Andrew Pinski @ 2008-10-06 22:26 UTC (permalink / raw)
To: Aldy Hernandez, David Edelsohn; +Cc: rth, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1046 bytes --]
On Tue, Sep 30, 2008 at 1:38 PM, Aldy Hernandez <aldyh@redhat.com> wrote:
> Well, the main goal was adding location to unary operators, but there
> were some supporting things that needed to be fixed and cleaned up.
>
> As an aside, now build_unary_op and build_binary_op set the
> EXPR_LCOATION so the caller doesn't have to.
>
> Nothing major here, just the usual fixes for locations.
>
> Tested on x86-64 Linux. GCC tests done. GDB tests are still going.
>
> OK pending GDB tests?
And this broke PowerPC because of the use of build_unary_op and
build_indirect_ref in rs6000-c.c
The following patch fixes the issue.
Applied as obvious after a bootstrap/test on ppc64-linux-gnu with no
regressions.
Note resolve_overloaded_builtin should really take a location_t but
that I assume will be worked on with the patch to explicitly pass the
location_t for call_exprs.
Thanks,
Andrew Pinski
ChangeLog:
* config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin):
Update calls to build_unary_op and build_indirect_ref for location
changes.
[-- Attachment #2: fixbootstrap.diff.txt --]
[-- Type: text/plain, Size: 1323 bytes --]
Index: rs6000-c.c
===================================================================
--- rs6000-c.c (revision 140914)
+++ rs6000-c.c (working copy)
@@ -3097,10 +3097,10 @@ altivec_resolve_overloaded_builtin (tree
innerptrtype = build_pointer_type (arg1_inner_type);
- stmt = build_unary_op (ADDR_EXPR, stmt, 0);
+ stmt = build_unary_op (input_location, ADDR_EXPR, stmt, 0);
stmt = convert (innerptrtype, stmt);
stmt = build_binary_op (input_location, PLUS_EXPR, stmt, arg2, 1);
- stmt = build_indirect_ref (stmt, NULL, input_location);
+ stmt = build_indirect_ref (input_location, stmt, NULL);
return stmt;
}
@@ -3155,10 +3155,10 @@ altivec_resolve_overloaded_builtin (tree
innerptrtype = build_pointer_type (arg1_inner_type);
- stmt = build_unary_op (ADDR_EXPR, stmt, 0);
+ stmt = build_unary_op (input_location, ADDR_EXPR, stmt, 0);
stmt = convert (innerptrtype, stmt);
stmt = build_binary_op (input_location, PLUS_EXPR, stmt, arg2, 1);
- stmt = build_indirect_ref (stmt, NULL, input_location);
+ stmt = build_indirect_ref (input_location, stmt, NULL);
stmt = build2 (MODIFY_EXPR, TREE_TYPE (stmt), stmt,
convert (TREE_TYPE (stmt), arg0));
stmt = build2 (COMPOUND_EXPR, arg1_type, stmt, decl);
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [patch] location for unary operators
[not found] ` <48E2B158.5080401@redhat.com>
@ 2008-10-06 22:41 ` Aldy Hernandez
0 siblings, 0 replies; 4+ messages in thread
From: Aldy Hernandez @ 2008-10-06 22:41 UTC (permalink / raw)
To: Richard Henderson; +Cc: gcc-patches, drow
> Ok.
>
>
> r~
Hi folks.
Sorry I took so long to commit this (just did), but the patch caused a
regression on the GDB testsuite that I wanted to address.
With more location granularity in expressions, arguments in function
calls now have the location of the actual argument, not the beginning of
the function call. For example:
line0 SOME-STATEMENT
line1 funccall(arg1,
line2 x=arg2);
With the patch in question, ``x=arg2'' now has a location of line #2
(not line#1 as before), which is confusing to the debugger. For
example, if we put a breakpoint on SOME-STATEMENT, on x86 the debugger
will stop right after line0, which is now line2 because code generation
has evaluated ``x=arg2'' before calling ``funccall''. Needless to say,
this is highly confusing, especially with multiple complex arguments.
Daniel beat me over the head explaining why "correct" location doesn't
necessarily mean good debug info. There was some discussion on using
the ``is_stmt'' DWARF flag to mark the beginning/end of statements.
However, this being stage3 and all, and me being inherently lazy... I
figured it is easier to make gimplify_arg() set the location from the
CALL_EXPR (patch below), thus ensuring that arguments have the location
of the original call.
If we encounter problems in which we need the original location (for
diagnostics in the gimplifier or later), but the resulting debug
information is not useful/accurate, we may have to use a DWARF flag, or
alternate solution. But this alas, will need a new branch.
For now, this works wonders.
In addition to the patch Richard approved, I am committing the patch
below tweaking gimplify_arg(). It was tested on x86-64 Linux for both
the GCC and GDB testsuite.
* gimplify.c (gimplify_arg): Add location argument. Use it.
(gimplify_call_expr): Pass location to gimplify_arg.
(gimplify_modify_expr_to_memcpy): Same.
(gimplify_modify_expr_to_memset): Same.
Index: gimplify.c
===================================================================
--- gimplify.c (revision 140913)
+++ gimplify.c (working copy)
@@ -2238,10 +2238,11 @@ maybe_with_size_expr (tree *expr_p)
/* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
- Store any side-effects in PRE_P. */
+ Store any side-effects in PRE_P. CALL_LOCATION is the location of
+ the CALL_EXPR. */
static enum gimplify_status
-gimplify_arg (tree *arg_p, gimple_seq *pre_p)
+gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location)
{
bool (*test) (tree);
fallback_t fb;
@@ -2259,6 +2260,10 @@ gimplify_arg (tree *arg_p, gimple_seq *p
/* If this is a variable sized type, we must remember the size. */
maybe_with_size_expr (arg_p);
+ /* Make sure arguments have the same location as the function call
+ itself. */
+ protected_set_expr_location (*arg_p, call_location);
+
/* There is a sequence point before a function call. Side effects in
the argument list must occur before the actual call. So, when
gimplifying arguments, force gimplify_expr to use an internal
@@ -2448,7 +2453,8 @@ gimplify_call_expr (tree *expr_p, gimple
be the plain PARM_DECL. */
if ((i != 1) || !builtin_va_start_p)
{
- t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p);
+ t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
+ EXPR_LOCATION (*expr_p));
if (t == GS_ERROR)
ret = GS_ERROR;
@@ -3095,10 +3101,10 @@ gimplify_modify_expr_to_memcpy (tree *ex
from = TREE_OPERAND (*expr_p, 1);
from_ptr = build_fold_addr_expr (from);
- gimplify_arg (&from_ptr, seq_p);
+ gimplify_arg (&from_ptr, seq_p, EXPR_LOCATION (*expr_p));
to_ptr = build_fold_addr_expr (to);
- gimplify_arg (&to_ptr, seq_p);
+ gimplify_arg (&to_ptr, seq_p, EXPR_LOCATION (*expr_p));
t = implicit_built_in_decls[BUILT_IN_MEMCPY];
@@ -3145,7 +3151,7 @@ gimplify_modify_expr_to_memset (tree *ex
to = TREE_OPERAND (*expr_p, 0);
to_ptr = build_fold_addr_expr (to);
- gimplify_arg (&to_ptr, seq_p);
+ gimplify_arg (&to_ptr, seq_p, EXPR_LOCATION (*expr_p));
t = implicit_built_in_decls[BUILT_IN_MEMSET];
gs = gimple_build_call (t, 3, to_ptr, integer_zero_node, size);
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [patch] location for unary operators
2008-10-06 22:26 ` Andrew Pinski
@ 2008-10-06 22:50 ` Aldy Hernandez
0 siblings, 0 replies; 4+ messages in thread
From: Aldy Hernandez @ 2008-10-06 22:50 UTC (permalink / raw)
To: Andrew Pinski; +Cc: David Edelsohn, rth, gcc-patches
> And this broke PowerPC because of the use of build_unary_op and
> build_indirect_ref in rs6000-c.c
>
> The following patch fixes the issue.
> Applied as obvious after a bootstrap/test on ppc64-linux-gnu with no
> regressions.
Thank you.
> Note resolve_overloaded_builtin should really take a location_t but
> that I assume will be worked on with the patch to explicitly pass the
> location_t for call_exprs.
Yes, there is plenty of location work left to do.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-10-06 22:41 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-09-30 21:52 [patch] location for unary operators Aldy Hernandez
2008-10-06 22:26 ` Andrew Pinski
2008-10-06 22:50 ` Aldy Hernandez
[not found] ` <48E2B158.5080401@redhat.com>
2008-10-06 22:41 ` Aldy Hernandez
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).