c++: Improve location information in constant evaluation
[official-gcc.git] / gcc / testsuite / g++.dg / cpp1z / constexpr-lambda6.C
blobc46c2d4c7fed36a8b996376c8ea6dc7fdaccdb6e
1 // Testcase from P0170R1
2 // { dg-do compile { target c++17 } }
4 auto monoid = [](auto v) { return [=] { return v; }; };  // { dg-error "not usable in a constant expression" }
5 auto add = [](auto m1) constexpr {
6   auto ret = m1();
7   return [=](auto m2) mutable {
8     auto m1val = m1();
9     auto plus = [=] (auto m2val) mutable constexpr
10       { return m1val += m2val; };
11     ret = plus(m2());
12     return monoid(ret);
13   };
16 int main()
18   constexpr auto zero = monoid(0);
19   constexpr auto one = monoid(1);
20   static_assert(add(one)(zero)() == one()); // OK
21   // Since 'two' below is not declared constexpr, an evaluation of its constexpr
22   // member function call operator can not perform an lvalue-to-rvalue conversion
23   // on one of its subobjects (that represents its capture) in a constant
24   // expression.
25   auto two = monoid(2);  // { dg-message "not declared .constexpr." }
26   if (!(two() == 2)) __builtin_abort(); // OK, not a constant expression.
27   static_assert(add(one)(one)() == two()); // { dg-error "|in .constexpr. expansion of " } two() is not a constant expression
28   static_assert(add(one)(one)() == monoid(2)()); // OK