OSDN Git Service

PR bootstrap/43699
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 12 Apr 2010 13:27:07 +0000 (13:27 +0000)
committerMasaki Muranaka <monaka@monami-software.com>
Sun, 23 May 2010 00:56:16 +0000 (09:56 +0900)
* 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

gcc/ChangeLog
gcc/c-typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/Wunused-var-7.c [new file with mode: 0644]

index 0d4284c..88c9903 100644 (file)
@@ -1,3 +1,9 @@
+2010-04-12  Jakub Jelinek  <jakub@redhat.com>
+
+       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  <ebotcazou@adacore.com>
 
        * expr.c (categorize_ctor_elements_1): Properly count sub-elements of
index 326fa86..681c0e4 100644 (file)
@@ -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;
 }
 \f
-/* 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);
+    }
 }
 \f
 /* 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 %<false%> "
-                           "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 %<true%> "
-                           "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 %<false%> "
-                           "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 %<true%> "
-                           "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)
        {
index fe70fb4..642f085 100644 (file)
@@ -1,5 +1,8 @@
 2010-04-12  Jakub Jelinek  <jakub@redhat.com>
 
+       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 (file)
index 0000000..e82e708
--- /dev/null
@@ -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;
+}