public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/102065] New: [C++20] Substitution failure of function instantiates its argument
@ 2021-08-25 13:36 seredinyegor at gmail dot com
2021-08-25 14:44 ` [Bug c++/102065] " ppalka at gcc dot gnu.org
2021-08-25 18:00 ` seredinyegor at gmail dot com
0 siblings, 2 replies; 3+ messages in thread
From: seredinyegor at gmail dot com @ 2021-08-25 13:36 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102065
Bug ID: 102065
Summary: [C++20] Substitution failure of function instantiates
its argument
Product: gcc
Version: 11.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: seredinyegor at gmail dot com
Target Milestone: ---
Created attachment 51356
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51356&action=edit
preprocessed file
Problem can be reproduced with:
- gcc version 11.2.0 (Ubuntu 11.2.0-1ubuntu2)
- gcc version 12.0.0 20210825 (experimental) (GCC)
Problem doesn't exist in:
- gcc version 10.3.0 (Ubuntu 10.3.0-1ubuntu1~20.04)
- Ubuntu clang version
13.0.0-++20210823084033+1f0b043ae709-1~exp1~20210823184829.58
CXXFLAGS: -std=c++20
Code:
#include <functional>
void elem_func(int) {}
template <
typename Sequence,
std::invocable<int> SequenceHandler
>
void func(
const Sequence& values,
SequenceHandler&& handler,
std::enable_if_t<std::is_pointer_v<Sequence>, int> = 0)
{
}
template <
typename T,
std::invocable<T> ValueHandler
>
void func(
T value,
ValueHandler&& handler,
std::enable_if_t<!std::is_pointer_v<T>, int> = 0)
{
}
int main()
{
func(
new int[1], // pointer => 1st func should be called
[](auto e) // lambda should be std::invocable<int> => decltype(e)==int
{
elem_func(e); // cannot call elem_func if decltype(e)==int* (2nd
func)
}
);
}
Compiler output:
sfinae_bug.cpp: In instantiation of ‘main()::<lambda(auto:3)> [with auto:3 =
int*]’:
/usr/include/c++/11/type_traits:2466:26: required by substitution of
‘template<class _Fn, class ... _Args> static std::__result_of_success<decltype
(declval<_Fn>()((declval<_Args>)()...)), std::__invoke_other>
std::__result_of_other_impl::_S_test(int) [with _Fn = main()::<lambda(auto:3)>;
_Args = {int*}]’
/usr/include/c++/11/type_traits:2477:55: required from ‘struct
std::__result_of_impl<false, false, main()::<lambda(auto:3)>, int*>’
/usr/include/c++/11/type_traits:2937:12: recursively required by substitution
of ‘template<class _Result, class _Ret> struct
std::__is_invocable_impl<_Result, _Ret, true, std::__void_t<typename
_CTp::type> > [with _Result = std::__invoke_result<main()::<lambda(auto:3)>,
int*>; _Ret = void]’
/usr/include/c++/11/type_traits:2937:12: required from ‘struct
std::is_invocable<main()::<lambda(auto:3)>, int*>’
/usr/include/c++/11/type_traits:3001:73: required from ‘constexpr const bool
std::is_invocable_v<main()::<lambda(auto:3)>, int*>’
/usr/include/c++/11/concepts:338:25: required by substitution of
‘template<class T, class ValueHandler> requires invocable<ValueHandler, T>
void func(T, ValueHandler&&, std::enable_if_t<(! is_pointer_v<T>), int>) [with
T = int*; ValueHandler = main()::<lambda(auto:3)>]’
sfinae_bug.cpp:29:9: required from here
sfinae_bug.cpp:33:23: error: invalid conversion from ‘int*’ to ‘int’
[-fpermissive]
33 | elem_func(e); // cannot call elem_func if decltype(e)==int*
(2nd func)
| ^
| |
| int*
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Bug c++/102065] [C++20] Substitution failure of function instantiates its argument
2021-08-25 13:36 [Bug c++/102065] New: [C++20] Substitution failure of function instantiates its argument seredinyegor at gmail dot com
@ 2021-08-25 14:44 ` ppalka at gcc dot gnu.org
2021-08-25 18:00 ` seredinyegor at gmail dot com
1 sibling, 0 replies; 3+ messages in thread
From: ppalka at gcc dot gnu.org @ 2021-08-25 14:44 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102065
Patrick Palka <ppalka at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Resolution|--- |DUPLICATE
CC| |ppalka at gcc dot gnu.org
Status|UNCONFIRMED |RESOLVED
--- Comment #1 from Patrick Palka <ppalka at gcc dot gnu.org> ---
Thanks for the bug report! Looks like this apparent regression started with
r11-2774 (which implements the changes in wg21.link/cwg2369).
But I think GCC's behavior is correct here, according to the latest standard.
The associated constraints of a function template are checked immediately after
deducing all template arguments, rather than after substituting the deduced
template arguments into the function type, so your use of enable_if_t as a
function parameter doesn't actually prevent the std::invocable constraint from
getting checked (and for the hard error to occur when this constraint check
causes the body of the lambda to get instantiated with int*).
One work around in your case is to give the lambda a non-deduced return type of
'void' so that we don't need to instantiate the body of the lambda during the
std::invocable check:
[](auto e) -> void
{
elem_func(e);
}
Another more general workaround is to instead encode the enable_if_t test as an
additional constraint that guards the std::invocable constraint, something
like:
#include <functional>
void elem_func(int) {}
template <
typename Sequence,
typename SequenceHandler
>
requires std::is_pointer_v<Sequence> && std::invocable<SequenceHandler, int>
void func(
const Sequence& values,
SequenceHandler&& handler)
{
}
template <
typename T,
typename ValueHandler
>
requires (!std::is_pointer_v<T>) && std::invocable<ValueHandler, T>
void func(
T value,
ValueHandler&& handler)
{
}
int main()
{
func(
new int[1], // pointer => 1st func should be called
[](auto e) // lambda should be std::invocable<int> => decltype(e)==int
{
elem_func(e); // cannot call elem_func if decltype(e)==int* (2nd
func)
}
);
}
*** This bug has been marked as a duplicate of bug 99599 ***
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Bug c++/102065] [C++20] Substitution failure of function instantiates its argument
2021-08-25 13:36 [Bug c++/102065] New: [C++20] Substitution failure of function instantiates its argument seredinyegor at gmail dot com
2021-08-25 14:44 ` [Bug c++/102065] " ppalka at gcc dot gnu.org
@ 2021-08-25 18:00 ` seredinyegor at gmail dot com
1 sibling, 0 replies; 3+ messages in thread
From: seredinyegor at gmail dot com @ 2021-08-25 18:00 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102065
--- Comment #2 from Egor Seredin <seredinyegor at gmail dot com> ---
Thank you! I agree that it is a duplicate.
Also, there is 3rd workaround without guards (may be with implicit guards):
move last function argument to last template argument:
https://godbolt.org/#z:OYLghAFBqd5QCxAYwPYBMCmBRdBLAF1QCcAaPECAM1QDsCBlZAQwBtMQBGAFlJvoCqAZ0wAFAB4gA5AAYppAFZdSrZrVDIApACYAQjt2kR7ZATx1KmWugDCqVgFcAtrRDbOpK%2BgAyeWpgA5ZwAjTGIuAA5SAAdUIUJzWjtHFzcPWPizOl9/IKdQ8M4o40xTRIYCZmICZOdXdyNMEyzaCqqCHMCQsMijSura1Iahfo6/LvyeooBKI1QHYmQOKR0AZj9kRywAak1VmyoHWjK6Nj3sTRkAQUurgDdUPHRtpswnAH1D44g/AmndgDs%2BgBABFbrcCG9oqpIbt9rdtojtgQAJ7RKzMJyYbYMTAARwcViWpARSJG6BAID8DxYwXYexsv3OOPxhOOmAAEmp0OwyKTEaj0bRMdi9iDtuTKRi6Zh3ngqO8CAzJVShO9Yr8wu87gzcQSiZhzqRtkzVhdrudbg8ntsvsgIPztmhaCMWfr2ToAGzbO5sQlCEnXJFutlLLnWXler3bBDc3nTcFAxNgi3XSFOaHMWEMx2CjFY7YAFUDV2DKupqFp9P2heZADU/Zy42ES8G88KC2KJQQKSBpew5QqlfswGBy2qNfQtTqa0aTfRLRazVbHs87Q6g0jCz7G62kQ3HE2I2Eo9pvbHj8QExakzeUzdrr9tk5mH4INebrfS0j147g/4AHd5yVABWXROE0ECQWNAB6GDtknSFiDhMEzW2ThXTtCUEHmVhnlCJ02HYZ4/yRSD9CgiBmAcIgXn%2BbY4O2VR8nQZhsNw/DsXLWgaWYGUGVNbAUOZLBNjzCBMATVZUJBJlN2DRFNC/BSVJedgPnXSS9l0Bj4JYWhaFQAhCNYVg1LeT4jmQE0qG2UTWHErTpLFX4ACptggbRrFtKyP1UwF72DKT9DvKRZlYaQQPkVxZHkVBpBsAwDAleZFlFbRVk4eQCGkORplmABrEBVlWAA6EqKsqqrPRUaRuGi3K4ukeQhBAGRSBy2LZjgWAkDQDM8F5chKH66JBp6YAhGFaIhBwgg%2BEGpDWogYJGtIYI/CqFFpCy0h%2BqxegAHlaFYbbYtILAX3Udg1vwYhSjMO5MFa87MHEUoaOWXbNQi87WDwYJiC2uwsDWghiDwJwdrCvhVEmus8EwADDqFaG%2BDoRgWBunh0cEEQJDWpQPFUdQUCSvQVAB1rIFmVBohaF6AFpyTFLQ9AMbQ5EaZpEksaxBlcDwvE6PICmUDIEjoAXxbiSXaBF7pCm5h7ylGaWPBKE5WlGBXJiVkZ2nVvp2l1sXOFmIRUqWLhwsihrzviqRxAiT1Gc9bhtmAZBrIgcGjgK/4IES9mKe2XBCBIXYMo8bY7AG3ko8y6Zssa/LSAQTBmCwcJ31IIqSvKqqi5Kmrfvq0gYq5x2WrajrU9IHrEBAeYCGiGjhogUbxqVzB8CIJX%2BExtgOBxwfhDESRzoAoHomh22pCiiu1sdw6aLb4zUFs53Xfdz3vY8v3aADjy47GhO1nNlOusK4qyuL4vaqkcvK6aqQa/azq8vn7R7ar5q6%2BvqQJ6xB4gWG4EAA
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2021-08-25 18:00 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-25 13:36 [Bug c++/102065] New: [C++20] Substitution failure of function instantiates its argument seredinyegor at gmail dot com
2021-08-25 14:44 ` [Bug c++/102065] " ppalka at gcc dot gnu.org
2021-08-25 18:00 ` seredinyegor at gmail dot com
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).