OSDN Git Service

* c-typeck.c (initializer_constant_valid_p): Move ...
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 31 Jul 1999 01:13:08 +0000 (01:13 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 31 Jul 1999 01:13:08 +0000 (01:13 +0000)
        * c-common.c (initializer_constant_valid_p): ... here.  Use
        FOO_TYPE_P instead of tests against TREE_CODE.  Allow subtraction
        of label addresses.
        * c-common.h (initializer_constant_valid_p): Declare.
        * c-tree.h (initializer_constant_valid_p): Remove.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@28349 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/c-common.c
gcc/c-common.h
gcc/c-tree.h
gcc/c-typeck.c

index 75de1b3..55dd809 100644 (file)
@@ -1,3 +1,12 @@
+1999-07-30  Richard Henderson  <rth@cygnus.com>
+
+       * c-typeck.c (initializer_constant_valid_p): Move ...
+       * c-common.c (initializer_constant_valid_p): ... here.  Use 
+       FOO_TYPE_P instead of tests against TREE_CODE.  Allow subtraction
+       of label addresses.
+       * c-common.h (initializer_constant_valid_p): Declare.
+       * c-tree.h (initializer_constant_valid_p): Remove.
+
 Fri Jul 30 16:33:42 1999  Mathias Froehlich  <frohlich@na.uni-tuebingen.de>
 
        * config/i386/sol2-c1.asm: Align the stack.
index 4c083de..137d1d3 100644 (file)
@@ -3767,3 +3767,159 @@ build_va_arg (expr, type)
 {
   return build1 (VA_ARG_EXPR, type, expr);
 }
+
+/* Return nonzero if VALUE is a valid constant-valued expression
+   for use in initializing a static variable; one that can be an
+   element of a "constant" initializer.
+
+   Return null_pointer_node if the value is absolute;
+   if it is relocatable, return the variable that determines the relocation.
+   We assume that VALUE has been folded as much as possible;
+   therefore, we do not need to check for such things as
+   arithmetic-combinations of integers.  */
+
+tree
+initializer_constant_valid_p (value, endtype)
+     tree value;
+     tree endtype;
+{
+  switch (TREE_CODE (value))
+    {
+    case CONSTRUCTOR:
+      if ((TREE_CODE (TREE_TYPE (value)) == UNION_TYPE
+          || TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE)
+         && TREE_CONSTANT (value)
+         && CONSTRUCTOR_ELTS (value))
+       return
+         initializer_constant_valid_p (TREE_VALUE (CONSTRUCTOR_ELTS (value)),
+                                       endtype);
+       
+      return TREE_STATIC (value) ? null_pointer_node : 0;
+
+    case INTEGER_CST:
+    case REAL_CST:
+    case STRING_CST:
+    case COMPLEX_CST:
+      return null_pointer_node;
+
+    case ADDR_EXPR:
+      return TREE_OPERAND (value, 0);
+
+    case NON_LVALUE_EXPR:
+      return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
+
+    case CONVERT_EXPR:
+    case NOP_EXPR:
+      /* Allow conversions between pointer types.  */
+      if (POINTER_TYPE_P (TREE_TYPE (value))
+         && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))))
+       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
+
+      /* Allow conversions between real types.  */
+      if (FLOAT_TYPE_P (TREE_TYPE (value))
+         && FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))))
+       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
+
+      /* Allow length-preserving conversions between integer types.  */
+      if (INTEGRAL_TYPE_P (TREE_TYPE (value))
+         && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))
+         && (TYPE_PRECISION (TREE_TYPE (value))
+             == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
+       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
+
+      /* Allow conversions between other integer types only if
+        explicit value.  */
+      if (INTEGRAL_TYPE_P (TREE_TYPE (value))
+         && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))))
+       {
+         tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0),
+                                                    endtype);
+         if (inner == null_pointer_node)
+           return null_pointer_node;
+         break;
+       }
+
+      /* Allow (int) &foo provided int is as wide as a pointer.  */
+      if (INTEGRAL_TYPE_P (TREE_TYPE (value))
+         && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))
+         && (TYPE_PRECISION (TREE_TYPE (value))
+             >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
+       return initializer_constant_valid_p (TREE_OPERAND (value, 0),
+                                            endtype);
+
+      /* Likewise conversions from int to pointers, but also allow
+        conversions from 0.  */
+      if (POINTER_TYPE_P (TREE_TYPE (value))
+         && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0))))
+       {
+         if (integer_zerop (TREE_OPERAND (value, 0)))
+           return null_pointer_node;
+         else if (TYPE_PRECISION (TREE_TYPE (value))
+                  <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))
+           return initializer_constant_valid_p (TREE_OPERAND (value, 0),
+                                                endtype);
+       }
+
+      /* Allow conversions to union types if the value inside is okay.  */
+      if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE)
+       return initializer_constant_valid_p (TREE_OPERAND (value, 0),
+                                            endtype);
+      break;
+
+    case PLUS_EXPR:
+      if (! INTEGRAL_TYPE_P (endtype)
+         || TYPE_PRECISION (endtype) >= POINTER_SIZE)
+        {
+         tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
+                                                     endtype);
+         tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
+                                                     endtype);
+         /* If either term is absolute, use the other terms relocation.  */
+         if (valid0 == null_pointer_node)
+           return valid1;
+         if (valid1 == null_pointer_node)
+           return valid0;
+        }
+      break;
+
+    case MINUS_EXPR:
+      if (! INTEGRAL_TYPE_P (endtype)
+         || TYPE_PRECISION (endtype) >= POINTER_SIZE)
+       {
+         tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
+                                                     endtype);
+         tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
+                                                     endtype);
+         /* Win if second argument is absolute.  */
+         if (valid1 == null_pointer_node)
+           return valid0;
+         /* Win if both arguments have the same relocation.
+            Then the value is absolute.  */
+         if (valid0 == valid1)
+           return null_pointer_node;
+       }
+
+      /* Support differences between labels.  */
+      if (INTEGRAL_TYPE_P (endtype))
+       {
+         tree op0, op1;
+         op0 = TREE_OPERAND (value, 0);
+         op1 = TREE_OPERAND (value, 1);
+         STRIP_NOPS (op0);
+         STRIP_NOPS (op1);
+
+         if (TREE_CODE (op0) == ADDR_EXPR
+             && TREE_CODE (TREE_OPERAND (op0, 0)) == LABEL_DECL
+             && TREE_CODE (op1) == ADDR_EXPR
+             && TREE_CODE (TREE_OPERAND (op1, 0)) == LABEL_DECL)
+           return null_pointer_node;
+       }
+      break;
+
+    default:
+      break;
+    }
+
+  return 0;
+}
+
index ec4a556..ab0cdec 100644 (file)
@@ -190,3 +190,5 @@ extern tree builtin_function                        PROTO((const char *, tree, enum built_in_function
 extern void c_common_nodes_and_builtins                PROTO((int, int, int));
 
 extern tree build_va_arg                       PROTO((tree, tree));
+
+extern tree initializer_constant_valid_p       PROTO((tree, tree));
index 1db0790..8e5aa73 100644 (file)
@@ -282,7 +282,6 @@ extern tree build_compound_expr                 PROTO((tree));
 extern tree build_c_cast                        PROTO((tree, tree));
 extern tree build_modify_expr                   PROTO((tree, enum tree_code,
                                                       tree));
-extern tree initializer_constant_valid_p       PROTO((tree, tree));
 extern void store_init_value                    PROTO((tree, tree));
 extern void error_init                         PROTO((const char *));
 extern void pedwarn_init                       PROTO((const char *));
index 18b8210..6d4c7df 100644 (file)
@@ -4246,145 +4246,6 @@ warn_for_assignment (msgid, opname, function, argnum)
   pedwarn (msgid, opname);
 }
 \f
-/* Return nonzero if VALUE is a valid constant-valued expression
-   for use in initializing a static variable; one that can be an
-   element of a "constant" initializer.
-
-   Return null_pointer_node if the value is absolute;
-   if it is relocatable, return the variable that determines the relocation.
-   We assume that VALUE has been folded as much as possible;
-   therefore, we do not need to check for such things as
-   arithmetic-combinations of integers.  */
-
-tree
-initializer_constant_valid_p (value, endtype)
-     tree value;
-     tree endtype;
-{
-  switch (TREE_CODE (value))
-    {
-    case CONSTRUCTOR:
-      if ((TREE_CODE (TREE_TYPE (value)) == UNION_TYPE
-          || TREE_CODE (TREE_TYPE (value)) == RECORD_TYPE)
-         && TREE_CONSTANT (value)
-         && CONSTRUCTOR_ELTS (value))
-       return
-         initializer_constant_valid_p (TREE_VALUE (CONSTRUCTOR_ELTS (value)),
-                                       endtype);
-       
-      return TREE_STATIC (value) ? null_pointer_node : 0;
-
-    case INTEGER_CST:
-    case REAL_CST:
-    case STRING_CST:
-    case COMPLEX_CST:
-      return null_pointer_node;
-
-    case ADDR_EXPR:
-      return TREE_OPERAND (value, 0);
-
-    case NON_LVALUE_EXPR:
-      return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-    case CONVERT_EXPR:
-    case NOP_EXPR:
-      /* Allow conversions between pointer types.  */
-      if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE)
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-      /* Allow conversions between real types.  */
-      if (TREE_CODE (TREE_TYPE (value)) == REAL_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == REAL_TYPE)
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-      /* Allow length-preserving conversions between integer types.  */
-      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE
-         && (TYPE_PRECISION (TREE_TYPE (value))
-             == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype);
-
-      /* Allow conversions between other integer types only if
-        explicit value.  */
-      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE)
-       {
-         tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                    endtype);
-         if (inner == null_pointer_node)
-           return null_pointer_node;
-         return 0;
-       }
-
-      /* Allow (int) &foo provided int is as wide as a pointer.  */
-      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE
-         && (TYPE_PRECISION (TREE_TYPE (value))
-             >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))))
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                            endtype);
-
-      /* Likewise conversions from int to pointers, but also allow
-        conversions from 0.  */
-      if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE
-         && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE)
-       {
-         if (integer_zerop (TREE_OPERAND (value, 0)))
-           return null_pointer_node;
-         else if (TYPE_PRECISION (TREE_TYPE (value))
-                  <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))
-           return initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                endtype);
-       }
-
-      /* Allow conversions to union types if the value inside is okay.  */
-      if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE)
-       return initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                            endtype);
-      return 0;
-
-    case PLUS_EXPR:
-      if (TREE_CODE (endtype) == INTEGER_TYPE
-         && TYPE_PRECISION (endtype) < POINTER_SIZE)
-       return 0;
-      {
-       tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                   endtype);
-       tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
-                                                   endtype);
-       /* If either term is absolute, use the other terms relocation.  */
-       if (valid0 == null_pointer_node)
-         return valid1;
-       if (valid1 == null_pointer_node)
-         return valid0;
-       return 0;
-      }
-
-    case MINUS_EXPR:
-      if (TREE_CODE (endtype) == INTEGER_TYPE
-         && TYPE_PRECISION (endtype) < POINTER_SIZE)
-       return 0;
-      {
-       tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0),
-                                                   endtype);
-       tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1),
-                                                   endtype);
-       /* Win if second argument is absolute.  */
-       if (valid1 == null_pointer_node)
-         return valid0;
-       /* Win if both arguments have the same relocation.
-          Then the value is absolute.  */
-       if (valid0 == valid1)
-         return null_pointer_node;
-       return 0;
-      }
-
-    default:
-      return 0;
-    }
-}
-
 /* If VALUE is a compound expr all of whose expressions are constant, then
    return its value.  Otherwise, return error_mark_node.