From 3be2e5e6971dbe3bec0ce5e694e792c725720cd0 Mon Sep 17 00:00:00 2001 From: jason Date: Thu, 12 Apr 2018 20:03:33 +0000 Subject: [PATCH] PR c++/85356 - ICE with pointer to member function. * pt.c (maybe_instantiate_noexcept): Do instantiate in templates if flag_noexcept_type. Build the new spec within the function context. * except.c (build_noexcept_spec): Do get constant value in templates if flag_noexcept_type. * decl.c (check_redeclaration_exception_specification): Don't instantiate noexcept on a dependent declaration. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@259356 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 10 ++++++++++ gcc/cp/decl.c | 7 +++++-- gcc/cp/except.c | 5 ++++- gcc/cp/pt.c | 5 +++-- gcc/testsuite/g++.dg/template/mem_func_ptr2.C | 13 +++++++++++++ 5 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/mem_func_ptr2.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index e3bc2d9b36e..08021dfb1e2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2018-04-12 Jason Merrill + + PR c++/85356 - ICE with pointer to member function. + * pt.c (maybe_instantiate_noexcept): Do instantiate in templates if + flag_noexcept_type. Build the new spec within the function context. + * except.c (build_noexcept_spec): Do get constant value in templates + if flag_noexcept_type. + * decl.c (check_redeclaration_exception_specification): Don't + instantiate noexcept on a dependent declaration. + 2018-04-12 Marek Polacek PR c++/85258 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 44a152bd195..9f1a171ead7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -1232,8 +1232,11 @@ check_redeclaration_exception_specification (tree new_decl, && UNEVALUATED_NOEXCEPT_SPEC_P (old_exceptions)) return; - maybe_instantiate_noexcept (new_decl); - maybe_instantiate_noexcept (old_decl); + if (!type_dependent_expression_p (old_decl)) + { + maybe_instantiate_noexcept (new_decl); + maybe_instantiate_noexcept (old_decl); + } new_exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (new_decl)); old_exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (old_decl)); diff --git a/gcc/cp/except.c b/gcc/cp/except.c index 0b46698b974..6dab6d6bd96 100644 --- a/gcc/cp/except.c +++ b/gcc/cp/except.c @@ -1194,11 +1194,14 @@ build_noexcept_spec (tree expr, int complain) { /* This isn't part of the signature, so don't bother trying to evaluate it until instantiation. */ - if (!processing_template_decl && TREE_CODE (expr) != DEFERRED_NOEXCEPT) + if (TREE_CODE (expr) != DEFERRED_NOEXCEPT + && (!processing_template_decl + || (flag_noexcept_type && !value_dependent_expression_p (expr)))) { expr = perform_implicit_conversion_flags (boolean_type_node, expr, complain, LOOKUP_NORMAL); + expr = instantiate_non_dependent_expr (expr); expr = cxx_constant_value (expr); } if (TREE_CODE (expr) == INTEGER_CST) diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 76e546cdeaa..da8a5264d33 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -23234,7 +23234,8 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) tree fntype, spec, noex, clone; /* Don't instantiate a noexcept-specification from template context. */ - if (processing_template_decl) + if (processing_template_decl + && (!flag_noexcept_type || type_dependent_expression_p (fn))) return true; if (DECL_CLONED_FUNCTION_P (fn)) @@ -23273,10 +23274,10 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain) tf_warning_or_error, fn, /*function_p=*/false, /*integral_constant_expression_p=*/true); + spec = build_noexcept_spec (noex, tf_warning_or_error); pop_deferring_access_checks (); 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; } diff --git a/gcc/testsuite/g++.dg/template/mem_func_ptr2.C b/gcc/testsuite/g++.dg/template/mem_func_ptr2.C new file mode 100644 index 00000000000..9ceabd3642b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/mem_func_ptr2.C @@ -0,0 +1,13 @@ +// PR c++/85356 + +struct A +{ + A& operator=(int); +}; + +void foo(A&(A::*)(int)); + +template void bar() +{ + foo(&A::operator=); +} -- 2.11.4.GIT