From: jakub Date: Mon, 12 Apr 2010 13:27:07 +0000 (+0000) Subject: PR bootstrap/43699 X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=c864294a4604fbd40f31f7932a78754af8c25e25 PR bootstrap/43699 * c-typeck.c (c_process_expr_stmt): Call mark_exp_read even for exprs satisfying handled_component_p. * gcc.dg/Wunused-var-7.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158224 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0d4284cca78..88c990397be 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-04-12 Jakub Jelinek + + PR bootstrap/43699 + * c-typeck.c (c_process_expr_stmt): Call mark_exp_read even + for exprs satisfying handled_component_p. + 2010-04-12 Eric Botcazou * expr.c (categorize_ctor_elements_1): Properly count sub-elements of diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 326fa86ee32..681c0e42df9 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -29,17 +29,21 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "tm.h" +#include "rtl.h" #include "tree.h" #include "langhooks.h" #include "c-tree.h" #include "c-lang.h" +#include "tm_p.h" #include "flags.h" #include "output.h" #include "expr.h" #include "toplev.h" #include "intl.h" +#include "ggc.h" #include "target.h" #include "tree-iterator.h" +#include "gimple.h" #include "tree-flow.h" /* Possible cases of implicit bad conversions. Used to select @@ -93,15 +97,14 @@ static int spelling_length (void); static char *print_spelling (char *); static void warning_init (int, const char *); static tree digest_init (location_t, tree, tree, tree, bool, bool, int); -static void output_init_element (tree, tree, bool, tree, tree, int, bool, - struct obstack *); -static void output_pending_init_elements (int, struct obstack *); -static int set_designator (int, struct obstack *); -static void push_range_stack (tree, struct obstack *); -static void add_pending_init (tree, tree, tree, bool, struct obstack *); -static void set_nonincremental_init (struct obstack *); -static void set_nonincremental_init_from_string (tree, struct obstack *); -static tree find_init_member (tree, struct obstack *); +static void output_init_element (tree, tree, bool, tree, tree, int, bool); +static void output_pending_init_elements (int); +static int set_designator (int); +static void push_range_stack (tree); +static void add_pending_init (tree, tree, tree, bool); +static void set_nonincremental_init (void); +static void set_nonincremental_init_from_string (tree); +static tree find_init_member (tree); static void readonly_error (tree, enum lvalue_use); static void readonly_warning (tree, enum lvalue_use); static int lvalue_or_else (const_tree, enum lvalue_use); @@ -1949,7 +1952,7 @@ default_conversion (tree exp) return exp; } -/* Look up COMPONENT in a structure or union TYPE. +/* Look up COMPONENT in a structure or union DECL. If the component name is not found, returns NULL_TREE. Otherwise, the return value is a TREE_LIST, with each TREE_VALUE a FIELD_DECL @@ -1959,8 +1962,9 @@ default_conversion (tree exp) unions, the list steps down the chain to the component. */ static tree -lookup_field (tree type, tree component) +lookup_field (tree decl, tree component) { + tree type = TREE_TYPE (decl); tree field; /* If TYPE_LANG_SPECIFIC is set, then it is a sorted array of pointers @@ -1990,7 +1994,7 @@ lookup_field (tree type, tree component) if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) { - tree anon = lookup_field (TREE_TYPE (field), component); + tree anon = lookup_field (field, component); if (anon) return tree_cons (NULL_TREE, field, anon); @@ -2026,7 +2030,7 @@ lookup_field (tree type, tree component) && (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE)) { - tree anon = lookup_field (TREE_TYPE (field), component); + tree anon = lookup_field (field, component); if (anon) return tree_cons (NULL_TREE, field, anon); @@ -2069,7 +2073,7 @@ build_component_ref (location_t loc, tree datum, tree component) return error_mark_node; } - field = lookup_field (type, component); + field = lookup_field (datum, component); if (!field) { @@ -6429,7 +6433,7 @@ really_start_incremental_init (tree type) IMPLICIT is 1 (or 2 if the push is because of designator list). */ void -push_init_level (int implicit, struct obstack * braced_init_obstack) +push_init_level (int implicit) { struct constructor_stack *p; tree value = NULL_TREE; @@ -6447,14 +6451,12 @@ push_init_level (int implicit, struct obstack * braced_init_obstack) if ((TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) && constructor_fields == 0) - process_init_element (pop_init_level (1, braced_init_obstack), - true, braced_init_obstack); + process_init_element (pop_init_level (1), true); else if (TREE_CODE (constructor_type) == ARRAY_TYPE && constructor_max_index && tree_int_cst_lt (constructor_max_index, constructor_index)) - process_init_element (pop_init_level (1, braced_init_obstack), - true, braced_init_obstack); + process_init_element (pop_init_level (1), true); else break; } @@ -6467,9 +6469,9 @@ push_init_level (int implicit, struct obstack * braced_init_obstack) if ((TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) && constructor_fields) - value = find_init_member (constructor_fields, braced_init_obstack); + value = find_init_member (constructor_fields); else if (TREE_CODE (constructor_type) == ARRAY_TYPE) - value = find_init_member (constructor_index, braced_init_obstack); + value = find_init_member (constructor_index); } p = XNEW (struct constructor_stack); @@ -6555,7 +6557,7 @@ push_init_level (int implicit, struct obstack * braced_init_obstack) if (!VEC_empty (constructor_elt, constructor_elements) && (TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == ARRAY_TYPE)) - set_nonincremental_init (braced_init_obstack); + set_nonincremental_init (); } if (implicit == 1 && warn_missing_braces && !missing_braces_mentioned) @@ -6616,7 +6618,7 @@ push_init_level (int implicit, struct obstack * braced_init_obstack) /* We need to split the char/wchar array into individual characters, so that we don't have to special case it everywhere. */ - set_nonincremental_init_from_string (value, braced_init_obstack); + set_nonincremental_init_from_string (value); } } else @@ -6640,7 +6642,7 @@ push_init_level (int implicit, struct obstack * braced_init_obstack) Otherwise, return a CONSTRUCTOR expression as the value. */ struct c_expr -pop_init_level (int implicit, struct obstack * braced_init_obstack) +pop_init_level (int implicit) { struct constructor_stack *p; struct c_expr ret; @@ -6653,16 +6655,14 @@ pop_init_level (int implicit, struct obstack * braced_init_obstack) /* When we come to an explicit close brace, pop any inner levels that didn't have explicit braces. */ while (constructor_stack->implicit) - { - process_init_element (pop_init_level (1, braced_init_obstack), - true, braced_init_obstack); - } + process_init_element (pop_init_level (1), true); + gcc_assert (!constructor_range_stack); } /* Now output all pending elements. */ constructor_incremental = 1; - output_pending_init_elements (1, braced_init_obstack); + output_pending_init_elements (1); p = constructor_stack; @@ -6803,7 +6803,7 @@ pop_init_level (int implicit, struct obstack * braced_init_obstack) ARRAY argument is nonzero for array ranges. Returns zero for success. */ static int -set_designator (int array, struct obstack * braced_init_obstack) +set_designator (int array) { tree subtype; enum tree_code subcode; @@ -6825,10 +6825,7 @@ set_designator (int array, struct obstack * braced_init_obstack) /* Designator list starts at the level of closest explicit braces. */ while (constructor_stack->implicit) - { - process_init_element (pop_init_level (1, braced_init_obstack), - true, braced_init_obstack); - } + process_init_element (pop_init_level (1), true); constructor_designated = 1; return 0; } @@ -6861,7 +6858,7 @@ set_designator (int array, struct obstack * braced_init_obstack) } constructor_designated = 1; - push_init_level (2, braced_init_obstack); + push_init_level (2); return 0; } @@ -6870,13 +6867,11 @@ set_designator (int array, struct obstack * braced_init_obstack) NULL_TREE if there is no range designator at this level. */ static void -push_range_stack (tree range_end, struct obstack * braced_init_obstack) +push_range_stack (tree range_end) { struct constructor_range_stack *p; - p = (struct constructor_range_stack *) - obstack_alloc (braced_init_obstack, - sizeof (struct constructor_range_stack)); + p = GGC_NEW (struct constructor_range_stack); p->prev = constructor_range_stack; p->next = 0; p->fields = constructor_fields; @@ -6894,10 +6889,9 @@ push_range_stack (tree range_end, struct obstack * braced_init_obstack) of indices, running from FIRST through LAST. */ void -set_init_index (tree first, tree last, - struct obstack * braced_init_obstack) +set_init_index (tree first, tree last) { - if (set_designator (1, braced_init_obstack)) + if (set_designator (1)) return; designator_erroneous = 1; @@ -6969,18 +6963,18 @@ set_init_index (tree first, tree last, designator_depth++; designator_erroneous = 0; if (constructor_range_stack || last) - push_range_stack (last, braced_init_obstack); + push_range_stack (last); } } /* Within a struct initializer, specify the next field to be initialized. */ void -set_init_label (tree fieldname, struct obstack * braced_init_obstack) +set_init_label (tree fieldname) { - tree field; + tree tail; - if (set_designator (0, braced_init_obstack)) + if (set_designator (0)) return; designator_erroneous = 1; @@ -6992,26 +6986,23 @@ set_init_label (tree fieldname, struct obstack * braced_init_obstack) return; } - field = lookup_field (constructor_type, fieldname); + for (tail = TYPE_FIELDS (constructor_type); tail; + tail = TREE_CHAIN (tail)) + { + if (DECL_NAME (tail) == fieldname) + break; + } - if (field == 0) + if (tail == 0) error ("unknown field %qE specified in initializer", fieldname); else - do - { - constructor_fields = TREE_VALUE (field); - designator_depth++; - designator_erroneous = 0; - if (constructor_range_stack) - push_range_stack (NULL_TREE, braced_init_obstack); - field = TREE_CHAIN (field); - if (field) - { - if (set_designator (0, braced_init_obstack)) - return; - } - } - while (field != NULL_TREE); + { + constructor_fields = tail; + designator_depth++; + designator_erroneous = 0; + if (constructor_range_stack) + push_range_stack (NULL_TREE); + } } /* Add a new initializer to the tree of pending initializers. PURPOSE @@ -7025,8 +7016,7 @@ set_init_label (tree fieldname, struct obstack * braced_init_obstack) existing initializer. */ static void -add_pending_init (tree purpose, tree value, tree origtype, bool implicit, - struct obstack * braced_init_obstack) +add_pending_init (tree purpose, tree value, tree origtype, bool implicit) { struct init_node *p, **q, *r; @@ -7085,8 +7075,7 @@ add_pending_init (tree purpose, tree value, tree origtype, bool implicit, } } - r = (struct init_node *) obstack_alloc (braced_init_obstack, - sizeof (struct init_node)); + r = GGC_NEW (struct init_node); r->purpose = purpose; r->value = value; r->origtype = origtype; @@ -7255,7 +7244,7 @@ add_pending_init (tree purpose, tree value, tree origtype, bool implicit, /* Build AVL tree from a sorted chain. */ static void -set_nonincremental_init (struct obstack * braced_init_obstack) +set_nonincremental_init (void) { unsigned HOST_WIDE_INT ix; tree index, value; @@ -7265,10 +7254,7 @@ set_nonincremental_init (struct obstack * braced_init_obstack) return; FOR_EACH_CONSTRUCTOR_ELT (constructor_elements, ix, index, value) - { - add_pending_init (index, value, NULL_TREE, false, - braced_init_obstack); - } + add_pending_init (index, value, NULL_TREE, false); constructor_elements = 0; if (TREE_CODE (constructor_type) == RECORD_TYPE) { @@ -7295,8 +7281,7 @@ set_nonincremental_init (struct obstack * braced_init_obstack) /* Build AVL tree from a string constant. */ static void -set_nonincremental_init_from_string (tree str, - struct obstack * braced_init_obstack) +set_nonincremental_init_from_string (tree str) { tree value, purpose, type; HOST_WIDE_INT val[2]; @@ -7359,8 +7344,7 @@ set_nonincremental_init_from_string (tree str, } value = build_int_cst_wide (type, val[1], val[0]); - add_pending_init (purpose, value, NULL_TREE, false, - braced_init_obstack); + add_pending_init (purpose, value, NULL_TREE, false); } constructor_incremental = 0; @@ -7370,7 +7354,7 @@ set_nonincremental_init_from_string (tree str, not initialized yet. */ static tree -find_init_member (tree field, struct obstack * braced_init_obstack) +find_init_member (tree field) { struct init_node *p; @@ -7378,7 +7362,7 @@ find_init_member (tree field, struct obstack * braced_init_obstack) { if (constructor_incremental && tree_int_cst_lt (field, constructor_unfilled_index)) - set_nonincremental_init (braced_init_obstack); + set_nonincremental_init (); p = constructor_pending_elts; while (p) @@ -7399,7 +7383,7 @@ find_init_member (tree field, struct obstack * braced_init_obstack) && (!constructor_unfilled_fields || tree_int_cst_lt (bitpos, bit_position (constructor_unfilled_fields)))) - set_nonincremental_init (braced_init_obstack); + set_nonincremental_init (); p = constructor_pending_elts; while (p) @@ -7443,8 +7427,7 @@ find_init_member (tree field, struct obstack * braced_init_obstack) static void output_init_element (tree value, tree origtype, bool strict_string, tree type, - tree field, int pending, bool implicit, - struct obstack * braced_init_obstack) + tree field, int pending, bool implicit) { tree semantic_type = NULL_TREE; constructor_elt *celt; @@ -7561,10 +7544,9 @@ output_init_element (tree value, tree origtype, bool strict_string, tree type, { if (constructor_incremental && tree_int_cst_lt (field, constructor_unfilled_index)) - set_nonincremental_init (braced_init_obstack); + set_nonincremental_init (); - add_pending_init (field, value, origtype, implicit, - braced_init_obstack); + add_pending_init (field, value, origtype, implicit); return; } else if (TREE_CODE (constructor_type) == RECORD_TYPE @@ -7577,7 +7559,7 @@ output_init_element (tree value, tree origtype, bool strict_string, tree type, if (constructor_incremental) { if (!constructor_unfilled_fields) - set_nonincremental_init (braced_init_obstack); + set_nonincremental_init (); else { tree bitpos, unfillpos; @@ -7586,12 +7568,11 @@ output_init_element (tree value, tree origtype, bool strict_string, tree type, unfillpos = bit_position (constructor_unfilled_fields); if (tree_int_cst_lt (bitpos, unfillpos)) - set_nonincremental_init (braced_init_obstack); + set_nonincremental_init (); } } - add_pending_init (field, value, origtype, implicit, - braced_init_obstack); + add_pending_init (field, value, origtype, implicit); return; } else if (TREE_CODE (constructor_type) == UNION_TYPE @@ -7640,7 +7621,7 @@ output_init_element (tree value, tree origtype, bool strict_string, tree type, /* Now output any pending elements which have become next. */ if (pending) - output_pending_init_elements (0, braced_init_obstack); + output_pending_init_elements (0); } /* Output any pending elements which have become next. @@ -7653,8 +7634,9 @@ output_init_element (tree value, tree origtype, bool strict_string, tree type, If ALL is 1, we output space as necessary so that we can output all the pending elements. */ + static void -output_pending_init_elements (int all, struct obstack * braced_init_obstack) +output_pending_init_elements (int all) { struct init_node *elt = constructor_pending_elts; tree next; @@ -7675,8 +7657,7 @@ output_pending_init_elements (int all, struct obstack * braced_init_obstack) constructor_unfilled_index)) output_init_element (elt->value, elt->origtype, true, TREE_TYPE (constructor_type), - constructor_unfilled_index, 0, false, - braced_init_obstack); + constructor_unfilled_index, 0, false); else if (tree_int_cst_lt (constructor_unfilled_index, elt->purpose)) { @@ -7730,8 +7711,7 @@ output_pending_init_elements (int all, struct obstack * braced_init_obstack) constructor_unfilled_fields = elt->purpose; output_init_element (elt->value, elt->origtype, true, TREE_TYPE (elt->purpose), - elt->purpose, 0, false, - braced_init_obstack); + elt->purpose, 0, false); } else if (tree_int_cst_lt (ctor_unfilled_bitpos, elt_bitpos)) { @@ -7802,8 +7782,7 @@ output_pending_init_elements (int all, struct obstack * braced_init_obstack) existing initializer. */ void -process_init_element (struct c_expr value, bool implicit, - struct obstack * braced_init_obstack) +process_init_element (struct c_expr value, bool implicit) { tree orig_value = value.value; int string_flag = orig_value != 0 && TREE_CODE (orig_value) == STRING_CST; @@ -7844,15 +7823,13 @@ process_init_element (struct c_expr value, bool implicit, if ((TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) && constructor_fields == 0) - process_init_element (pop_init_level (1, braced_init_obstack), - true, braced_init_obstack); + process_init_element (pop_init_level (1), true); else if ((TREE_CODE (constructor_type) == ARRAY_TYPE || TREE_CODE (constructor_type) == VECTOR_TYPE) && (constructor_max_index == 0 || tree_int_cst_lt (constructor_max_index, constructor_index))) - process_init_element (pop_init_level (1, braced_init_obstack), - true, braced_init_obstack); + process_init_element (pop_init_level (1), true); else break; } @@ -7922,7 +7899,7 @@ process_init_element (struct c_expr value, bool implicit, && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE || fieldcode == UNION_TYPE || fieldcode == VECTOR_TYPE)) { - push_init_level (1, braced_init_obstack); + push_init_level (1); continue; } @@ -7931,8 +7908,7 @@ process_init_element (struct c_expr value, bool implicit, push_member_name (constructor_fields); output_init_element (value.value, value.original_type, strict_string, fieldtype, - constructor_fields, 1, implicit, - braced_init_obstack); + constructor_fields, 1, implicit); RESTORE_SPELLING_DEPTH (constructor_depth); } else @@ -8014,7 +7990,7 @@ process_init_element (struct c_expr value, bool implicit, && (fieldcode == RECORD_TYPE || fieldcode == ARRAY_TYPE || fieldcode == UNION_TYPE || fieldcode == VECTOR_TYPE)) { - push_init_level (1, braced_init_obstack); + push_init_level (1); continue; } @@ -8023,8 +7999,7 @@ process_init_element (struct c_expr value, bool implicit, push_member_name (constructor_fields); output_init_element (value.value, value.original_type, strict_string, fieldtype, - constructor_fields, 1, implicit, - braced_init_obstack); + constructor_fields, 1, implicit); RESTORE_SPELLING_DEPTH (constructor_depth); } else @@ -8056,7 +8031,7 @@ process_init_element (struct c_expr value, bool implicit, && (eltcode == RECORD_TYPE || eltcode == ARRAY_TYPE || eltcode == UNION_TYPE || eltcode == VECTOR_TYPE)) { - push_init_level (1, braced_init_obstack); + push_init_level (1); continue; } @@ -8075,8 +8050,7 @@ process_init_element (struct c_expr value, bool implicit, push_array_bounds (tree_low_cst (constructor_index, 1)); output_init_element (value.value, value.original_type, strict_string, elttype, - constructor_index, 1, implicit, - braced_init_obstack); + constructor_index, 1, implicit); RESTORE_SPELLING_DEPTH (constructor_depth); } @@ -8110,8 +8084,7 @@ process_init_element (struct c_expr value, bool implicit, elttype = TYPE_MAIN_VARIANT (constructor_type); output_init_element (value.value, value.original_type, strict_string, elttype, - constructor_index, 1, implicit, - braced_init_obstack); + constructor_index, 1, implicit); } constructor_index @@ -8139,8 +8112,7 @@ process_init_element (struct c_expr value, bool implicit, if (value.value) output_init_element (value.value, value.original_type, strict_string, constructor_type, - NULL_TREE, 1, implicit, - braced_init_obstack); + NULL_TREE, 1, implicit); constructor_fields = 0; } @@ -8156,17 +8128,14 @@ process_init_element (struct c_expr value, bool implicit, while (constructor_stack != range_stack->stack) { gcc_assert (constructor_stack->implicit); - process_init_element (pop_init_level (1, - braced_init_obstack), - true, braced_init_obstack); + process_init_element (pop_init_level (1), true); } for (p = range_stack; !p->range_end || tree_int_cst_equal (p->index, p->range_end); p = p->prev) { gcc_assert (constructor_stack->implicit); - process_init_element (pop_init_level (1, braced_init_obstack), - true, braced_init_obstack); + process_init_element (pop_init_level (1), true); } p->index = size_binop_loc (input_location, @@ -8186,7 +8155,7 @@ process_init_element (struct c_expr value, bool implicit, p = p->next; if (!p) break; - push_init_level (2, braced_init_obstack); + push_init_level (2); p->stack = constructor_stack; if (p->range_end && tree_int_cst_equal (p->index, p->range_end)) p->index = p->range_start; @@ -8837,8 +8806,6 @@ emit_side_effect_warnings (location_t loc, tree expr) tree c_process_expr_stmt (location_t loc, tree expr) { - tree exprv; - if (!expr) return NULL_TREE; @@ -8859,17 +8826,13 @@ c_process_expr_stmt (location_t loc, tree expr) && warn_unused_value) emit_side_effect_warnings (loc, expr); - exprv = expr; - while (TREE_CODE (exprv) == COMPOUND_EXPR) - exprv = TREE_OPERAND (exprv, 1); - if (DECL_P (exprv) || handled_component_p (exprv)) - mark_exp_read (exprv); + if (DECL_P (expr) || handled_component_p (expr)) + mark_exp_read (expr); /* If the expression is not of a type to which we cannot assign a line number, wrap the thing in a no-op NOP_EXPR. */ if (DECL_P (expr) || CONSTANT_CLASS_P (expr)) { - mark_exp_read (expr); expr = build1 (NOP_EXPR, TREE_TYPE (expr), expr); SET_EXPR_LOCATION (expr, loc); } @@ -9507,46 +9470,6 @@ build_binary_op (location_t location, enum tree_code code, && (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == FIXED_POINT_TYPE || code1 == COMPLEX_TYPE)) short_compare = 1; - else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1)) - { - if (TREE_CODE (op0) == ADDR_EXPR - && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0))) - { - if (code == EQ_EXPR) - warning_at (location, - OPT_Waddress, - "the comparison will always evaluate as % " - "for the address of %qD will never be NULL", - TREE_OPERAND (op0, 0)); - else - warning_at (location, - OPT_Waddress, - "the comparison will always evaluate as % " - "for the address of %qD will never be NULL", - TREE_OPERAND (op0, 0)); - } - result_type = type0; - } - else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0)) - { - if (TREE_CODE (op1) == ADDR_EXPR - && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0))) - { - if (code == EQ_EXPR) - warning_at (location, - OPT_Waddress, - "the comparison will always evaluate as % " - "for the address of %qD will never be NULL", - TREE_OPERAND (op1, 0)); - else - warning_at (location, - OPT_Waddress, - "the comparison will always evaluate as % " - "for the address of %qD will never be NULL", - TREE_OPERAND (op1, 0)); - } - result_type = type1; - } else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) { tree tt0 = TREE_TYPE (type0); @@ -9560,6 +9483,10 @@ build_binary_op (location_t location, enum tree_code code, and both must be object or both incomplete. */ if (comp_target_types (location, type0, type1)) result_type = common_pointer_type (type0, type1); + else if (null_pointer_constant_p (orig_op0)) + result_type = type1; + else if (null_pointer_constant_p (orig_op1)) + result_type = type0; else if (!addr_space_superset (as0, as1, &as_common)) { error_at (location, "comparison of pointers to " @@ -9591,6 +9518,24 @@ build_binary_op (location_t location, enum tree_code code, (build_qualified_type (void_type_node, qual)); } } + else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1)) + { + if (TREE_CODE (op0) == ADDR_EXPR + && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0))) + warning_at (location, + OPT_Waddress, "the address of %qD will never be NULL", + TREE_OPERAND (op0, 0)); + result_type = type0; + } + else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0)) + { + if (TREE_CODE (op1) == ADDR_EXPR + && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0))) + warning_at (location, + OPT_Waddress, "the address of %qD will never be NULL", + TREE_OPERAND (op1, 0)); + result_type = type1; + } else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { result_type = type0; @@ -9629,11 +9574,6 @@ build_binary_op (location_t location, enum tree_code code, else if (TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE) pedwarn (location, OPT_pedantic, "ISO C forbids " "ordered comparisons of pointers to functions"); - else if (null_pointer_constant_p (orig_op0) - || null_pointer_constant_p (orig_op1)) - warning_at (location, OPT_Wextra, - "ordered comparison of pointer with null pointer"); - } else if (!addr_space_superset (as0, as1, &as_common)) { @@ -9658,17 +9598,13 @@ build_binary_op (location_t location, enum tree_code code, "ordered comparison of pointer with integer zero"); else if (extra_warnings) warning_at (location, OPT_Wextra, - "ordered comparison of pointer with integer zero"); + "ordered comparison of pointer with integer zero"); } else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0)) { result_type = type1; - if (pedantic) - pedwarn (location, OPT_pedantic, - "ordered comparison of pointer with integer zero"); - else if (extra_warnings) - warning_at (location, OPT_Wextra, - "ordered comparison of pointer with integer zero"); + pedwarn (location, OPT_pedantic, + "ordered comparison of pointer with integer zero"); } else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fe70fb42424..642f08525ba 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2010-04-12 Jakub Jelinek + PR bootstrap/43699 + * gcc.dg/Wunused-var-7.c: New test. + PR tree-optimization/43560 * gcc.c-torture/execute/pr43560.c: New test. diff --git a/gcc/testsuite/gcc.dg/Wunused-var-7.c b/gcc/testsuite/gcc.dg/Wunused-var-7.c new file mode 100644 index 00000000000..e82e708deae --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wunused-var-7.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-Wunused -W" } */ + +int +f1 (unsigned int x) +{ + int c = ({ union { unsigned int a; int b; } u; u.a = x; u.b; }); + return c; +} + +void +f2 (void) +{ + struct S { int i; } a; + int b[1]; + a.i = 1; + a.i; /* { dg-warning "with no effect" } */ + b[0] = 1; + b[0]; /* { dg-warning "with no effect" } */ +} + +void +f3 (void) +{ + struct S { int i; } a; /* { dg-warning "set but not used" } */ + int b[1]; /* { dg-warning "set but not used" } */ + a.i = 1; + b[0] = 1; +}