OSDN Git Service

* c-typeck.c (comptypes, tagged_types_tu_compatible_p,
[pf3gnuchains/gcc-fork.git] / gcc / c-typeck.c
index bf48094..c1a262b 100644 (file)
@@ -50,11 +50,14 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    message within this initializer.  */
 static int missing_braces_mentioned;
 
+static int require_constant_value;
+static int require_constant_elements;
+
 static tree qualify_type (tree, tree);
-static int tagged_types_tu_compatible_p (tree, tree, int);
+static int tagged_types_tu_compatible_p (tree, tree);
 static int comp_target_types (tree, tree, int);
-static int function_types_compatible_p (tree, tree, int);
-static int type_lists_compatible_p (tree, tree, int);
+static int function_types_compatible_p (tree, tree);
+static int type_lists_compatible_p (tree, tree);
 static tree decl_constant_value_for_broken_optimization (tree);
 static tree default_function_array_conversion (tree);
 static tree lookup_field (tree, tree);
@@ -80,6 +83,7 @@ static void add_pending_init (tree, tree);
 static void set_nonincremental_init (void);
 static void set_nonincremental_init_from_string (tree);
 static tree find_init_member (tree);
+static int lvalue_or_else (tree, const char *);
 \f
 /* Do `exp = require_complete_type (exp);' to make sure exp
    does not have an incomplete type.  (That includes void types.)  */
@@ -199,19 +203,14 @@ qualify_type (tree type, tree like)
                                 TYPE_QUALS (type) | TYPE_QUALS (like));
 }
 \f
-/* Return the composite type of two compatible types, or the common
-   type for two arithmetic types under the usual arithmetic
-   conversions.
+/* Return the composite type of two compatible types.
 
-   Unless both types are arithmetic types, we assume that comptypes
-   has already been done and returned 1; if that isn't so, this may
-   crash.  In particular, we assume that qualifiers match.
-
-   This is the type for the result of most arithmetic operations
-   if the operands have the given two types.  */
+   We assume that comptypes has already been done and returned
+   nonzero; if that isn't so, this may crash.  In particular, we
+   assume that qualifiers match.  */
 
 tree
-common_type (tree t1, tree t2)
+composite_type (tree t1, tree t2)
 {
   enum tree_code code1;
   enum tree_code code2;
@@ -227,126 +226,40 @@ common_type (tree t1, tree t2)
   if (t2 == error_mark_node)
     return t1;
 
+  code1 = TREE_CODE (t1);
+  code2 = TREE_CODE (t2);
+
   /* Merge the attributes.  */
   attributes = targetm.merge_type_attributes (t1, t2);
 
-  /* Treat an enum type as the unsigned integer type of the same width.  */
-
-  if (TREE_CODE (t1) == ENUMERAL_TYPE)
-    t1 = c_common_type_for_size (TYPE_PRECISION (t1), 1);
-  if (TREE_CODE (t2) == ENUMERAL_TYPE)
-    t2 = c_common_type_for_size (TYPE_PRECISION (t2), 1);
+  /* If one is an enumerated type and the other is the compatible
+     integer type, the composite type might be either of the two
+     (DR#013 question 3).  For consistency, use the enumerated type as
+     the composite type.  */
 
-  code1 = TREE_CODE (t1);
-  code2 = TREE_CODE (t2);
-
-  /* If one type is complex, form the common type of the non-complex
-     components, then make that complex.  Use T1 or T2 if it is the
-     required type.  */
-  if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
-    {
-      tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
-      tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
-      tree subtype = common_type (subtype1, subtype2);
+  if (code1 == ENUMERAL_TYPE && code2 == INTEGER_TYPE)
+    return t1;
+  if (code2 == ENUMERAL_TYPE && code1 == INTEGER_TYPE)
+    return t2;
 
-      if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
-       return build_type_attribute_variant (t1, attributes);
-      else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
-       return build_type_attribute_variant (t2, attributes);
-      else
-       return build_type_attribute_variant (build_complex_type (subtype),
-                                            attributes);
-    }
+  if (code1 != code2)
+    abort ();
 
   switch (code1)
     {
-    case INTEGER_TYPE:
-    case REAL_TYPE:
-      /* If only one is real, use it as the result.  */
-
-      if (code1 == REAL_TYPE && code2 != REAL_TYPE)
-       return build_type_attribute_variant (t1, attributes);
-
-      if (code2 == REAL_TYPE && code1 != REAL_TYPE)
-       return build_type_attribute_variant (t2, attributes);
-
-      /* Both real or both integers; use the one with greater precision.  */
-
-      if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
-       return build_type_attribute_variant (t1, attributes);
-      else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
-       return build_type_attribute_variant (t2, attributes);
-
-      /* Same precision.  Prefer long longs to longs to ints when the
-        same precision, following the C99 rules on integer type rank
-        (which are equivalent to the C90 rules for C90 types).  */
-
-      if (TYPE_MAIN_VARIANT (t1) == long_long_unsigned_type_node
-         || TYPE_MAIN_VARIANT (t2) == long_long_unsigned_type_node)
-       return build_type_attribute_variant (long_long_unsigned_type_node,
-                                            attributes);
-
-      if (TYPE_MAIN_VARIANT (t1) == long_long_integer_type_node
-         || TYPE_MAIN_VARIANT (t2) == long_long_integer_type_node)
-       {
-         if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
-            t1 = long_long_unsigned_type_node;
-         else
-            t1 = long_long_integer_type_node;
-         return build_type_attribute_variant (t1, attributes);
-       }
-
-      if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
-         || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
-       return build_type_attribute_variant (long_unsigned_type_node,
-                                            attributes);
-
-      if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
-         || TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
-       {
-         /* But preserve unsignedness from the other type,
-            since long cannot hold all the values of an unsigned int.  */
-         if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
-            t1 = long_unsigned_type_node;
-         else
-            t1 = long_integer_type_node;
-         return build_type_attribute_variant (t1, attributes);
-       }
-
-      /* Likewise, prefer long double to double even if same size.  */
-      if (TYPE_MAIN_VARIANT (t1) == long_double_type_node
-         || TYPE_MAIN_VARIANT (t2) == long_double_type_node)
-       return build_type_attribute_variant (long_double_type_node,
-                                            attributes);
-
-      /* Otherwise prefer the unsigned one.  */
-
-      if (TYPE_UNSIGNED (t1))
-       return build_type_attribute_variant (t1, attributes);
-      else
-       return build_type_attribute_variant (t2, attributes);
-
     case POINTER_TYPE:
-      /* For two pointers, do this recursively on the target type,
-        and combine the qualifiers of the two types' targets.  */
-      /* This code was turned off; I don't know why.
-        But ANSI C specifies doing this with the qualifiers.
-        So I turned it on again.  */
+      /* For two pointers, do this recursively on the target type.  */
       {
        tree pointed_to_1 = TREE_TYPE (t1);
        tree pointed_to_2 = TREE_TYPE (t2);
-       tree target = common_type (TYPE_MAIN_VARIANT (pointed_to_1),
-                                  TYPE_MAIN_VARIANT (pointed_to_2));
-       t1 = build_pointer_type (c_build_qualified_type
-                                (target,
-                                 TYPE_QUALS (pointed_to_1) |
-                                 TYPE_QUALS (pointed_to_2)));
+       tree target = composite_type (pointed_to_1, pointed_to_2);
+       t1 = build_pointer_type (target);
        return build_type_attribute_variant (t1, attributes);
       }
 
     case ARRAY_TYPE:
       {
-       tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
+       tree elt = composite_type (TREE_TYPE (t1), TREE_TYPE (t2));
        /* Save space: see if the result is identical to one of the args.  */
        if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1))
          return build_type_attribute_variant (t1, attributes);
@@ -361,7 +274,7 @@ common_type (tree t1, tree t2)
       /* Function types: prefer the one that specified arg types.
         If both do, merge the arg types.  Also merge the return types.  */
       {
-       tree valtype = common_type (TREE_TYPE (t1), TREE_TYPE (t2));
+       tree valtype = composite_type (TREE_TYPE (t1), TREE_TYPE (t2));
        tree p1 = TYPE_ARG_TYPES (t1);
        tree p2 = TYPE_ARG_TYPES (t2);
        int len;
@@ -425,8 +338,7 @@ common_type (tree t1, tree t2)
                tree memb;
                for (memb = TYPE_FIELDS (TREE_VALUE (p1));
                     memb; memb = TREE_CHAIN (memb))
-                 if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2), 
-                                COMPARE_STRICT))
+                 if (comptypes (TREE_TYPE (memb), TREE_VALUE (p2)))
                    {
                      TREE_VALUE (n) = TREE_VALUE (p2);
                      if (pedantic)
@@ -440,8 +352,7 @@ common_type (tree t1, tree t2)
                tree memb;
                for (memb = TYPE_FIELDS (TREE_VALUE (p2));
                     memb; memb = TREE_CHAIN (memb))
-                 if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1), 
-                                COMPARE_STRICT))
+                 if (comptypes (TREE_TYPE (memb), TREE_VALUE (p1)))
                    {
                      TREE_VALUE (n) = TREE_VALUE (p1);
                      if (pedantic)
@@ -449,7 +360,7 @@ common_type (tree t1, tree t2)
                      goto parm_done;
                    }
              }
-           TREE_VALUE (n) = common_type (TREE_VALUE (p1), TREE_VALUE (p2));
+           TREE_VALUE (n) = composite_type (TREE_VALUE (p1), TREE_VALUE (p2));
          parm_done: ;
          }
 
@@ -463,13 +374,189 @@ common_type (tree t1, tree t2)
     }
 
 }
+
+/* Return the type of a conditional expression between pointers to
+   possibly differently qualified versions of compatible types.
+
+   We assume that comp_target_types has already been done and returned
+   nonzero; if that isn't so, this may crash.  */
+
+static tree
+common_pointer_type (tree t1, tree t2)
+{
+  tree attributes;
+  tree pointed_to_1;
+  tree pointed_to_2;
+  tree target;
+
+  /* Save time if the two types are the same.  */
+
+  if (t1 == t2) return t1;
+
+  /* If one type is nonsense, use the other.  */
+  if (t1 == error_mark_node)
+    return t2;
+  if (t2 == error_mark_node)
+    return t1;
+
+  if (TREE_CODE (t1) != POINTER_TYPE || TREE_CODE (t2) != POINTER_TYPE)
+    abort ();
+
+  /* Merge the attributes.  */
+  attributes = targetm.merge_type_attributes (t1, t2);
+
+  /* Find the composite type of the target types, and combine the
+     qualifiers of the two types' targets.  */
+  pointed_to_1 = TREE_TYPE (t1);
+  pointed_to_2 = TREE_TYPE (t2);
+  target = composite_type (TYPE_MAIN_VARIANT (pointed_to_1),
+                          TYPE_MAIN_VARIANT (pointed_to_2));
+  t1 = build_pointer_type (c_build_qualified_type
+                          (target,
+                           TYPE_QUALS (pointed_to_1) |
+                           TYPE_QUALS (pointed_to_2)));
+  return build_type_attribute_variant (t1, attributes);
+}
+
+/* Return the common type for two arithmetic types under the usual
+   arithmetic conversions.  The default conversions have already been
+   applied, and enumerated types converted to their compatible integer
+   types.  The resulting type is unqualified and has no attributes.
+
+   This is the type for the result of most arithmetic operations
+   if the operands have the given two types.  */
+
+tree
+common_type (tree t1, tree t2)
+{
+  enum tree_code code1;
+  enum tree_code code2;
+
+  /* If one type is nonsense, use the other.  */
+  if (t1 == error_mark_node)
+    return t2;
+  if (t2 == error_mark_node)
+    return t1;
+
+  if (TYPE_QUALS (t1) != TYPE_UNQUALIFIED)
+    t1 = TYPE_MAIN_VARIANT (t1);
+
+  if (TYPE_QUALS (t2) != TYPE_UNQUALIFIED)
+    t2 = TYPE_MAIN_VARIANT (t2);
+
+  if (TYPE_ATTRIBUTES (t1) != NULL_TREE)
+    t1 = build_type_attribute_variant (t1, NULL_TREE);
+
+  if (TYPE_ATTRIBUTES (t2) != NULL_TREE)
+    t2 = build_type_attribute_variant (t2, NULL_TREE);
+
+  /* Save time if the two types are the same.  */
+
+  if (t1 == t2) return t1;
+
+  code1 = TREE_CODE (t1);
+  code2 = TREE_CODE (t2);
+
+  if (code1 != VECTOR_TYPE && code1 != COMPLEX_TYPE
+      && code1 != REAL_TYPE && code1 != INTEGER_TYPE)
+    abort ();
+
+  if (code2 != VECTOR_TYPE && code2 != COMPLEX_TYPE
+      && code2 != REAL_TYPE && code2 != INTEGER_TYPE)
+    abort ();
+
+  /* If one type is a vector type, return that type.  (How the usual
+     arithmetic conversions apply to the vector types extension is not
+     precisely specified.)  */
+  if (code1 == VECTOR_TYPE)
+    return t1;
+
+  if (code2 == VECTOR_TYPE)
+    return t2;
+
+  /* If one type is complex, form the common type of the non-complex
+     components, then make that complex.  Use T1 or T2 if it is the
+     required type.  */
+  if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE)
+    {
+      tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1;
+      tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2;
+      tree subtype = common_type (subtype1, subtype2);
+
+      if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype)
+       return t1;
+      else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype)
+       return t2;
+      else
+       return build_complex_type (subtype);
+    }
+
+  /* If only one is real, use it as the result.  */
+
+  if (code1 == REAL_TYPE && code2 != REAL_TYPE)
+    return t1;
+
+  if (code2 == REAL_TYPE && code1 != REAL_TYPE)
+    return t2;
+
+  /* Both real or both integers; use the one with greater precision.  */
+
+  if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2))
+    return t1;
+  else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1))
+    return t2;
+
+  /* Same precision.  Prefer long longs to longs to ints when the
+     same precision, following the C99 rules on integer type rank
+     (which are equivalent to the C90 rules for C90 types).  */
+
+  if (TYPE_MAIN_VARIANT (t1) == long_long_unsigned_type_node
+      || TYPE_MAIN_VARIANT (t2) == long_long_unsigned_type_node)
+    return long_long_unsigned_type_node;
+
+  if (TYPE_MAIN_VARIANT (t1) == long_long_integer_type_node
+      || TYPE_MAIN_VARIANT (t2) == long_long_integer_type_node)
+    {
+      if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
+       return long_long_unsigned_type_node;
+      else
+        return long_long_integer_type_node;
+    }
+
+  if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node
+      || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node)
+    return long_unsigned_type_node;
+
+  if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node
+      || TYPE_MAIN_VARIANT (t2) == long_integer_type_node)
+    {
+      /* But preserve unsignedness from the other type,
+        since long cannot hold all the values of an unsigned int.  */
+      if (TYPE_UNSIGNED (t1) || TYPE_UNSIGNED (t2))
+       return long_unsigned_type_node;
+      else
+       return long_integer_type_node;
+    }
+
+  /* Likewise, prefer long double to double even if same size.  */
+  if (TYPE_MAIN_VARIANT (t1) == long_double_type_node
+      || TYPE_MAIN_VARIANT (t2) == long_double_type_node)
+    return long_double_type_node;
+
+  /* Otherwise prefer the unsigned one.  */
+
+  if (TYPE_UNSIGNED (t1))
+    return t1;
+  else
+    return t2;
+}
 \f
 /* Return 1 if TYPE1 and TYPE2 are compatible types for assignment
    or various other operations.  Return 2 if they are compatible
    but a warning may be needed if you use them together.  */
 
 int
-comptypes (tree type1, tree type2, int flags)
+comptypes (tree type1, tree type2)
 {
   tree t1 = type1;
   tree t2 = type2;
@@ -506,9 +593,10 @@ comptypes (tree type1, tree type2, int flags)
 
   /* Different classes of types can't be compatible.  */
 
-  if (TREE_CODE (t1) != TREE_CODE (t2)) return 0;
+  if (TREE_CODE (t1) != TREE_CODE (t2))
+    return 0;
 
-  /* Qualifiers must match.  */
+  /* Qualifiers must match. C99 6.7.3p9 */
 
   if (TYPE_QUALS (t1) != TYPE_QUALS (t2))
     return 0;
@@ -535,11 +623,11 @@ comptypes (tree type1, tree type2, int flags)
       if (c_dialect_objc () && (val = objc_comptypes (t1, t2, 0)) >= 0)
        break;
       val = (TREE_TYPE (t1) == TREE_TYPE (t2)
-            ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2), flags));
+            ? 1 : comptypes (TREE_TYPE (t1), TREE_TYPE (t2)));
       break;
 
     case FUNCTION_TYPE:
-      val = function_types_compatible_p (t1, t2, flags);
+      val = function_types_compatible_p (t1, t2);
       break;
 
     case ARRAY_TYPE:
@@ -552,8 +640,7 @@ comptypes (tree type1, tree type2, int flags)
 
        /* Target types must match incl. qualifiers.  */
        if (TREE_TYPE (t1) != TREE_TYPE (t2)
-           && 0 == (val = comptypes (TREE_TYPE (t1), TREE_TYPE (t2),
-                                     flags)))
+           && 0 == (val = comptypes (TREE_TYPE (t1), TREE_TYPE (t2))))
          return 0;
 
        /* Sizes must match unless one is missing or variable.  */
@@ -591,12 +678,12 @@ comptypes (tree type1, tree type2, int flags)
     case ENUMERAL_TYPE:
     case UNION_TYPE:
       if (val != 1 && !same_translation_unit_p (t1, t2))
-       val = tagged_types_tu_compatible_p (t1, t2, flags);
+       val = tagged_types_tu_compatible_p (t1, t2);
       break;
 
     case VECTOR_TYPE:
       val = TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2)
-           && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), 0);
+           && comptypes (TREE_TYPE (t1), TREE_TYPE (t2));
       break;
 
     default:
@@ -622,7 +709,7 @@ comp_target_types (tree ttl, tree ttr, int reflexive)
     return val;
 
   val = comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (ttl)),
-                  TYPE_MAIN_VARIANT (TREE_TYPE (ttr)), COMPARE_STRICT);
+                  TYPE_MAIN_VARIANT (TREE_TYPE (ttr)));
 
   if (val == 2 && pedantic)
     pedwarn ("types are not quite compatible");
@@ -682,11 +769,11 @@ static const struct tagged_tu_seen * tagged_tu_seen_base;
    rules.  */
 
 static int
-tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
+tagged_types_tu_compatible_p (tree t1, tree t2)
 {
   tree s1, s2;
   bool needs_warning = false;
-  
+
   /* We have to verify that the tags of the types are the same.  This
      is harder than it looks because this may be a typedef, so we have
      to go look at the original type.  It may even be a typedef of a
@@ -706,33 +793,33 @@ tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
   /* C90 didn't have the requirement that the two tags be the same.  */
   if (flag_isoc99 && TYPE_NAME (t1) != TYPE_NAME (t2))
     return 0;
-  
+
   /* C90 didn't say what happened if one or both of the types were
      incomplete; we choose to follow C99 rules here, which is that they
      are compatible.  */
   if (TYPE_SIZE (t1) == NULL
       || TYPE_SIZE (t2) == NULL)
     return 1;
-  
+
   {
     const struct tagged_tu_seen * tts_i;
     for (tts_i = tagged_tu_seen_base; tts_i != NULL; tts_i = tts_i->next)
       if (tts_i->t1 == t1 && tts_i->t2 == t2)
        return 1;
   }
-  
+
   switch (TREE_CODE (t1))
     {
     case ENUMERAL_TYPE:
       {
-      
+
         /* Speed up the case where the type values are in the same order.  */
         tree tv1 = TYPE_VALUES (t1);
         tree tv2 = TYPE_VALUES (t2);
-        
+
         if (tv1 == tv2)
           return 1;
-        
+
         for (;tv1 && tv2; tv1 = TREE_CHAIN (tv1), tv2 = TREE_CHAIN (tv2))
           {
             if (TREE_PURPOSE (tv1) != TREE_PURPOSE (tv2))
@@ -740,15 +827,15 @@ tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
             if (simple_cst_equal (TREE_VALUE (tv1), TREE_VALUE (tv2)) != 1)
               return 0;
           }
-        
+
         if (tv1 == NULL_TREE && tv2 == NULL_TREE)
           return 1;
         if (tv1 == NULL_TREE || tv2 == NULL_TREE)
           return 0;
-        
+
        if (list_length (TYPE_VALUES (t1)) != list_length (TYPE_VALUES (t2)))
          return 0;
-       
+
        for (s1 = TYPE_VALUES (t1); s1; s1 = TREE_CHAIN (s1))
          {
            s2 = purpose_member (TREE_PURPOSE (s1), TYPE_VALUES (t2));
@@ -773,18 +860,18 @@ tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
            tts.t1 = t1;
            tts.t2 = t2;
            tagged_tu_seen_base = &tts;
-       
+
            if (DECL_NAME (s1) != NULL)
              for (s2 = TYPE_VALUES (t2); s2; s2 = TREE_CHAIN (s2))
                if (DECL_NAME (s1) == DECL_NAME (s2))
                  {
                    int result;
-                   result = comptypes (TREE_TYPE (s1), TREE_TYPE (s2), flags);
+                   result = comptypes (TREE_TYPE (s1), TREE_TYPE (s2));
                    if (result == 0)
                      break;
                    if (result == 2)
                      needs_warning = true;
-                   
+
                    if (TREE_CODE (s1) == FIELD_DECL
                        && simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
                                             DECL_FIELD_BIT_OFFSET (s2)) != 1)
@@ -803,13 +890,13 @@ tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
     case RECORD_TYPE:
       {
        struct tagged_tu_seen tts;
-       
+
        tts.next = tagged_tu_seen_base;
        tts.t1 = t1;
        tts.t2 = t2;
        tagged_tu_seen_base = &tts;
-         
-       for (s1 = TYPE_FIELDS (t1), s2 = TYPE_FIELDS (t2); 
+
+       for (s1 = TYPE_FIELDS (t1), s2 = TYPE_FIELDS (t2);
             s1 && s2;
             s1 = TREE_CHAIN (s1), s2 = TREE_CHAIN (s2))
          {
@@ -817,12 +904,12 @@ tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
            if (TREE_CODE (s1) != TREE_CODE (s2)
                || DECL_NAME (s1) != DECL_NAME (s2))
              break;
-           result = comptypes (TREE_TYPE (s1), TREE_TYPE (s2), flags);
+           result = comptypes (TREE_TYPE (s1), TREE_TYPE (s2));
            if (result == 0)
              break;
            if (result == 2)
              needs_warning = true;
-           
+
            if (TREE_CODE (s1) == FIELD_DECL
                && simple_cst_equal (DECL_FIELD_BIT_OFFSET (s1),
                                     DECL_FIELD_BIT_OFFSET (s2)) != 1)
@@ -847,7 +934,7 @@ tagged_types_tu_compatible_p (tree t1, tree t2, int flags)
    Otherwise, the argument types must match.  */
 
 static int
-function_types_compatible_p (tree f1, tree f2, int flags)
+function_types_compatible_p (tree f1, tree f2)
 {
   tree args1, args2;
   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
@@ -868,7 +955,7 @@ function_types_compatible_p (tree f1, tree f2, int flags)
   if (TYPE_VOLATILE (ret2))
     ret2 = build_qualified_type (TYPE_MAIN_VARIANT (ret2),
                                 TYPE_QUALS (ret2) & ~TYPE_QUAL_VOLATILE);
-  val = comptypes (ret1, ret2, flags);
+  val = comptypes (ret1, ret2);
   if (val == 0)
     return 0;
 
@@ -886,8 +973,7 @@ function_types_compatible_p (tree f1, tree f2, int flags)
         compare that with the other type's arglist.
         If they don't match, ask for a warning (but no error).  */
       if (TYPE_ACTUAL_ARG_TYPES (f1)
-         && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1),
-                                          flags))
+         && 1 != type_lists_compatible_p (args2, TYPE_ACTUAL_ARG_TYPES (f1)))
        val = 2;
       return val;
     }
@@ -896,14 +982,13 @@ function_types_compatible_p (tree f1, tree f2, int flags)
       if (!self_promoting_args_p (args1))
        return 0;
       if (TYPE_ACTUAL_ARG_TYPES (f2)
-         && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2),
-                                          flags))
+         && 1 != type_lists_compatible_p (args1, TYPE_ACTUAL_ARG_TYPES (f2)))
        val = 2;
       return val;
     }
 
   /* Both types have argument lists: compare them and propagate results.  */
-  val1 = type_lists_compatible_p (args1, args2, flags);
+  val1 = type_lists_compatible_p (args1, args2);
   return val1 != 1 ? val1 : val;
 }
 
@@ -912,7 +997,7 @@ function_types_compatible_p (tree f1, tree f2, int flags)
    or 2 for compatible with warning.  */
 
 static int
-type_lists_compatible_p (tree args1, tree args2, int flags)
+type_lists_compatible_p (tree args1, tree args2)
 {
   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
   int val = 1;
@@ -945,8 +1030,7 @@ type_lists_compatible_p (tree args1, tree args2, int flags)
               || TREE_CODE (TREE_VALUE (args2)) == ERROR_MARK)
        ;
       else if (! (newval = comptypes (TYPE_MAIN_VARIANT (TREE_VALUE (args1)),
-                                     TYPE_MAIN_VARIANT (TREE_VALUE (args2)),
-                                     flags)))
+                                     TYPE_MAIN_VARIANT (TREE_VALUE (args2)))))
        {
          /* Allow  wait (union {union wait *u; int *i} *)
             and  wait (union wait *)  to be compatible.  */
@@ -960,8 +1044,7 @@ type_lists_compatible_p (tree args1, tree args2, int flags)
              tree memb;
              for (memb = TYPE_FIELDS (TREE_VALUE (args1));
                   memb; memb = TREE_CHAIN (memb))
-               if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2),
-                              flags))
+               if (comptypes (TREE_TYPE (memb), TREE_VALUE (args2)))
                  break;
              if (memb == 0)
                return 0;
@@ -976,8 +1059,7 @@ type_lists_compatible_p (tree args1, tree args2, int flags)
              tree memb;
              for (memb = TYPE_FIELDS (TREE_VALUE (args2));
                   memb; memb = TREE_CHAIN (memb))
-               if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1),
-                              flags))
+               if (comptypes (TREE_TYPE (memb), TREE_VALUE (args1)))
                  break;
              if (memb == 0)
                return 0;
@@ -1117,7 +1199,7 @@ default_function_array_conversion (tree exp)
                                    | (volatilep * TYPE_QUAL_VOLATILE));
 
       if (TREE_CODE (exp) == INDIRECT_REF)
-       return convert (TYPE_POINTER_TO (restype),
+       return convert (build_pointer_type (restype),
                        TREE_OPERAND (exp, 0));
 
       if (TREE_CODE (exp) == COMPOUND_EXPR)
@@ -1747,7 +1829,7 @@ build_function_call (tree function, tree params)
       && TREE_CODE (function) == NOP_EXPR
       && TREE_CODE (tem = TREE_OPERAND (function, 0)) == ADDR_EXPR
       && TREE_CODE (tem = TREE_OPERAND (tem, 0)) == FUNCTION_DECL
-      && ! comptypes (fntype, TREE_TYPE (tem), COMPARE_STRICT))
+      && ! comptypes (fntype, TREE_TYPE (tem)))
     {
       tree return_type = TREE_TYPE (fntype);
       tree trap = build_function_call (built_in_decls[BUILT_IN_TRAP],
@@ -1806,7 +1888,18 @@ build_function_call (tree function, tree params)
   result = build (CALL_EXPR, TREE_TYPE (fntype),
                  function, coerced_params, NULL_TREE);
   TREE_SIDE_EFFECTS (result) = 1;
-  result = fold (result);
+
+  if (require_constant_value)
+    {
+      result = fold_initializer (result);
+
+      if (TREE_CONSTANT (result)
+         && (name == NULL_TREE
+             || strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10) != 0))
+       pedwarn_init ("initializer element is not constant");
+    }
+  else
+    result = fold (result);
 
   if (VOID_TYPE_P (TREE_TYPE (result)))
     return result;
@@ -2499,7 +2592,8 @@ build_unary_op (enum tree_code code, tree xarg, int flag)
 
   if (argtype == 0)
     argtype = TREE_TYPE (arg);
-  return fold (build1 (code, argtype, arg));
+  val = build1 (code, argtype, arg);
+  return require_constant_value ? fold_initializer (val) : fold (val);
 }
 
 /* Return nonzero if REF is an lvalue valid for this language.
@@ -2543,7 +2637,7 @@ lvalue_p (tree ref)
 /* Return nonzero if REF is an lvalue valid for this language;
    otherwise, print an error message and return zero.  */
 
-int
+static int
 lvalue_or_else (tree ref, const char *msgid)
 {
   int win = lvalue_p (ref);
@@ -2740,7 +2834,7 @@ build_conditional_expr (tree ifexp, tree op1, tree op2)
   else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE)
     {
       if (comp_target_types (type1, type2, 1))
-       result_type = common_type (type1, type2);
+       result_type = common_pointer_type (type1, type2);
       else if (integer_zerop (op1) && TREE_TYPE (type1) == void_type_node
               && TREE_CODE (orig_op1) != NOP_EXPR)
        result_type = qualify_type (type2, type1);
@@ -2911,7 +3005,7 @@ build_c_cast (tree type, tree expr)
 
       for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
        if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (field)),
-                      TYPE_MAIN_VARIANT (TREE_TYPE (value)), COMPARE_STRICT))
+                      TYPE_MAIN_VARIANT (TREE_TYPE (value))))
          break;
 
       if (field)
@@ -3259,7 +3353,7 @@ convert_for_assignment (tree type, tree rhs, const char *errtype,
      This code doesn't fully support references, it's just for the
      special case of va_start and va_copy.  */
   if (codel == REFERENCE_TYPE
-      && comptypes (TREE_TYPE (type), TREE_TYPE (rhs), COMPARE_STRICT) == 1)
+      && comptypes (TREE_TYPE (type), TREE_TYPE (rhs)) == 1)
     {
       if (!lvalue_p (rhs))
        {
@@ -3307,7 +3401,7 @@ convert_for_assignment (tree type, tree rhs, const char *errtype,
          tree memb_type = TREE_TYPE (memb_types);
 
          if (comptypes (TYPE_MAIN_VARIANT (memb_type),
-                        TYPE_MAIN_VARIANT (rhstype), COMPARE_STRICT))
+                        TYPE_MAIN_VARIANT (rhstype)))
            break;
 
          if (TREE_CODE (memb_type) != POINTER_TYPE)
@@ -3886,7 +3980,7 @@ digest_init (tree type, tree init, int require_constant)
          && ((inside_init && TREE_CODE (inside_init) == STRING_CST)))
        {
          if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
-                        TYPE_MAIN_VARIANT (type), COMPARE_STRICT))
+                        TYPE_MAIN_VARIANT (type)))
            return inside_init;
 
          if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)))
@@ -3933,8 +4027,7 @@ digest_init (tree type, tree init, int require_constant)
       {
        if (TREE_CODE (inside_init) == VECTOR_CST
             && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
-                         TYPE_MAIN_VARIANT (type),
-                         COMPARE_STRICT))
+                         TYPE_MAIN_VARIANT (type)))
          return inside_init;
        else
          return build_vector (type, CONSTRUCTOR_ELTS (inside_init));
@@ -3945,19 +4038,19 @@ digest_init (tree type, tree init, int require_constant)
 
   if (inside_init && TREE_TYPE (inside_init) != 0
       && (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
-                    TYPE_MAIN_VARIANT (type), COMPARE_STRICT)
+                    TYPE_MAIN_VARIANT (type))
          || (code == ARRAY_TYPE
-             && comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT))
+             && comptypes (TREE_TYPE (inside_init), type))
          || (code == VECTOR_TYPE
-             && comptypes (TREE_TYPE (inside_init), type, COMPARE_STRICT))
+             && comptypes (TREE_TYPE (inside_init), type))
          || (code == POINTER_TYPE
              && TREE_CODE (TREE_TYPE (inside_init)) == ARRAY_TYPE
              && comptypes (TREE_TYPE (TREE_TYPE (inside_init)),
-                           TREE_TYPE (type), COMPARE_STRICT))
+                           TREE_TYPE (type)))
          || (code == POINTER_TYPE
              && TREE_CODE (TREE_TYPE (inside_init)) == FUNCTION_TYPE
              && comptypes (TREE_TYPE (inside_init),
-                           TREE_TYPE (type), COMPARE_STRICT))))
+                           TREE_TYPE (type)))))
     {
       if (code == POINTER_TYPE)
        {
@@ -4141,9 +4234,6 @@ static int constructor_depth;
 /* 0 if implicitly pushing constructor levels is allowed.  */
 int constructor_no_implicit = 0; /* 0 for C; 1 for some other languages.  */
 
-static int require_constant_value;
-static int require_constant_elements;
-
 /* DECL node for which an initializer is being read.
    0 means we are reading a constructor expression
    such as (struct foo) {...}.  */
@@ -4319,7 +4409,7 @@ finish_init (void)
 
   /* Pop back to the data of the outer initializer (if any).  */
   free (spelling_base);
-  
+
   constructor_decl = p->decl;
   constructor_asmspec = p->asmspec;
   require_constant_value = p->require_constant_value;
@@ -5401,7 +5491,7 @@ output_init_element (tree value, tree type, tree field, int pending)
               && TREE_CODE (type) == ARRAY_TYPE
               && TREE_CODE (TREE_TYPE (type)) == INTEGER_TYPE)
          && !comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (value)),
-                        TYPE_MAIN_VARIANT (type), COMPARE_STRICT)))
+                        TYPE_MAIN_VARIANT (type))))
     value = default_conversion (value);
 
   if (TREE_CODE (value) == COMPOUND_LITERAL_EXPR
@@ -6684,7 +6774,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
             Otherwise, the targets must be compatible
             and both must be object or both incomplete.  */
          if (comp_target_types (type0, type1, 1))
-           result_type = common_type (type0, type1);
+           result_type = common_pointer_type (type0, type1);
          else if (VOID_TYPE_P (tt0))
            {
              /* op0 != orig_op0 detects the case of something
@@ -6732,7 +6822,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
        {
          if (comp_target_types (type0, type1, 1))
            {
-             result_type = common_type (type0, type1);
+             result_type = common_pointer_type (type0, type1);
              if (pedantic
                  && TREE_CODE (TREE_TYPE (type0)) == FUNCTION_TYPE)
                pedwarn ("ISO C forbids ordered comparisons of pointers to functions");
@@ -6757,7 +6847,7 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
        {
          if (comp_target_types (type0, type1, 1))
            {
-             result_type = common_type (type0, type1);
+             result_type = common_pointer_type (type0, type1);
              if (!COMPLETE_TYPE_P (TREE_TYPE (type0))
                  != !COMPLETE_TYPE_P (TREE_TYPE (type1)))
                pedwarn ("comparison of complete and incomplete pointers");
@@ -7108,8 +7198,8 @@ build_binary_op (enum tree_code code, tree orig_op0, tree orig_op1,
     tree result = build (resultcode, build_type, op0, op1);
 
     /* Treat expressions in initializers specially as they can't trap.  */
-    result = initializer_stack ? fold_initializer (result)
-                              : fold (result);
+    result = require_constant_value ? fold_initializer (result)
+                                   : fold (result);
 
     if (final_type != 0)
       result = convert (final_type, result);