utils2.c (gnat_protect_expr): Also protect only the address if the expression is...
authorEric Botcazou <ebotcazou@adacore.com>
Sun, 13 Nov 2016 18:08:25 +0000 (18:08 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sun, 13 Nov 2016 18:08:25 +0000 (18:08 +0000)
* gcc-interface/utils2.c (gnat_protect_expr): Also protect only the
address if the expression is the component of a dereference.
Do not use a reference type for the final temporary reference.

From-SVN: r242358

gcc/ada/ChangeLog
gcc/ada/gcc-interface/utils2.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/renaming11.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/renaming11.ads [new file with mode: 0644]

index e498316e2914d61330ea447b7ea129139f4b0190..f896d14820f3667774c6837b61219bb0a4ce1610 100644 (file)
@@ -1,3 +1,9 @@
+2016-11-13  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc-interface/utils2.c (gnat_protect_expr): Also protect only the
+       address if the expression is the component of a dereference.
+       Do not use a reference type for the final temporary reference.
+
 2016-11-13  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gcc-interface/Makefile.in (NO_OMIT_ADAFLAGS): Define.
index c0d831fb1e5ba90373a483afb8d57781b3aee136..fc6f1b86bdc3800c0310324b53bb8089d0ac17e2 100644 (file)
@@ -2586,6 +2586,12 @@ gnat_protect_expr (tree exp)
       return t;
     }
 
+  /* Likewise if we're indirectly referencing part of something.  */
+  if (code == COMPONENT_REF
+      && TREE_CODE (TREE_OPERAND (exp, 0)) == INDIRECT_REF)
+    return build3 (code, type, gnat_protect_expr (TREE_OPERAND (exp, 0)),
+                  TREE_OPERAND (exp, 1), NULL_TREE);
+
   /* If this is a COMPONENT_REF of a fat pointer, save the entire fat pointer.
      This may be more efficient, but will also allow us to more easily find
      the match for the PLACEHOLDER_EXPR.  */
@@ -2605,9 +2611,7 @@ gnat_protect_expr (tree exp)
   /* Otherwise reference, protect the address and dereference.  */
   return
     build_unary_op (INDIRECT_REF, type,
-                   save_expr (build_unary_op (ADDR_EXPR,
-                                              build_reference_type (type),
-                                              exp)));
+                   save_expr (build_unary_op (ADDR_EXPR, NULL_TREE, exp)));
 }
 
 /* This is equivalent to stabilize_reference_1 in tree.c but we take an extra
index ee0282c78706b81b2db0134e6eb2d13ed53989d6..a273920d43b5bf7280f6a0a459eaaa75d2e26562 100644 (file)
@@ -1,3 +1,7 @@
+2016-11-13  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/renaming11.ad[sb]: New test.
+
 2016-11-13  Eric Botcazou  <ebotcazou@adacore.com>
 
        * c-c++-common/dump-ada-spec-6.c: New test.
diff --git a/gcc/testsuite/gnat.dg/renaming11.adb b/gcc/testsuite/gnat.dg/renaming11.adb
new file mode 100644 (file)
index 0000000..c9241c2
--- /dev/null
@@ -0,0 +1,12 @@
+-- { dg-do compile }
+
+package body Renaming11 is
+
+   function F (Arg: Ptr3) return Integer is
+      V : Ptr1 renames Arg.all.all;
+      I : Integer renames V.A(1);
+   begin
+      return I;
+   end;
+
+end Renaming11;
diff --git a/gcc/testsuite/gnat.dg/renaming11.ads b/gcc/testsuite/gnat.dg/renaming11.ads
new file mode 100644 (file)
index 0000000..d3dda72
--- /dev/null
@@ -0,0 +1,19 @@
+package Renaming11 is
+
+   subtype Index_Type is Integer range 1..10;
+
+   type Arr is array (Index_Type range <>) of Integer;
+
+   type Rec (Min : Index_Type; Max : Index_Type) is record
+      A : Arr (Min .. Max);
+   end record;
+
+   type Ptr1 is access Rec;
+
+   type Ptr2 is access Ptr1;
+
+   type Ptr3 is access Ptr2;
+
+   function F (Arg : Ptr3) return Integer;
+
+end Renaming11;