PR c++/90047 - ICE with enable_if alias template.
authorJason Merrill <jason@redhat.com>
Thu, 18 Apr 2019 03:32:24 +0000 (23:32 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 18 Apr 2019 03:32:24 +0000 (23:32 -0400)
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.

* pt.c (tsubst_decl) [TYPE_DECL]: Don't put an erroneous decl in the
hash table when we're in SFINAE context.

From-SVN: r270433

33 files changed:
gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/alias-decl-67.C [new file with mode: 0644]
gcc/testsuite/g++.old-deja/g++.robertl/eb43.C
libstdc++-v3/testsuite/20_util/duration/arithmetic/dr3050.cc
libstdc++-v3/testsuite/20_util/from_chars/1_c++20_neg.cc
libstdc++-v3/testsuite/20_util/from_chars/1_neg.cc
libstdc++-v3/testsuite/20_util/shared_ptr/assign/auto_ptr_neg.cc
libstdc++-v3/testsuite/20_util/shared_ptr/assign/shared_ptr_neg.cc
libstdc++-v3/testsuite/20_util/shared_ptr/cons/unique_ptr_neg.cc
libstdc++-v3/testsuite/20_util/to_chars/1_neg.cc
libstdc++-v3/testsuite/20_util/tuple/element_access/get_neg.cc
libstdc++-v3/testsuite/20_util/unique_ptr/cons/ptr_deleter_neg.cc
libstdc++-v3/testsuite/20_util/unique_ptr/modifiers/reset_neg.cc
libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc
libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc
libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc
libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc
libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/assign_neg.cc
libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_1_neg.cc
libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/constructor_2_neg.cc
libstdc++-v3/testsuite/23_containers/forward_list/requirements/dr438/insert_neg.cc
libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc
libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc
libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_2_neg.cc
libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc
libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc
libstdc++-v3/testsuite/experimental/memory/shared_ptr/cons/copy_ctor_neg.cc
libstdc++-v3/testsuite/experimental/memory/shared_ptr/cons/pointer_ctor_neg.cc
libstdc++-v3/testsuite/experimental/memory/shared_ptr/modifiers/reset_neg.cc

index a37a6c225494a2e2ea7ee5bb27809e84cb0335be..bfaf355ebb709b1f8e0ebbec9ec10a078f60ba5e 100644 (file)
@@ -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.
index f8001317bda58bef38b8556d77c82bbe4a3f64f2..3a11eaa763009d754af71bfb65c659376faf0650 100644 (file)
@@ -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/gcc/testsuite/g++.dg/cpp0x/alias-decl-67.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-67.C
new file mode 100644 (file)
index 0000000..55961cc
--- /dev/null
@@ -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 *)""; }
index 1dc43284c43163d979db35ace55bb8b9ae942543..90afbe4f19010095873cdc6f7021d35d7d77fb43 100644 (file)
@@ -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" }
index 5854195dce542276cdbc8d8e55d4a09e9ff1d5b2..fc64e5a4e619f4e2d5fc1fdbd3e4262a0b3cebac 100644 (file)
@@ -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" }
index 83d297676bf2d26fe7e0eb7bcfe29f57c065837f..821cc17413d0a71f2d0b0d90ff8e7a9378128c65 100644 (file)
@@ -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" }
index 2e3c34c914553b3d0e6276b73d3d9c59f03cde9c..bc52628218ac04e775c18d3e8751e0f7fe9e417d 100644 (file)
@@ -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" }
index 19a73a1d8f29371632a23615379c50c31ea4ca8b..9c80c77c96ecb967252e900b98c3fdb555cd7ffd 100644 (file)
@@ -47,3 +47,4 @@ main()
 }
 
 // { dg-prune-output "cannot convert" }
+// { dg-prune-output "enable_if" }
index aa64c8a3b5a5a2b563db2242eb5872307a99289a..181850f256e81f033b2b4498709f295233b20839 100644 (file)
@@ -35,3 +35,5 @@ test01()
   std::shared_ptr<B> b;
   a = b;                      // { dg-error "no match" }
 }
+
+// { dg-prune-output "enable_if" }
index 2d8832354aae4d9a0ac2f1a8bc25707d850a4d05..a003e17bc6d3ef008bb6b10ee27be7c9f620cd1d 100644 (file)
@@ -43,3 +43,4 @@ main()
   return 0;
 }
 // { dg-prune-output "initializing argument" }
+// { dg-prune-output "enable_if" }
index c454d93ec1d678ed60063f4b1b7decbbaddc38a9..d125eda5883969ed972e13d357450f55954c9e65 100644 (file)
@@ -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" }
index 66861b32581e8df147f12916bcc7b05ed2299aac..ef14d9153a769997135ca1211e83928d283081e2 100644 (file)
@@ -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" }
index 81a67b3a025a9c2bf0f159d3497a9a167831028a..f6e2ea09b5e7515cca0d921f090493518f35c24b 100644 (file)
@@ -51,3 +51,5 @@ main()
   test02();
   return 0;
 }
+
+// { dg-prune-output "enable_if" }
index 6a794313cfb8bc71f09fd4f11b6f3cd9c286602b..745dea474d68bab07323e3bfd33c7cd63b4ec6aa 100644 (file)
@@ -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" }
index 624085af4ea3d6d534ef4d0373169fe8fd861964..0be1e96510363cbb9254f1fb3553aa6bec9a3342 100644 (file)
@@ -32,3 +32,5 @@ void f()
   std::deque<A> d;
   d.assign(10, 1);             // { dg-error "no match|here" }
 }
+
+// { dg-prune-output "iterator_traits" }
index ea8c8de87f16a1d8193137a3d809133eadc0a727..d99bd63abb53cb1d152ed226032d3ceeb046b845 100644 (file)
@@ -26,3 +26,5 @@ void f()
 {
   std::deque<std::deque<int> > d(10, 1); // { dg-error "here|no match" }
 }
+
+// { dg-prune-output "iterator_traits" }
index 9ed1ea10ef22578c89c6d60856bfbca2c081b7f2..9962bbfa225e5863fcbbe1075c7539e499fd2eb1 100644 (file)
@@ -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" }
index f4ed6de19f04d402fa201e83e0a6c4aa74ec5c41..8051196011bad6fa58c8af37722808185e475be0 100644 (file)
@@ -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" }
index a45833b1799e421fcc185f2538b898235e75657c..e5b680e5bdf00a3ec7456a760d58f5440ee41b05 100644 (file)
@@ -30,3 +30,5 @@ void f()
   test_type l;
   l.assign(10, 1); // { dg-error "no matching" }
 }
+
+// { dg-prune-output "iterator_traits" }
index c362d8c3f19b41407760edd89dbcee3fd241a428..e0147fe42a317b68f685ec2ad8e1704e978c0dd9 100644 (file)
@@ -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" }
index e7b41f93964eb1657df6018533963923b0646c28..9a1a5ad6a0acba205495be1b77d959d35a04150f 100644 (file)
@@ -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" }
index 18897779742d7cae22188b99ea51364ee69064c4..0a48debdec340b0ff13416708ca55bfe3e82a444 100644 (file)
@@ -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" }
index b06f7b1c6a1db669b27ffa6be28358cce06e8e6b..a3da00b03e910caf194e5b0a2dc04ec7031a09e9 100644 (file)
@@ -33,3 +33,5 @@ void f()
   list_type l;
   l.assign(10, 1);             // { dg-error "here|no match" }
 }
+
+// { dg-prune-output "iterator_traits" }
index 85c12a4a69dfdc0dc967e495651ac67dffe3815f..fc8d48fb934d95b2b9c6d9a823fa57631b51715b 100644 (file)
@@ -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" }
index 36c9f795444e1e89ef07b7de677b62c83c2c0b56..0fccc43192f20a85f5b5fd19911535bde3935e39 100644 (file)
@@ -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" }
index 772e3e9c16a90bf6befdd1d6d07078e79e9e10ac..86a1b3c53a012977ddad4e951ee2985198109b3f 100644 (file)
@@ -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" }
index 818cf69a027f099f2b5227ebc8cd3f2b6cbe31fe..ae825128c58bfb5390e81323ca80892f5178f213 100644 (file)
@@ -32,3 +32,5 @@ void f()
   std::vector<A> v;
   v.assign(10, 1);             // { dg-error "here|no match" }
 }
+
+// { dg-prune-output "iterator_traits" }
index 8c97d90c279e2d56aa6614fab5f3659123e74079..2794cae093548e6bb42842ebdf6c9906df4c62e7 100644 (file)
@@ -26,3 +26,5 @@ void f()
 {
   std::vector<std::vector<int> > v(10, 1); // { dg-error "here|no match" }
 }
+
+// { dg-prune-output "iterator_traits" }
index 8b366a33656e60905357b0239e5152cbc074b90b..f8fe1d6618e84067b4814a79310da81f78f8f89b 100644 (file)
@@ -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" }
index ca04a21b73045c5d739864c6c34855289d3b1f2a..55fcc00bc517cd0127a088bb18353a13767d3e15 100644 (file)
@@ -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" }
index 2862c6e111ddf846a2642cff6ce4ab435eee234f..89f7fc9bb12be712e1d93e90eddf3528372d5e71 100644 (file)
@@ -50,3 +50,5 @@ main()
   test02();
   return 0;
 }
+
+// { dg-prune-output "enable_if" }
index e0ddbd8e32b905c7faf45e9fc9fc327f8b27e42d..2fb5b086c52290fa6469d428c7d1dc9732d57cfc 100644 (file)
@@ -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" }
index 6f98842a12dcc8f3340424178addf61a1723d0a0..4ecd702722451563f94fdfd83169ca0cc8e1d1e3 100644 (file)
@@ -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" }