From: Jason Merrill Date: Wed, 28 Jun 2017 20:02:12 +0000 (-0400) Subject: PR c++/69300 - ICE with self-referential noexcept X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=38a79c5a9575709f649ae6646134744302ac9224;p=gcc.git PR c++/69300 - ICE with self-referential noexcept * pt.c (maybe_instantiate_noexcept): Check for recursion. From-SVN: r249757 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9c21f6f363e..2245ca9060c 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,8 @@ 2017-06-28 Jason Merrill + 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 fa75037aa3d..047d3baabbf 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* fns = new hash_set; + 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 00000000000..c51e94e7573 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept30.C @@ -0,0 +1,12 @@ +// PR c++/69300 +// { dg-do compile { target c++11 } } + +template +struct F { + template + void f() noexcept(&F::template f) {} // { dg-error "exception specification" } +}; + +int main () { + F().f(); +}