aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-06-28 16:02:12 -0400
committerJason Merrill <jason@gcc.gnu.org>2017-06-28 16:02:12 -0400
commit38a79c5a9575709f649ae6646134744302ac9224 (patch)
treefe88f317e4fa0b3bf0f3a64a8c1b7c8b5a4d5932
parent7e61b3d4fd0ec658697ece8dac2d27000d6da921 (diff)
downloadgcc-38a79c5a9575709f649ae6646134744302ac9224.zip
gcc-38a79c5a9575709f649ae6646134744302ac9224.tar.gz
gcc-38a79c5a9575709f649ae6646134744302ac9224.tar.bz2
PR c++/69300 - ICE with self-referential noexcept
* pt.c (maybe_instantiate_noexcept): Check for recursion. From-SVN: r249757
-rw-r--r--gcc/cp/ChangeLog3
-rw-r--r--gcc/cp/pt.c15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/noexcept30.C12
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>();
+}