diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 0e0456c874016c385c13510c4347ef6b96c41c87..f6eb89b9d3a11a5eacd9ab730af29cac124662f6 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,8 @@
+2012-07-03  Eric Botcazou  <ebotcazou@adacore.com>
+
+	* gcc-interface/utils2.c (build_simple_component_ref): Do not look
+	through an extension if the type contains a placeholder.
+
 2012-07-03  Eric Botcazou  <ebotcazou@adacore.com>
 
 	* exp_disp.adb (Expand_Dispatching_Call): Propagate the convention on
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
index c7dfe98fce26e540772c061db1608d41d50562e4..b72ebedcea335ed6559fff8c680fe360630486da 100644
--- a/gcc/ada/gcc-interface/utils2.c
+++ b/gcc/ada/gcc-interface/utils2.c
@@ -1912,10 +1912,12 @@ build_simple_component_ref (tree record_variable, tree component,
 	  break;
 
       /* Next, see if we're looking for an inherited component in an extension.
-	 If so, look thru the extension directly.  */
+	 If so, look thru the extension directly, but not if the type contains
+	 a placeholder, as it might be needed for a later substitution.  */
       if (!new_field
 	  && TREE_CODE (record_variable) == VIEW_CONVERT_EXPR
 	  && TYPE_ALIGN_OK (record_type)
+	  && !type_contains_placeholder_p (record_type)
 	  && TREE_CODE (TREE_TYPE (TREE_OPERAND (record_variable, 0)))
 	     == RECORD_TYPE
 	  && TYPE_ALIGN_OK (TREE_TYPE (TREE_OPERAND (record_variable, 0))))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0dc8e2580db4348ac5d1b77a179263a2c7132cf2..539dfd3b4c204f7417e9c9134a425f2abd4fe5d5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2012-07-03  Eric Botcazou  <ebotcazou@adacore.com>
+
+	* gnat.dg/discr37.ad[sb]: New test.
+
 2012-07-03  Oleg Endo  <olegendo@gcc.gnu.org>
 
 	* g++.dg/other/packed1.C: Remove SH from xfail list.
diff --git a/gcc/testsuite/gnat.dg/discr37.adb b/gcc/testsuite/gnat.dg/discr37.adb
new file mode 100644
index 0000000000000000000000000000000000000000..b0e750e8cacce4c74f65e5e78702673d6ec82922
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/discr37.adb
@@ -0,0 +1,12 @@
+-- { dg-do compile }
+
+package body Discr37 is
+
+  procedure Proc (A : access Child) is
+    B : Derived renames Derived (A.F(1).all);
+    C : Derived renames Derived (B.S(1).all);
+  begin
+    null;
+  end;
+
+end Discr37;
diff --git a/gcc/testsuite/gnat.dg/discr37.ads b/gcc/testsuite/gnat.dg/discr37.ads
new file mode 100644
index 0000000000000000000000000000000000000000..7d91b2d594e591b7db8610c402ca509e8bf54805
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/discr37.ads
@@ -0,0 +1,22 @@
+package Discr37 is
+
+  subtype Index is Integer range 0 .. 100;
+
+  type Root;
+  type Frame_Ptr is access all Root'Class;
+
+  type Arr is array (Index range <>) of Frame_Ptr;
+
+  type Root (Level : Index) is tagged record
+    S : Arr (0 .. Level);
+  end record;
+
+  type Derived (Level : Index) is new Root (Level) with null record;
+
+  type Child is new Derived (0) with record
+    F : Arr (0 .. 100);
+  end record;
+
+  procedure Proc (A : access Child);
+
+end Discr37;