diff options
author | Jason Merrill <jason@redhat.com> | 2011-06-14 23:51:59 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2011-06-14 23:51:59 -0400 |
commit | b273cdb17474d4d221fda93c6c9936bfd7d0a6ae (patch) | |
tree | 894f5414477006e9ef4e80113e95f3c6f4ed6beb /gcc/cp/pt.c | |
parent | f1608bfca56f5ab4a7160c57d5179e59a7c4a197 (diff) | |
download | gcc-b273cdb17474d4d221fda93c6c9936bfd7d0a6ae.zip gcc-b273cdb17474d4d221fda93c6c9936bfd7d0a6ae.tar.gz gcc-b273cdb17474d4d221fda93c6c9936bfd7d0a6ae.tar.bz2 |
re PR c++/49107 ([C++0x][4.7 Regression] incomplete type regression with std::pair)
PR c++/49107
* cp-tree.h (DEFERRED_NOEXCEPT_SPEC_P): Handle overload.
* method.c (defaulted_late_check): Only maybe_instantiate_noexcept
if the declaration had an exception-specifier.
(process_subob_fn): Don't maybe_instantiate_noexcept.
* pt.c (maybe_instantiate_noexcept): Handle overload.
* typeck2.c (nothrow_spec_p_uninst): New.
(merge_exception_specifiers): Add 'fn' parm. Build up overload.
* typeck.c (merge_types): Adjust.
From-SVN: r175073
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 54 |
1 files changed, 38 insertions, 16 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5f53ce8..ff145a26 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -17354,27 +17354,49 @@ always_instantiate_p (tree decl) void maybe_instantiate_noexcept (tree fn) { - tree fntype = TREE_TYPE (fn); - tree spec = TYPE_RAISES_EXCEPTIONS (fntype); - tree noex = NULL_TREE; - tree clone; + tree fntype, spec, noex, clone; + + if (DECL_CLONED_FUNCTION_P (fn)) + fn = DECL_CLONED_FUNCTION (fn); + fntype = TREE_TYPE (fn); + spec = TYPE_RAISES_EXCEPTIONS (fntype); if (!DEFERRED_NOEXCEPT_SPEC_P (spec)) return; + noex = TREE_PURPOSE (spec); - push_tinst_level (fn); - push_access_scope (fn); - input_location = DECL_SOURCE_LOCATION (fn); - noex = tsubst_copy_and_build (DEFERRED_NOEXCEPT_PATTERN (noex), - DEFERRED_NOEXCEPT_ARGS (noex), - tf_warning_or_error, fn, /*function_p=*/false, - /*integral_constant_expression_p=*/true); - pop_access_scope (fn); - pop_tinst_level (); - spec = build_noexcept_spec (noex, tf_warning_or_error); - if (spec == error_mark_node) - spec = noexcept_false_spec; + if (TREE_CODE (noex) == DEFERRED_NOEXCEPT) + { + push_tinst_level (fn); + push_access_scope (fn); + input_location = DECL_SOURCE_LOCATION (fn); + noex = tsubst_copy_and_build (DEFERRED_NOEXCEPT_PATTERN (noex), + DEFERRED_NOEXCEPT_ARGS (noex), + tf_warning_or_error, fn, /*function_p=*/false, + /*integral_constant_expression_p=*/true); + pop_access_scope (fn); + pop_tinst_level (); + spec = build_noexcept_spec (noex, tf_warning_or_error); + if (spec == error_mark_node) + spec = noexcept_false_spec; + } + else + { + /* This is an implicitly declared function, so NOEX is a list of + other functions to evaluate and merge. */ + tree elt; + spec = noexcept_true_spec; + for (elt = noex; elt; elt = OVL_NEXT (elt)) + { + tree fn = OVL_CURRENT (elt); + tree subspec; + maybe_instantiate_noexcept (fn); + subspec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn)); + spec = merge_exception_specifiers (spec, subspec, NULL_TREE); + } + } + TREE_TYPE (fn) = build_exception_variant (fntype, spec); FOR_EACH_CLONE (clone, fn) |