diff options
author | Alexander Monakov <amonakov@ispras.ru> | 2016-11-09 16:58:17 +0300 |
---|---|---|
committer | Alexander Monakov <amonakov@ispras.ru> | 2016-11-09 16:58:17 +0300 |
commit | 333610c1ceadf0febb112e8f9a3f405d25a0345a (patch) | |
tree | 29ee0b1fc30f8a28e916e1c06f982933a73f4f2b /gcc/cp/tree.c | |
parent | 16ca0e4e4bc093bfb2c08b167ce1f2116e37758b (diff) | |
parent | 421721dfaaddd54b376a5ac48e15ce6c7704bde3 (diff) | |
download | gcc-amonakov/gomp-nvptx.tar.gz |
Merge remote-tracking branch 'origin/trunk' into gomp-nvptx-branch-merge-trunkamonakov/gomp-nvptx
Diffstat (limited to 'gcc/cp/tree.c')
-rw-r--r-- | gcc/cp/tree.c | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 03eef0030d0..7872dd29cf8 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1980,7 +1980,8 @@ static bool cp_check_qualified_type (const_tree cand, const_tree base, int type_quals, cp_ref_qualifier rqual, tree raises) { - return (check_qualified_type (cand, base, type_quals) + return (TYPE_QUALS (cand) == type_quals + && check_base_type (cand, base) && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (cand), ce_exact) && type_memfn_rqual (cand) == rqual); @@ -2208,6 +2209,27 @@ cxx_printable_name_translate (tree decl, int v) return cxx_printable_name_internal (decl, v, true); } +/* Return the canonical version of exception-specification RAISES for a C++17 + function type, for use in type comparison and building TYPE_CANONICAL. */ + +tree +canonical_eh_spec (tree raises) +{ + if (raises == NULL_TREE) + return raises; + else if (DEFERRED_NOEXCEPT_SPEC_P (raises) + || uses_template_parms (raises) + || uses_template_parms (TREE_PURPOSE (raises))) + /* Keep a dependent or deferred exception specification. */ + return raises; + else if (nothrow_spec_p (raises)) + /* throw() -> noexcept. */ + return noexcept_true_spec; + else + /* For C++17 type matching, anything else -> nothing. */ + return NULL_TREE; +} + /* Build the FUNCTION_TYPE or METHOD_TYPE which may throw exceptions listed in RAISES. */ @@ -2229,6 +2251,25 @@ build_exception_variant (tree type, tree raises) /* Need to build a new variant. */ v = build_variant_type_copy (type); TYPE_RAISES_EXCEPTIONS (v) = raises; + + if (!flag_noexcept_type) + /* The exception-specification is not part of the canonical type. */ + return v; + + /* Canonicalize the exception specification. */ + tree cr = canonical_eh_spec (raises); + + if (TYPE_STRUCTURAL_EQUALITY_P (type)) + /* Propagate structural equality. */ + SET_TYPE_STRUCTURAL_EQUALITY (v); + else if (TYPE_CANONICAL (type) != type || cr != raises) + /* Build the underlying canonical type, since it is different + from TYPE. */ + TYPE_CANONICAL (v) = build_exception_variant (TYPE_CANONICAL (type), cr); + else + /* T is its own canonical type. */ + TYPE_CANONICAL (v) = v; + return v; } @@ -4080,9 +4121,7 @@ cp_build_type_attribute_variant (tree type, tree attributes) } /* Return TRUE if TYPE1 and TYPE2 are identical for type hashing purposes. - Called only after doing all language independent checks. Only - to check TYPE_RAISES_EXCEPTIONS for FUNCTION_TYPE, the rest is already - compared in type_hash_eq. */ + Called only after doing all language independent checks. */ bool cxx_type_hash_eq (const_tree typea, const_tree typeb) @@ -4090,6 +4129,8 @@ cxx_type_hash_eq (const_tree typea, const_tree typeb) gcc_assert (TREE_CODE (typea) == FUNCTION_TYPE || TREE_CODE (typea) == METHOD_TYPE); + if (type_memfn_rqual (typea) != type_memfn_rqual (typeb)) + return false; return comp_except_specs (TYPE_RAISES_EXCEPTIONS (typea), TYPE_RAISES_EXCEPTIONS (typeb), ce_exact); } @@ -4282,7 +4323,7 @@ special_function_p (const_tree decl) /* Rather than doing all this stuff with magic names, we should probably have a field of type `special_function_kind' in DECL_LANG_SPECIFIC. */ - if (DECL_INHERITED_CTOR_BASE (decl)) + if (DECL_INHERITED_CTOR (decl)) return sfk_inheriting_constructor; if (DECL_COPY_CONSTRUCTOR_P (decl)) return sfk_copy_constructor; |