diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 17e513fd95940b34c1f16bb35ffebd4890988e7c..739cdb574bedd1f1e7226e4e2202101cc2541b8d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2009-10-20  Eric Botcazou  <ebotcazou@adacore.com>
+
+	* tree-sra.c (build_ref_for_offset_1) <RECORD_TYPE>: Skip fields
+	without size or with size that can't be represented as a host integer.
+
 2009-10-20  Alexandre Oliva  <aoliva@redhat.com>
 
 	* tree-ssa-dce.c (eliminate_unnecessary_stmts): Don't regard
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e0d007a32340895255377f953ce543cabe382fb2..1868e09da721034a51ea0dbd824be7bf35b65fa5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2009-10-20  Eric Botcazou  <ebotcazou@adacore.com>
+
+	* gnat.dg/discr21.ad[sb]: New test.
+	* gnat.dg/discr21_pkg.ads: New helper.
+
 2009-10-20  Paul Thomas  <pault@gcc.gnu.org>
 
 	PR fortran/41706
diff --git a/gcc/testsuite/gnat.dg/discr21.adb b/gcc/testsuite/gnat.dg/discr21.adb
new file mode 100644
index 0000000000000000000000000000000000000000..5c105cdb25c17fa2abb3fbf60d6d7e7fde2bfc90
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/discr21.adb
@@ -0,0 +1,34 @@
+-- { dg-do compile }
+-- { dg-options "-gnatws -O3" }
+
+with Discr21_Pkg; use Discr21_Pkg;
+
+package body Discr21 is
+
+  type Index is new Natural range 0 .. 100;
+
+  type Arr is array (Index range <> ) of Position;
+
+  type Rec(Size : Index := 1) is record
+    A : Arr(1 .. Size);
+  end record;
+
+  Data : Rec;
+
+  function To_V(pos : Position) return VPosition is
+  begin
+    return To_Position(pos.x, pos.y, pos.z);
+  end;
+
+  procedure Read(Data : Rec) is
+    pos : VPosition := To_V (Data.A(1));
+  begin
+    null;
+  end;
+
+  procedure Test is
+  begin
+    Read (Data);
+  end;
+
+end Discr21;
diff --git a/gcc/testsuite/gnat.dg/discr21.ads b/gcc/testsuite/gnat.dg/discr21.ads
new file mode 100644
index 0000000000000000000000000000000000000000..8de8ed08b768cb488219ba3ab02614cb483dc7f5
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/discr21.ads
@@ -0,0 +1,5 @@
+package Discr21 is
+
+  procedure Test;
+
+end Discr21;
diff --git a/gcc/testsuite/gnat.dg/discr21_pkg.ads b/gcc/testsuite/gnat.dg/discr21_pkg.ads
new file mode 100644
index 0000000000000000000000000000000000000000..d156df625170fd157287089893eda555ec6b5839
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/discr21_pkg.ads
@@ -0,0 +1,19 @@
+package Discr21_Pkg is
+
+  type Position is record
+    x,y,z : Float;
+  end record;
+
+  type Dim is (Two, Three);
+
+  type VPosition (D: Dim := Three) is record
+    x, y : Float;
+    case D is
+      when Two => null;
+      when Three => z : Float;
+    end case;
+  end record;
+
+  function To_Position (x, y, z : Float) return VPosition;
+
+end Discr21_Pkg;
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index dd3f6807b83abf6dfeeee24a5bae1d287f579ffd..862466886805199c5487ae9d9042bf57a11cddb2 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1243,7 +1243,10 @@ build_ref_for_offset_1 (tree *res, tree type, HOST_WIDE_INT offset,
 
 	      pos = int_bit_position (fld);
 	      gcc_assert (TREE_CODE (type) == RECORD_TYPE || pos == 0);
-	      size = tree_low_cst (DECL_SIZE (fld), 1);
+	      tr_size = DECL_SIZE (fld);
+	      if (!tr_size || !host_integerp (tr_size, 1))
+		continue;
+	      size = tree_low_cst (tr_size, 1);
 	      if (pos > offset || (pos + size) <= offset)
 		continue;