[C++ PATCH] PR c++/90047 - ICE with enable_if alias template.

Jason Merrill jason@redhat.com
Thu Apr 18 04:11:00 GMT 2019


In order to make alias templates useful for SFINAE we instantiate them under
the prevailing 'complain' argument, so an error encountered while
instantiating during SFINAE context is silent.  The problem in this PR comes
when we later look up the erroneous instantiation and don't give an error at
that point.  Fixed by not adding an erroneous instantiation to the hash
table, so we instantiate it again when needed and get the error.  This
required changes to a number of tests, which previously said "substitution
failed:" with no explanation of what the failure was; now we properly
explain.

Tested x86_64-pc-linux-gnu, applying to trunk.

	* pt.c (tsubst_decl) [TYPE_DECL]: Don't put an erroneous decl in the
	hash table when we're in SFINAE context.
---
 gcc/cp/pt.c                                   |  3 +-
 .../20_util/duration/arithmetic/dr3050.cc     |  2 ++
 .../20_util/from_chars/1_c++20_neg.cc         |  2 ++
 .../testsuite/20_util/from_chars/1_neg.cc     |  2 ++
 .../20_util/shared_ptr/assign/auto_ptr_neg.cc |  1 +
 .../shared_ptr/assign/shared_ptr_neg.cc       |  2 ++
 .../20_util/shared_ptr/cons/unique_ptr_neg.cc |  1 +
 .../testsuite/20_util/to_chars/1_neg.cc       |  2 ++
 .../20_util/tuple/element_access/get_neg.cc   |  2 ++
 .../unique_ptr/cons/ptr_deleter_neg.cc        |  2 ++
 .../20_util/unique_ptr/modifiers/reset_neg.cc |  2 ++
 .../deque/requirements/dr438/assign_neg.cc    |  2 ++
 .../requirements/dr438/constructor_1_neg.cc   |  2 ++
 .../requirements/dr438/constructor_2_neg.cc   |  2 ++
 .../deque/requirements/dr438/insert_neg.cc    |  2 ++
 .../requirements/dr438/assign_neg.cc          |  2 ++
 .../requirements/dr438/constructor_1_neg.cc   |  2 ++
 .../requirements/dr438/constructor_2_neg.cc   |  2 ++
 .../requirements/dr438/insert_neg.cc          |  2 ++
 .../list/requirements/dr438/assign_neg.cc     |  2 ++
 .../requirements/dr438/constructor_1_neg.cc   |  2 ++
 .../requirements/dr438/constructor_2_neg.cc   |  2 ++
 .../list/requirements/dr438/insert_neg.cc     |  2 ++
 .../vector/requirements/dr438/assign_neg.cc   |  2 ++
 .../requirements/dr438/constructor_1_neg.cc   |  2 ++
 .../requirements/dr438/constructor_2_neg.cc   |  2 ++
 .../vector/requirements/dr438/insert_neg.cc   |  2 ++
 .../memory/shared_ptr/cons/copy_ctor_neg.cc   |  2 ++
 .../shared_ptr/cons/pointer_ctor_neg.cc       |  2 ++
 .../memory/shared_ptr/modifiers/reset_neg.cc  |  2 ++
 gcc/testsuite/g++.dg/cpp0x/alias-decl-67.C    | 30 +++++++++++++++++++
 gcc/testsuite/g++.old-deja/g++.robertl/eb43.C |  2 ++
 gcc/cp/ChangeLog                              |  6 ++++
 33 files changed, 96 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-67.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f8001317bda..3a11eaa7630 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -13948,7 +13948,8 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
 
 	    DECL_TEMPLATE_INFO (r) = build_template_info (tmpl, argvec);
 	    SET_DECL_IMPLICIT_INSTANTIATION (r);
-	    register_specialization (r, gen_tmpl, argvec, false, hash);
+	    if (!error_operand_p (r) || (complain & tf_error))
+	      register_specialization (r, gen_tmpl, argvec, false, hash);
 	  }
 	else
 	  {
diff --git a/libstdc++-v3/testsuite/20_util/duration/arithmetic/dr3050.cc b/libstdc++-v3/testsuite/20_util/duration/arithmetic/dr3050.cc
index 5854195dce5..fc64e5a4e61 100644
--- a/libstdc++-v3/testsuite/20_util/duration/arithmetic/dr3050.cc
+++ b/libstdc++-v3/testsuite/20_util/duration/arithmetic/dr3050.cc
@@ -28,3 +28,5 @@ void test01(std::chrono::seconds s, X x)
   s / x; // { dg-error "no match" }
   s % x; // { dg-error "no match" }
 }
+
+// { dg-prune-output "enable_if" }
diff --git a/libstdc++-v3/testsuite/20_util/from_chars/1_c++20_neg.cc b/libstdc++-v3/testsuite/20_util/from_chars/1_c++20_neg.cc
index 83d297676bf..821cc17413d 100644
--- a/libstdc++-v3/testsuite/20_util/from_chars/1_c++20_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/from_chars/1_c++20_neg.cc
@@ -36,3 +36,5 @@ test01(const char* first, const char* last)
   std::from_chars(first, last, c32); // { dg-error "no matching" }
   std::from_chars(first, last, c32, 10); // { dg-error "no matching" }
 }
+
+// { dg-prune-output "enable_if" }
diff --git a/libstdc++-v3/testsuite/20_util/from_chars/1_neg.cc b/libstdc++-v3/testsuite/20_util/from_chars/1_neg.cc
index 2e3c34c9145..bc52628218a 100644
--- a/libstdc++-v3/testsuite/20_util/from_chars/1_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/from_chars/1_neg.cc
@@ -36,3 +36,5 @@ test01(const char* first, const char* last)
   std::from_chars(first, last, c32); // { dg-error "no matching" }
   std::from_chars(first, last, c32, 10); // { dg-error "no matching" }
 }
+
+// { dg-prune-output "enable_if" }
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc
index 19a73a1d8f2..9c80c77c96e 100644
--- a/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc
@@ -47,3 +47,4 @@ main()
 }
 
 // { dg-prune-output "cannot convert" }
+// { dg-prune-output "enable_if" }
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/assign/shared_ptr_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/shared_ptr_neg.cc
index aa64c8a3b5a..181850f256e 100644
--- a/libstdc++-v3/testsuite/20_util/shared_ptr/assign/shared_ptr_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/assign/shared_ptr_neg.cc
@@ -35,3 +35,5 @@ test01()
   std::shared_ptr<B> b;
   a = b;                      // { dg-error "no match" }
 }
+
+// { dg-prune-output "enable_if" }
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr_neg.cc
index 2d8832354aa..a003e17bc6d 100644
--- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr_neg.cc
@@ -43,3 +43,4 @@ main()
   return 0;
 }
 // { dg-prune-output "initializing argument" }
+// { dg-prune-output "enable_if" }
diff --git a/libstdc++-v3/testsuite/20_util/to_chars/1_neg.cc b/libstdc++-v3/testsuite/20_util/to_chars/1_neg.cc
index c454d93ec1d..d125eda5883 100644
--- a/libstdc++-v3/testsuite/20_util/to_chars/1_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/to_chars/1_neg.cc
@@ -33,3 +33,5 @@ test01(char* first, char* last)
   std::to_chars(first, last, U'\x1'); // { dg-error "no matching" }
   std::to_chars(first, last, U'\x1', 10); // { dg-error "no matching" }
 }
+
+// { dg-prune-output "enable_if" }
diff --git a/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc b/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc
index 66861b32581..ef14d9153a7 100644
--- a/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc
@@ -59,3 +59,5 @@ test03()
   std::get<6>(const_cast<const test_type&>(t));	// { dg-error "no match" }
   std::get<6>(static_cast<test_type&&>(t));	// { dg-error "no match" }
 }
+
+// { dg-prune-output "no type named .type" }
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc
index 81a67b3a025..f6e2ea09b5e 100644
--- a/libstdc++-v3/testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc
@@ -51,3 +51,5 @@ main()
   test02();
   return 0;
 }
+
+// { dg-prune-output "enable_if" }
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
index 6a794313cfb..745dea474d6 100644
--- a/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
@@ -55,3 +55,5 @@ test02()
   std::unique_ptr<const volatile A[]> cvA3;
   cvA3.reset(p); // { dg-error "no matching function" }
 }
+
+// { dg-prune-output "enable_if" }
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
index 624085af4ea..0be1e965103 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
@@ -32,3 +32,5 @@ void f()
   std::deque<A> d;
   d.assign(10, 1);		// { dg-error "no match|here" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
index ea8c8de87f1..d99bd63abb5 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
@@ -26,3 +26,5 @@ void f()
 {
   std::deque<std::deque<int> > d(10, 1); // { dg-error "here|no match" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
index 9ed1ea10ef2..9962bbfa225 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
@@ -27,3 +27,5 @@ void f()
 {
   std::deque<std::deque<std::pair<char, char> > > d('a', 'b'); // { dg-error "here|no match" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
index f4ed6de19f0..8051196011b 100644
--- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
@@ -32,3 +32,5 @@ void f()
   std::deque<A> d;
   d.insert(d.begin(), 10, 1); // { dg-error "here|no match" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc
index a45833b1799..e5b680e5bdf 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc
@@ -30,3 +30,5 @@ void f()
   test_type l;
   l.assign(10, 1); // { dg-error "no matching" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc
index c362d8c3f19..e0147fe42a3 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc
@@ -24,3 +24,5 @@ void f()
   typedef std::forward_list<std::forward_list<int> > test_type;
   test_type l(10, 1); // { dg-error "no matching" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc
index e7b41f93964..9a1a5ad6a0a 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc
@@ -25,3 +25,5 @@ void f()
   typedef std::forward_list<std::forward_list<std::pair<char, char> > > test_type;
   test_type l('a', 'b'); // { dg-error "no matching" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc
index 18897779742..0a48debdec3 100644
--- a/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc
@@ -30,3 +30,5 @@ void f()
   test_type l;
   l.insert_after(l.begin(), 10, 1); // { dg-error "no matching" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
index b06f7b1c6a1..a3da00b03e9 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
@@ -33,3 +33,5 @@ void f()
   list_type l;
   l.assign(10, 1);		// { dg-error "here|no match" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
index 85c12a4a69d..fc8d48fb934 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
@@ -27,3 +27,5 @@ void f()
   typedef std::list<std::list<int> > list_type;
   list_type l(10, 1);		// { dg-error "here|no match" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
index 36c9f795444..0fccc43192f 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
@@ -28,3 +28,5 @@ void f()
   typedef std::list<std::list<std::pair<char, char> > > list_type;
   list_type l('a', 'b');	// { dg-error "here|no match" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc
index 772e3e9c16a..86a1b3c53a0 100644
--- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc
@@ -33,3 +33,5 @@ void f()
   list_type l;
   l.insert(l.begin(), 10, 1);	// { dg-error "here|no match" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
index 818cf69a027..ae825128c58 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
@@ -32,3 +32,5 @@ void f()
   std::vector<A> v;
   v.assign(10, 1);		// { dg-error "here|no match" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
index 8c97d90c279..2794cae0935 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
@@ -26,3 +26,5 @@ void f()
 {
   std::vector<std::vector<int> > v(10, 1); // { dg-error "here|no match" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
index 8b366a33656..f8fe1d6618e 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
@@ -27,3 +27,5 @@ void f()
 {
   std::vector<std::vector<std::pair<char, char> > > v('a', 'b'); // { dg-error "here|no match" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
index ca04a21b730..55fcc00bc51 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
@@ -32,3 +32,5 @@ void f()
   std::vector<A> v;
   v.insert(v.begin(), 10, 1);	// { dg-error "here|no match" }
 }
+
+// { dg-prune-output "iterator_traits" }
diff --git a/libstdc++-v3/testsuite/experimental/memory/shared_ptr/cons/copy_ctor_neg.cc b/libstdc++-v3/testsuite/experimental/memory/shared_ptr/cons/copy_ctor_neg.cc
index 2862c6e111d..89f7fc9bb12 100644
--- a/libstdc++-v3/testsuite/experimental/memory/shared_ptr/cons/copy_ctor_neg.cc
+++ b/libstdc++-v3/testsuite/experimental/memory/shared_ptr/cons/copy_ctor_neg.cc
@@ -50,3 +50,5 @@ main()
   test02();
   return 0;
 }
+
+// { dg-prune-output "enable_if" }
diff --git a/libstdc++-v3/testsuite/experimental/memory/shared_ptr/cons/pointer_ctor_neg.cc b/libstdc++-v3/testsuite/experimental/memory/shared_ptr/cons/pointer_ctor_neg.cc
index e0ddbd8e32b..2fb5b086c52 100644
--- a/libstdc++-v3/testsuite/experimental/memory/shared_ptr/cons/pointer_ctor_neg.cc
+++ b/libstdc++-v3/testsuite/experimental/memory/shared_ptr/cons/pointer_ctor_neg.cc
@@ -49,3 +49,5 @@ test03()
   B * const b = nullptr;
   std::experimental::shared_ptr<A[]> p(b); // { dg-error "no match" }
 }
+
+// { dg-prune-output "enable_if" }
diff --git a/libstdc++-v3/testsuite/experimental/memory/shared_ptr/modifiers/reset_neg.cc b/libstdc++-v3/testsuite/experimental/memory/shared_ptr/modifiers/reset_neg.cc
index 6f98842a12d..4ecd7027224 100644
--- a/libstdc++-v3/testsuite/experimental/memory/shared_ptr/modifiers/reset_neg.cc
+++ b/libstdc++-v3/testsuite/experimental/memory/shared_ptr/modifiers/reset_neg.cc
@@ -43,3 +43,5 @@ test01()
   p1.reset(new constA[5]);      // { dg-error "no matching function" }
   p1.reset(new constA[5], D()); // { dg-error "no matching function" }
 }
+
+// { dg-prune-output "enable_if" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-67.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-67.C
new file mode 100644
index 00000000000..55961ccd186
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-67.C
@@ -0,0 +1,30 @@
+// PR c++/90047
+// { dg-do compile { target c++11 } }
+
+template <int a> struct b { static constexpr int c = a; };
+template <typename> struct aa;
+template <typename...> struct d;
+template <typename e, typename f, typename g, typename... h>
+struct d<e, f, g, h...> : aa<e>::i {};
+template <typename> struct j;
+template <typename k, long l> struct j<k[l]> : b<true> {};
+struct m {
+  typedef b<0> i;
+};
+template <typename> struct n : m::i {};
+template <bool> struct o;
+template <typename p> struct aa { typedef p i; };
+template <bool ab> using ac = typename o<ab>::i; // { dg-error "incomplete" }
+class q {
+  template <typename k, typename> using ad = ac<d<n<k>, int, int>::c>;
+  template <typename k, typename = ad<k, void>> q(k &);
+};
+template <typename r> struct s {
+  s(r) { t; }
+  template <ac<!j<r>::c> *> void t();
+};
+class I {
+  friend char operator<<(char p1, I p2) { return p1 << p2; }
+  q ag;
+};
+int main() { s<char[10]> a = (char *)""; }
diff --git a/gcc/testsuite/g++.old-deja/g++.robertl/eb43.C b/gcc/testsuite/g++.old-deja/g++.robertl/eb43.C
index 1dc43284c43..90afbe4f190 100644
--- a/gcc/testsuite/g++.old-deja/g++.robertl/eb43.C
+++ b/gcc/testsuite/g++.old-deja/g++.robertl/eb43.C
@@ -42,3 +42,5 @@ int main()
   sort( a.begin(), a.end(),
 	pointer_to_binary_function<const Expr<int>, const Expr<int>, bool>(compare<>) );
 }
+
+// { dg-prune-output "enable_if" }
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a37a6c22549..bfaf355ebb7 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2019-04-17  Jason Merrill  <jason@redhat.com>
+
+	PR c++/90047 - ICE with enable_if alias template.
+	* pt.c (tsubst_decl) [TYPE_DECL]: Don't put an erroneous decl in the
+	hash table when we're in SFINAE context.
+
 2019-04-17  Marek Polacek  <polacek@redhat.com>
 
 	PR c++/90124 - bogus error with incomplete type in decltype.

base-commit: 3778aa8e05d04d13dab9d249ee8064bd939b711a
-- 
2.20.1



More information about the Gcc-patches mailing list