diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-24 14:00:43 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-11-24 14:00:43 +0000 |
commit | 1a8f4550a26dec9e4569956b534a688e83d079b0 (patch) | |
tree | f53ce93547fbf3759ca2ed7a8b9faa7bd83d993f /gcc/lto-streamer-in.c | |
parent | 111d2db1c3069030c0d84ac9b265dc3ac2ee9751 (diff) | |
download | gcc-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.c | 58 |
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; } |