summaryrefslogtreecommitdiff
path: root/gcc/except.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/except.c')
-rw-r--r--gcc/except.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/gcc/except.c b/gcc/except.c
index ed489d9604c..c97928eadf1 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -1688,6 +1688,10 @@ add_type_for_runtime (tree type)
{
tree *slot;
+ /* If TYPE is NOP_EXPR, it means that it already is a runtime type. */
+ if (TREE_CODE (type) == NOP_EXPR)
+ return;
+
slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
TREE_HASH (type), INSERT);
if (*slot == NULL)
@@ -1702,6 +1706,10 @@ lookup_type_for_runtime (tree type)
{
tree *slot;
+ /* If TYPE is NOP_EXPR, it means that it already is a runtime type. */
+ if (TREE_CODE (type) == NOP_EXPR)
+ return type;
+
slot = (tree *) htab_find_slot_with_hash (type_to_runtime_map, type,
TREE_HASH (type), NO_INSERT);
@@ -2881,8 +2889,33 @@ check_handled (tree handled, tree type)
if (! lang_eh_type_covers)
{
for (t = handled; t ; t = TREE_CHAIN (t))
- if (TREE_VALUE (t) == type)
- return 1;
+ {
+ tree t1 = TREE_VALUE (t);
+ tree t2 = type;
+
+ /* If the types have been converted to runtime types (i.e.,
+ when the IL is being read from disk in an LTO
+ compilation), then T1 and T2 will be pointers to the
+ runtime type of the form '(void *) &<runtime_type>' (See
+ cp/except.c:build_eh_type_type). Strip the conversion
+ and the address. */
+ if (CONVERT_EXPR_P (t1))
+ {
+ STRIP_NOPS (t1);
+ gcc_assert (TREE_CODE (t1) == ADDR_EXPR);
+ t1 = TREE_OPERAND (t1, 0);
+ }
+
+ if (CONVERT_EXPR_P (t2))
+ {
+ STRIP_NOPS (t2);
+ gcc_assert (TREE_CODE (t2) == ADDR_EXPR);
+ t2 = TREE_OPERAND (t2, 0);
+ }
+
+ if (t1 == t2)
+ return 1;
+ }
}
else
{