summaryrefslogtreecommitdiff
path: root/gcc/lto-streamer-in.c
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-24 14:00:43 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-24 14:00:43 +0000
commit1a8f4550a26dec9e4569956b534a688e83d079b0 (patch)
treef53ce93547fbf3759ca2ed7a8b9faa7bd83d993f /gcc/lto-streamer-in.c
parent111d2db1c3069030c0d84ac9b265dc3ac2ee9751 (diff)
downloadgcc-1a8f4550a26dec9e4569956b534a688e83d079b0.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167115 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/lto-streamer-in.c')
-rw-r--r--gcc/lto-streamer-in.c58
1 files changed, 47 insertions, 11 deletions
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index cf1b0118d76..4d36f067592 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;
}