]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree.c (walk_type_fields): Do not handle TYPE_MIN_VALUE and TYPE_MAX_VALUE for scalar...
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 4 Dec 2006 07:47:32 +0000 (07:47 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 4 Dec 2006 07:47:32 +0000 (07:47 +0000)
* tree.c (walk_type_fields): Do not handle TYPE_MIN_VALUE and
TYPE_MAX_VALUE for scalar types here but...
(walk_tree): ...there instead.  Return NULL_TREE if the TYPE_DECL
is attached an error mark, and the return value of the callback
if it is not NULL_TREE.

cp/
* pt.c (for_each_template_parm_r) <INTEGER_TYPE>: New case.
Call for_each_template_parm on TYPE_MIN_VALUE and TYPE_MAX_VALUE.

testsuite/
* gnat.dg/pointer_variable_bounds.adb: New test.
* gnat.dg/pointer_variable_bounds.ads: Likewise.
* gnat.dg/pointer_variable_bounds_q.ads: Likewise.

From-SVN: r119481

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/pointer_variable_bounds.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/pointer_variable_bounds.ads [new file with mode: 0644]
gcc/testsuite/gnat.dg/pointer_variable_bounds_q.ads [new file with mode: 0644]
gcc/tree.c

index e0b7813136c0200f66b72794a737f5c9c09db759..0a0984d96da4c98bc6520de8e01da5aa2b0222df 100644 (file)
@@ -1,3 +1,11 @@
+2006-12-04  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * tree.c (walk_type_fields): Do not handle TYPE_MIN_VALUE and
+       TYPE_MAX_VALUE for scalar types here but...
+       (walk_tree): ...there instead.  Return NULL_TREE if the TYPE_DECL
+       is attached an error mark, and the return value of the callback
+       if it is not NULL_TREE.
+
 2006-12-04  Ben Elliston  <bje@au.ibm.com>
 
        * config/spu/spu.md (_mulv4si3): Remove unused local variables.
index 7e482c01e1d94ae06956c936e5c9756c6e943f3d..cf577f0d9f84ddaaa9f1b629b87cf49ca3e7be60 100644 (file)
@@ -1,3 +1,8 @@
+2006-12-04  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * pt.c (for_each_template_parm_r) <INTEGER_TYPE>: New case.
+       Call for_each_template_parm on TYPE_MIN_VALUE and TYPE_MAX_VALUE.
+
 2006-12-03  Richard Henderson  <rth@redhat.com>
             Andrew Pinski  <pinskia@gmail.com>
 
index 2f4e89968394efbf08eab07e48f4b95339fb45a5..0b8eecac3ff4cd16ada73a383a58613c112991ea 100644 (file)
@@ -4958,6 +4958,14 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
        return error_mark_node;
       break;
 
+    case INTEGER_TYPE:
+      if (for_each_template_parm (TYPE_MIN_VALUE (t),
+                                 fn, data, pfd->visited)
+         || for_each_template_parm (TYPE_MAX_VALUE (t),
+                                    fn, data, pfd->visited))
+       return error_mark_node;
+      break;
+
     case METHOD_TYPE:
       /* Since we're not going to walk subtrees, we have to do this
         explicitly here.  */
index db198ec418a3e80e2b70b6a8fd31b9f1a7f91875..c460815853501332234fd398a7c05b82e46489cc 100644 (file)
@@ -1,3 +1,9 @@
+2006-12-04  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/pointer_variable_bounds.adb: New test.
+       * gnat.dg/pointer_variable_bounds.ads: Likewise.
+       * gnat.dg/pointer_variable_bounds_q.ads: Likewise.
+
 2006-12-03  Eric Christopher  <echristo@apple.com>
 
        * gcc.target/i386/stack-prot-kernel.c: Skip for x86_64-*-darwin.
diff --git a/gcc/testsuite/gnat.dg/pointer_variable_bounds.adb b/gcc/testsuite/gnat.dg/pointer_variable_bounds.adb
new file mode 100644 (file)
index 0000000..5cc838a
--- /dev/null
@@ -0,0 +1,26 @@
+-- { dg-do compile }\r
+-- { dg-options "-gnatws" }\r
+\r
+package body pointer_variable_bounds is\r
+\r
+  function COMPONENT_DAT(BP : in BUNDLE_POINTER_TYPE; CP : in COMP_POINTER_TYPE) return HALF_INTEGER is\r
+    type CP_TYPE is access COMP_POINTER_TYPE;\r
+    type CD_TYPE is access HALF_INTEGER;\r
+    CD : CD_TYPE;\r
+  begin\r
+    return CD.all;\r
+  end;\r
+\r
+  procedure BUNDLE_DAT(BP : in BUNDLE_POINTER_TYPE) is\r
+    N0 : C_POINTER_TYPE := COMPONENT_DAT(BP, 4);\r
+  begin\r
+    null;\r
+  end;\r
+\r
+  procedure SEQUENCE_DAT(BP : in BUNDLE_POINTER_TYPE) is\r
+    N0 : C_POINTER_TYPE := COMPONENT_DAT(BP, 4);\r
+  begin\r
+    null;\r
+  end;\r
+\r
+end pointer_variable_bounds;\r
diff --git a/gcc/testsuite/gnat.dg/pointer_variable_bounds.ads b/gcc/testsuite/gnat.dg/pointer_variable_bounds.ads
new file mode 100644 (file)
index 0000000..b18c354
--- /dev/null
@@ -0,0 +1,16 @@
+with pointer_variable_bounds_q; use pointer_variable_bounds_q;\r
+\r
+package pointer_variable_bounds is\r
+\r
+  type HALF_INTEGER is range -32768 .. 32767;\r
+  subtype HALF_NATURAL is HALF_INTEGER range 0 .. 32767;\r
+\r
+  MAX_COMPS : constant HALF_NATURAL := HALF_NATURAL(A_MAX_COMPS);\r
+  subtype COMP_POINTER_TYPE is HALF_NATURAL range 0 .. MAX_COMPS;\r
+  subtype BUNDLE_POINTER_TYPE is HALF_NATURAL range 0 .. 1;\r
+  subtype C_POINTER_TYPE is HALF_NATURAL range 0 .. 1;\r
+\r
+  procedure BUNDLE_DAT(BP : in BUNDLE_POINTER_TYPE);\r
+  procedure SEQUENCE_DAT(BP : in BUNDLE_POINTER_TYPE);\r
+\r
+end pointer_variable_bounds;\r
diff --git a/gcc/testsuite/gnat.dg/pointer_variable_bounds_q.ads b/gcc/testsuite/gnat.dg/pointer_variable_bounds_q.ads
new file mode 100644 (file)
index 0000000..03997f7
--- /dev/null
@@ -0,0 +1,6 @@
+package pointer_variable_bounds_q is
+
+  type A_SIZE_TYPE is new INTEGER range 0 .. 65536;
+  function A_MAX_COMPS return A_SIZE_TYPE;
+
+end pointer_variable_bounds_q;
index 6e3d13b8792b5d96a5c4828cf19defa7c6e02eb9..2d2ef08e5f7091e0f7651ebbbdd91c5ecf8c4959 100644 (file)
@@ -7442,14 +7442,6 @@ walk_type_fields (tree type, walk_tree_fn func, void *data,
       WALK_SUBTREE (TYPE_DOMAIN (type));
       break;
 
-    case BOOLEAN_TYPE:
-    case ENUMERAL_TYPE:
-    case INTEGER_TYPE:
-    case REAL_TYPE:
-      WALK_SUBTREE (TYPE_MIN_VALUE (type));
-      WALK_SUBTREE (TYPE_MAX_VALUE (type));
-      break;
-
     case OFFSET_TYPE:
       WALK_SUBTREE (TREE_TYPE (type));
       WALK_SUBTREE (TYPE_OFFSET_BASETYPE (type));
@@ -7518,7 +7510,7 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, struct pointer_set_t *pset)
 
   result = lang_hooks.tree_inlining.walk_subtrees (tp, &walk_subtrees, func,
                                                   data, pset);
-  if (result || ! walk_subtrees)
+  if (result || !walk_subtrees)
     return result;
 
   switch (code)
@@ -7648,23 +7640,29 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, struct pointer_set_t *pset)
       }
 
     case DECL_EXPR:
-      /* Walk into various fields of the type that it's defining.  We only
-        want to walk into these fields of a type in this case.  Note that
-        decls get walked as part of the processing of a BIND_EXPR.
-
-        ??? Precisely which fields of types that we are supposed to walk in
-        this case vs. the normal case aren't well defined.  */
-      if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL
-         && TREE_CODE (TREE_TYPE (DECL_EXPR_DECL (*tp))) != ERROR_MARK)
+      /* If this is a TYPE_DECL, walk into the fields of the type that it's
+        defining.  We only want to walk into these fields of a type in this
+        case and not in the general case of a mere reference to the type.
+
+        The criterion is as follows: if the field can be an expression, it
+        must be walked only here.  This should be in keeping with the fields
+        that are directly gimplified in gimplify_type_sizes in order for the
+        mark/copy-if-shared/unmark machinery of the gimplifier to work with
+        variable-sized types.
+  
+        Note that DECLs get walked as part of processing the BIND_EXPR.  */
+      if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL)
        {
          tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp));
+         if (TREE_CODE (*type_p) == ERROR_MARK)
+           return NULL_TREE;
 
          /* Call the function for the type.  See if it returns anything or
             doesn't want us to continue.  If we are to continue, walk both
             the normal fields and those for the declaration case.  */
          result = (*func) (type_p, &walk_subtrees, data);
          if (result || !walk_subtrees)
-           return NULL_TREE;
+           return result;
 
          result = walk_type_fields (*type_p, func, data, pset);
          if (result)
@@ -7695,6 +7693,16 @@ walk_tree (tree *tp, walk_tree_fn func, void *data, struct pointer_set_t *pset)
                }
            }
 
+         /* Same for scalar types.  */
+         else if (TREE_CODE (*type_p) == BOOLEAN_TYPE
+                  || TREE_CODE (*type_p) == ENUMERAL_TYPE
+                  || TREE_CODE (*type_p) == INTEGER_TYPE
+                  || TREE_CODE (*type_p) == REAL_TYPE)
+           {
+             WALK_SUBTREE (TYPE_MIN_VALUE (*type_p));
+             WALK_SUBTREE (TYPE_MAX_VALUE (*type_p));
+           }
+
          WALK_SUBTREE (TYPE_SIZE (*type_p));
          WALK_SUBTREE_TAIL (TYPE_SIZE_UNIT (*type_p));
        }