diff options
Diffstat (limited to 'gcc/except.c')
-rw-r--r-- | gcc/except.c | 37 |
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 { |