bug90745.cc 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // -*- mode: c++; coding: utf-8 -*-
  2. // ra-ra/test - Reduced regression from 8.3 to 9.1
  3. // /opt/gcc-10.2/bin/g++ -o const -std=c++20 -Wall -Werror -ftemplate-backtrace-limit=0 const.cc
  4. // from redi @ #gcc
  5. // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90745
  6. /*
  7. <lloda> I posted on ##C++ but maybe here is better [16:29]
  8. <lloda> https://wandbox.org/permlink/WNhI31fE28NQqIzP
  9. <lloda> error with 9.1 but fine in 8.3
  10. <lloda> not using tuple (#ifdef 0) makes the error go away [16:30]
  11. <lloda> I don't understand why cell<view<const int>> operator= is even
  12. instantiated :-/ [16:31]
  13. <redi> lloda: I'm pretty sure it's a consequence of
  14. https://gcc.gnu.org/r263625 for https://gcc.gnu.org/PR86963 but I'm not
  15. sure why yet [17:09]
  16. <redi> I think there's a failure outside the immediate context of a SFINAE
  17. check
  18. <lloda> redi: thanks [17:15]
  19. <redi> lloda: I also don't understand why cell<view<const int>> operator= is
  20. even instantiated
  21. <lloda> clang gives a similar error, only it hides the library steps. I'll try
  22. to digest the links. [17:27]
  23. <redi> lloda: yeah I see the problem. It's as I thought [17:34]
  24. <redi> the copy assignment operator of std::tuple now uses
  25. conditional<__assignable<const _T1&, const _T2&>(), const tuple&, const
  26. __nonesuch_no_braces&>
  27. <redi> but it's not a dependent context, so SFINAE doesn't apply
  28. <redi> the __is_assignable check blows up [17:35]
  29. <redi> the instantiation of std::tuple<x,y> triggers the instantiations of its
  30. copy assignment operator (because it's not a template) and that blows
  31. up [17:36]
  32. <redi> drat, I need to fix this
  33. <zid> Agreed, burn the C++ spec [17:37]
  34. */
  35. #include <tuple>
  36. template <class Op, class P0, class P1>
  37. struct Expr
  38. {
  39. Op op;
  40. std::tuple<P0, P1> t;
  41. using R = decltype(op(*(std::get<0>(t).p), *(std::get<1>(t).p)));
  42. operator R() { return op(*(std::get<0>(t).p), *(std::get<1>(t).p)); }
  43. };
  44. template <class Op, class P0, class P1> inline auto
  45. expr(Op && op, P0 && p0, P1 && p1)
  46. {
  47. return Expr<Op, P0, P1> { op, { p0, p1 } };
  48. }
  49. template <class Op, class P0, class P1> inline void
  50. for_each(Op && op, P0 && p0, P1 && p1)
  51. {
  52. expr(op, p0, p1);
  53. }
  54. template <class V>
  55. struct cell
  56. {
  57. typename V::value_type * p;
  58. cell(typename V::value_type * p_): p { p_ } {}
  59. template <class X> decltype(auto) operator =(X && x)
  60. {
  61. for_each([](auto && y, auto && x)
  62. { y = x; },
  63. *this, x);
  64. }
  65. };
  66. template <class T>
  67. struct view
  68. {
  69. T * p;
  70. using value_type = T;
  71. cell<view<T>> iter() { return p; }
  72. cell<view<T const>> iter() const { return p; }
  73. view(T * p_): p(p_) {}
  74. };
  75. int main()
  76. {
  77. {
  78. int cdata[2] = {44, 44};
  79. int ndata[2] = {77, 77};
  80. view<int> const c {cdata};
  81. view<int> n {ndata};
  82. for_each([](auto && n, auto && c) { n = c; }, n.iter(), c.iter());
  83. }
  84. }