OSDN Git Service

2003-06-10 Andrew Haley <aph@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / c-typeck.c
index aa58bea..c4e482e 100644 (file)
@@ -630,9 +630,23 @@ function_types_compatible_p (f1, f2)
   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
   int val = 1;
   int val1;
-
-  if (!(TREE_TYPE (f1) == TREE_TYPE (f2)
-       || (val = comptypes (TREE_TYPE (f1), TREE_TYPE (f2)))))
+  tree ret1, ret2;
+
+  ret1 = TREE_TYPE (f1);
+  ret2 = TREE_TYPE (f2);
+
+  /* 'volatile' qualifiers on a function's return type mean the function
+     is noreturn.  */
+  if (pedantic && TYPE_VOLATILE (ret1) != TYPE_VOLATILE (ret2))
+    pedwarn ("function return types not compatible due to `volatile'");
+  if (TYPE_VOLATILE (ret1))
+    ret1 = build_qualified_type (TYPE_MAIN_VARIANT (ret1),
+                                TYPE_QUALS (ret1) & ~TYPE_QUAL_VOLATILE);
+  if (TYPE_VOLATILE (ret2))
+    ret2 = build_qualified_type (TYPE_MAIN_VARIANT (ret2),
+                                TYPE_QUALS (ret2) & ~TYPE_QUAL_VOLATILE);
+  val = comptypes (ret1, ret2);
+  if (val == 0)
     return 0;
 
   args1 = TYPE_ARG_TYPES (f1);
@@ -1463,6 +1477,17 @@ build_external_ref (id, fun)
       ref = DECL_INITIAL (ref);
       TREE_CONSTANT (ref) = 1;
     }
+  else if (current_function_decl != 0
+          && DECL_CONTEXT (current_function_decl) != 0
+          && (TREE_CODE (ref) == VAR_DECL
+              || TREE_CODE (ref) == PARM_DECL
+              || TREE_CODE (ref) == FUNCTION_DECL))
+    {
+      tree context = decl_function_context (ref);
+    
+      if (context != 0 && context != current_function_decl)
+       DECL_NONLOCAL (ref) = 1;
+    }
 
   return ref;
 }
@@ -2433,8 +2458,7 @@ build_binary_op (code, orig_op0, orig_op1, convert_p)
          converted = 1;
          resultcode = xresultcode;
 
-         if ((warn_sign_compare < 0 ? extra_warnings : warn_sign_compare != 0)
-             && skip_evaluation == 0)
+         if (warn_sign_compare && skip_evaluation == 0)
            {
              int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0));
              int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1));
@@ -3423,8 +3447,7 @@ build_conditional_expr (ifexp, op1, op2)
         and later code won't know it used to be different.
         Do this check on the original types, so that explicit casts
         will be considered, but default promotions won't.  */
-      if ((warn_sign_compare < 0 ? extra_warnings : warn_sign_compare)
-         && !skip_evaluation)
+      if (warn_sign_compare && !skip_evaluation)
        {
          int unsigned_op1 = TREE_UNSIGNED (TREE_TYPE (orig_op1));
          int unsigned_op2 = TREE_UNSIGNED (TREE_TYPE (orig_op2));
@@ -3578,7 +3601,7 @@ internal_build_compound_expr (list, first_p)
       /* The left-hand operand of a comma expression is like an expression
          statement: with -Wextra or -Wunused, we should warn if it doesn't have
         any side-effects, unless it was explicitly cast to (void).  */
-      if ((extra_warnings || warn_unused_value)
+      if (warn_unused_value
            && ! (TREE_CODE (TREE_VALUE (list)) == CONVERT_EXPR
                 && VOID_TYPE_P (TREE_TYPE (TREE_VALUE (list)))))
         warning ("left-hand operand of comma expression has no effect");
@@ -4186,12 +4209,20 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum)
     {
       tree ttl = TREE_TYPE (type);
       tree ttr = TREE_TYPE (rhstype);
+      bool is_opaque_pointer;
+
+      /* Opaque pointers are treated like void pointers.  */
+      is_opaque_pointer = ((*targetm.vector_opaque_p) (type)
+                           || (*targetm.vector_opaque_p) (rhstype))
+        && TREE_CODE (ttl) == VECTOR_TYPE
+        && TREE_CODE (ttr) == VECTOR_TYPE;
 
       /* Any non-function converts to a [const][volatile] void *
         and vice versa; otherwise, targets must be the same.
         Meanwhile, the lhs target must have all the qualifiers of the rhs.  */
       if (VOID_TYPE_P (ttl) || VOID_TYPE_P (ttr)
          || comp_target_types (type, rhstype, 0)
+         || is_opaque_pointer
          || (c_common_unsigned_type (TYPE_MAIN_VARIANT (ttl))
              == c_common_unsigned_type (TYPE_MAIN_VARIANT (ttr))))
        {
@@ -4756,10 +4787,17 @@ digest_init (type, init, require_constant)
   /* Build a VECTOR_CST from a *constant* vector constructor.  If the
      vector constructor is not constant (e.g. {1,2,3,foo()}) then punt
      below and handle as a constructor.  */
-  if (code == VECTOR_TYPE
-      && comptypes (TREE_TYPE (inside_init), type)
-      && TREE_CONSTANT (inside_init))
-    return build_vector (type, TREE_OPERAND (inside_init, 1));
+    if (code == VECTOR_TYPE
+        && comptypes (TREE_TYPE (inside_init), type)
+        && TREE_CONSTANT (inside_init))
+      {
+       if (TREE_CODE (inside_init) == VECTOR_CST
+           && comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (inside_init)),
+                         TYPE_MAIN_VARIANT (type)))
+         return inside_init;
+       else
+         return build_vector (type, CONSTRUCTOR_ELTS (inside_init));
+      }
 
   /* Any type can be initialized
      from an expression of the same type, optionally with braces.  */
@@ -4920,9 +4958,6 @@ static int constructor_simple;
 /* 1 if this constructor is erroneous so far.  */
 static int constructor_erroneous;
 
-/* 1 if have called defer_addressed_constants.  */
-static int constructor_subconstants_deferred;
-
 /* Structure for managing pending initializer elements, organized as an
    AVL tree.  */
 
@@ -5040,7 +5075,6 @@ struct initializer_stack
   char top_level;
   char require_constant_value;
   char require_constant_elements;
-  char deferred;
 };
 
 struct initializer_stack *initializer_stack;
@@ -5071,14 +5105,12 @@ start_init (decl, asmspec_tree, top_level)
   p->spelling = spelling;
   p->spelling_base = spelling_base;
   p->spelling_size = spelling_size;
-  p->deferred = constructor_subconstants_deferred;
   p->top_level = constructor_top_level;
   p->next = initializer_stack;
   initializer_stack = p;
 
   constructor_decl = decl;
   constructor_asmspec = asmspec;
-  constructor_subconstants_deferred = 0;
   constructor_designated = 0;
   constructor_top_level = top_level;
 
@@ -5120,12 +5152,6 @@ finish_init ()
 {
   struct initializer_stack *p = initializer_stack;
 
-  /* Output subconstants (string constants, usually)
-     that were referenced within this initializer and saved up.
-     Must do this if and only if we called defer_addressed_constants.  */
-  if (constructor_subconstants_deferred)
-    output_deferred_addressed_constants ();
-
   /* Free the whole constructor stack of this initializer.  */
   while (constructor_stack)
     {
@@ -5148,7 +5174,6 @@ finish_init ()
   spelling = p->spelling;
   spelling_base = p->spelling_base;
   spelling_size = p->spelling_size;
-  constructor_subconstants_deferred = p->deferred;
   constructor_top_level = p->top_level;
   initializer_stack = p->next;
   free (p);
@@ -5377,7 +5402,7 @@ push_init_level (implicit)
     {
       constructor_constant = TREE_CONSTANT (value);
       constructor_simple = TREE_STATIC (value);
-      constructor_elements = TREE_OPERAND (value, 1);
+      constructor_elements = CONSTRUCTOR_ELTS (value);
       if (constructor_elements
          && (TREE_CODE (constructor_type) == RECORD_TYPE
              || TREE_CODE (constructor_type) == ARRAY_TYPE))