diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index aed9418d47060a98bb477e7321dca71374fcfa31..084ec33521e9e601aa8d837c706a3fb24569d866 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2009-10-17  Richard Guenther  <rguenther@suse.de>
+
+	* lto-streamer-in.c (input_gimple_stmt): Fixup FIELD_DECL
+	operands in COMPONENT_REFs.
+
 2009-10-17  Anatoly Sokolov  <aesok@post.ru>
 
 	* targhooks.c (default_libcall_value): Don't use LIBCALL_VALUE macro
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 71faf0f39f65e4314dfb35d12c74854edb530f70..45be0c2d47be47e1344c5fb3671b172b629c7f01 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -1061,6 +1061,36 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
 	{
 	  tree op = lto_input_tree (ib, data_in);
 	  gimple_set_op (stmt, i, op);
+
+	  /* Fixup FIELD_DECLs.  */
+	  while (op && handled_component_p (op))
+	    {
+	      if (TREE_CODE (op) == COMPONENT_REF)
+		{
+		  tree field, type, tem;
+		  field = TREE_OPERAND (op, 1);
+		  type = DECL_CONTEXT (field);
+		  for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
+		    {
+		      if (tem == field
+			  || (TREE_TYPE (tem) == TREE_TYPE (field)
+			      && (DECL_FIELD_OFFSET (tem)
+				  == DECL_FIELD_OFFSET (field))
+			      && (DECL_FIELD_BIT_OFFSET (tem)
+				  == DECL_FIELD_BIT_OFFSET (field))
+			      && (DECL_OFFSET_ALIGN (tem)
+				  == DECL_OFFSET_ALIGN (field))))
+			break;
+		    }
+		  /* In case of type mismatches across units we can fail
+		     to unify some types and thus not find a proper
+		     field-decl here.  Just do nothing in this case.  */
+		  if (tem != NULL_TREE)
+		    TREE_OPERAND (op, 1) = tem;
+		}
+
+	      op = TREE_OPERAND (op, 0);
+	    }
 	}
       break;