const.C 3.3 KB

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