]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR ada/22333 (ACATS FAIL c34007p c34007r c45282b spurious discriminant CONSTRAINT_...
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>
Thu, 17 Nov 2005 21:03:50 +0000 (21:03 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Thu, 17 Nov 2005 21:03:50 +0000 (21:03 +0000)
PR ada/22333
* trans.c (gnat_gimplify_expr, case ADDR_EXPR): Always make
a temporary if taking the address of something that is neither
reference, declaration, or constant, since the gimplifier
can't handle that case.

From-SVN: r107134

gcc/ada/ChangeLog
gcc/ada/trans.c

index 75651bc7bc49e1ae9772ae1e421b53911aa9b2c3..78aaba7a9a626257137ce2c60f486cc5461ff58f 100644 (file)
@@ -1,3 +1,11 @@
+2005-11-17  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
+
+       PR ada/22333
+       * trans.c (gnat_gimplify_expr, case ADDR_EXPR): Always make
+       a temporary if taking the address of something that is neither
+       reference, declaration, or constant, since the gimplifier
+       can't handle that case.
+
 2005-11-17  Laurent GUERBY  <laurent@guerby.net>
 
        PR ada/24857
index 918f374b5daaf5b04cbfc1961fc3ffb2455ce08d..c71267200030ae48b80ff6d5448d1b66cb6dabb5 100644 (file)
@@ -4570,6 +4570,7 @@ int
 gnat_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
 {
   tree expr = *expr_p;
+  tree op;
 
   if (IS_ADA_STMT (expr))
     return gnat_gimplify_stmt (expr_p);
@@ -4600,25 +4601,50 @@ gnat_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
       return GS_OK;
 
     case ADDR_EXPR:
+      op = TREE_OPERAND (expr, 0);
+
       /* If we're taking the address of a constant CONSTRUCTOR, force it to
         be put into static memory.  We know it's going to be readonly given
         the semantics we have and it's required to be static memory in
-        the case when the reference is in an elaboration procedure.  */
-      if (TREE_CODE (TREE_OPERAND (expr, 0)) == CONSTRUCTOR
-         && TREE_CONSTANT (TREE_OPERAND (expr, 0)))
+        the case when the reference is in an elaboration procedure.   */
+      if (TREE_CODE (op) == CONSTRUCTOR && TREE_CONSTANT (op))
        {
-         tree new_var
-           = create_tmp_var (TREE_TYPE (TREE_OPERAND (expr, 0)), "C");
+         tree new_var = create_tmp_var (TREE_TYPE (op), "C");
 
          TREE_READONLY (new_var) = 1;
          TREE_STATIC (new_var) = 1;
          TREE_ADDRESSABLE (new_var) = 1;
-         DECL_INITIAL (new_var) = TREE_OPERAND (expr, 0);
+         DECL_INITIAL (new_var) = op;
+
+         TREE_OPERAND (expr, 0) = new_var;
+         recompute_tree_invarant_for_addr_expr (expr);
+         return GS_ALL_DONE;
+       }
+
+      /* Otherwise, if we are taking the address of something that is neither
+        reference, declaration, or constant, make a variable for the operand
+        here and then take its address.  If we don't do it this way, we may
+        confuse the gimplifier because it needs to know the variable is
+        addressable at this point.  This duplicates code in
+        internal_get_tmp_var, which is unfortunate.  */
+      else if (TREE_CODE_CLASS (TREE_CODE (op)) != tcc_reference
+              && TREE_CODE_CLASS (TREE_CODE (op)) != tcc_declaration
+              && TREE_CODE_CLASS (TREE_CODE (op)) != tcc_constant)
+       {
+         tree new_var = create_tmp_var (TREE_TYPE (op), "A");
+         tree mod = build (MODIFY_EXPR, TREE_TYPE (op), new_var, op);
+
+         TREE_ADDRESSABLE (new_var) = 1;
+
+         if (EXPR_HAS_LOCATION (op))
+           SET_EXPR_LOCUS (mod, EXPR_LOCUS (op));
 
+         gimplify_and_add (mod, pre_p);
          TREE_OPERAND (expr, 0) = new_var;
          recompute_tree_invarant_for_addr_expr (expr);
          return GS_ALL_DONE;
        }
+
       return GS_UNHANDLED;
 
     case COMPONENT_REF: