aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2010-11-24 14:00:43 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-11-24 14:00:43 +0000
commitdbe9f23ca7046f0dc78d06a485a02b5c076f0015 (patch)
treef53ce93547fbf3759ca2ed7a8b9faa7bd83d993f
parentae758cb2fdb948ea76ea8896d3f9115fbb60b315 (diff)
downloadgcc-dbe9f23ca7046f0dc78d06a485a02b5c076f0015.zip
gcc-dbe9f23ca7046f0dc78d06a485a02b5c076f0015.tar.gz
gcc-dbe9f23ca7046f0dc78d06a485a02b5c076f0015.tar.bz2
re PR lto/46606 (ICE in input_gimple_stmt in lto1)
2010-11-24 Richard Guenther <rguenther@suse.de> PR lto/46606 * lto-streamer-in.c (input_gimple_stmt): When we cannot find a FIELD_DECL that is type correct issue a warning and fixup with a VIEW_CONVERT_EXPR. From-SVN: r167115
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/lto-streamer-in.c58
2 files changed, 54 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cc0549c..bacb39c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2010-11-24 Richard Guenther <rguenther@suse.de>
+
+ PR lto/46606
+ * lto-streamer-in.c (input_gimple_stmt): When we cannot find
+ a FIELD_DECL that is type correct issue a warning and fixup
+ with a VIEW_CONVERT_EXPR.
+
2010-11-24 Basile Starynkevitch <basile@starynkevitch.net>
* doc/invoke.texi (Options for Debugging Your Program or GCC):
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index cf1b011..4d36f06 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -956,25 +956,61 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
if (TREE_CODE (op) == COMPONENT_REF)
{
tree field, type, tem;
+ tree closest_match = NULL_TREE;
field = TREE_OPERAND (op, 1);
type = DECL_CONTEXT (field);
for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
{
- if (tem == field
- || (gimple_types_compatible_p (TREE_TYPE (tem),
- TREE_TYPE (field),
- GTC_DIAG)
- && DECL_NONADDRESSABLE_P (tem)
- == DECL_NONADDRESSABLE_P (field)
- && gimple_compare_field_offset (tem, field)))
+ if (tem == field)
break;
+ if (DECL_NONADDRESSABLE_P (tem)
+ == DECL_NONADDRESSABLE_P (field)
+ && gimple_compare_field_offset (tem, field))
+ {
+ if (gimple_types_compatible_p (TREE_TYPE (tem),
+ TREE_TYPE (field),
+ GTC_DIAG))
+ break;
+ else
+ closest_match = tem;
+ }
}
/* In case of type mismatches across units we can fail
to unify some types and thus not find a proper
- field-decl here. So only assert here if checking
- is enabled. */
- gcc_checking_assert (tem != NULL_TREE);
- if (tem != NULL_TREE)
+ field-decl here. */
+ if (tem == NULL_TREE)
+ {
+ /* Thus, emit a ODR violation warning. */
+ if (warning_at (gimple_location (stmt), 0,
+ "use of type %<%E%> with two mismatching "
+ "declarations at field %<%E%>",
+ type, TREE_OPERAND (op, 1)))
+ {
+ if (TYPE_FIELDS (type))
+ inform (DECL_SOURCE_LOCATION (TYPE_FIELDS (type)),
+ "original type declared here");
+ inform (DECL_SOURCE_LOCATION (TREE_OPERAND (op, 1)),
+ "field in mismatching type declared here");
+ if (TYPE_NAME (TREE_TYPE (field))
+ && (TREE_CODE (TYPE_NAME (TREE_TYPE (field)))
+ == TYPE_DECL))
+ inform (DECL_SOURCE_LOCATION
+ (TYPE_NAME (TREE_TYPE (field))),
+ "type of field declared here");
+ if (closest_match
+ && TYPE_NAME (TREE_TYPE (closest_match))
+ && (TREE_CODE (TYPE_NAME
+ (TREE_TYPE (closest_match))) == TYPE_DECL))
+ inform (DECL_SOURCE_LOCATION
+ (TYPE_NAME (TREE_TYPE (closest_match))),
+ "type of mismatching field declared here");
+ }
+ /* And finally fixup the types. */
+ TREE_OPERAND (op, 0)
+ = build1 (VIEW_CONVERT_EXPR, type,
+ TREE_OPERAND (op, 0));
+ }
+ else
TREE_OPERAND (op, 1) = tem;
}