aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.c
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2011-06-14 23:51:59 -0400
committerJason Merrill <jason@gcc.gnu.org>2011-06-14 23:51:59 -0400
commitb273cdb17474d4d221fda93c6c9936bfd7d0a6ae (patch)
tree894f5414477006e9ef4e80113e95f3c6f4ed6beb /gcc/cp/pt.c
parentf1608bfca56f5ab4a7160c57d5179e59a7c4a197 (diff)
downloadgcc-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.c54
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)