diff options
-rw-r--r-- | gcc/cp/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/cp/pt.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/noexcept30.C | 12 |
3 files changed, 30 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9c21f6f..2245ca9 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2017-06-28 Jason Merrill <jason@redhat.com> + PR c++/69300 - ICE with self-referential noexcept + * pt.c (maybe_instantiate_noexcept): Check for recursion. + PR c++/61022 - error with variadic template template parm * pt.c (convert_template_argument): Keep the TYPE_PACK_EXPANSION. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index fa75037..047d3ba 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -22557,8 +22557,20 @@ maybe_instantiate_noexcept (tree fn) if (TREE_CODE (noex) == DEFERRED_NOEXCEPT) { + static hash_set<tree>* fns = new hash_set<tree>; + bool added = false; if (DEFERRED_NOEXCEPT_PATTERN (noex) == NULL_TREE) spec = get_defaulted_eh_spec (fn); + else if (!(added = !fns->add (fn))) + { + /* If hash_set::add returns true, the element was already there. */ + location_t loc = EXPR_LOC_OR_LOC (DEFERRED_NOEXCEPT_PATTERN (noex), + DECL_SOURCE_LOCATION (fn)); + error_at (loc, + "exception specification of %qD depends on itself", + fn); + spec = noexcept_false_spec; + } else if (push_tinst_level (fn)) { push_access_scope (fn); @@ -22579,6 +22591,9 @@ maybe_instantiate_noexcept (tree fn) else spec = noexcept_false_spec; + if (added) + fns->remove (fn); + TREE_TYPE (fn) = build_exception_variant (fntype, spec); } diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept30.C b/gcc/testsuite/g++.dg/cpp0x/noexcept30.C new file mode 100644 index 0000000..c51e94e --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept30.C @@ -0,0 +1,12 @@ +// PR c++/69300 +// { dg-do compile { target c++11 } } + +template<typename A> +struct F { + template<typename B> + void f() noexcept(&F::template f<B>) {} // { dg-error "exception specification" } +}; + +int main () { + F<void>().f<int>(); +} |