You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[BUG] Malformed lambda call inside inspect lead to compilation without error and silent default value #433
Inside inspect, I have lambda where I forgot to pass argument. Like :(x) -> _ = {return "int"} (); instead of :(x) -> _ = {return "int"} (x);
It was accepted by compilers and emitted code, which runs and silently returns ""
error: no matching function for call to object of type '(lambda at lambdaparam.cpp2:13:6)'
note: candidate function template not viable: requires single argument 'x', but no arguments were provided
Actual result/error
Code silently compiles at cpp2 and cpp1 and silently runs without calling lambda and returning default value for inspect case, in this case an empty string.
Additional context
I understand this may be alpha version limitation of inspect
Emitted cpp1 code is roughly
if (cpp2::is(__expr)) { if constexpr( requires{V} ) if constexpr( std::is_convertible_v<V,T>) return V; else return T{}; else return T{}; }
Edit: after some investigation, it appears that cpp1 if constexpr( requires{[](auto const& x) -> auto{ ... }();} ) returns false.
I think they should be replaced with a contract check or something along those lines.
The user wrote a statement for the chosen alternative, but it doesn't work for it!
See https://compiler-explorer.com/z/MKTTxoTn7.
I replaced the above with an assertion,
and dropped the else generated from is _ -> to return unconditionally in order to silence warnings.
Program returned: 139
output.s: /app/example.cpp:49: gettype<int>(const int&)::<lambda()>: Assertion `false && "Ill-formed statement for chosen alternative!"' failed.
Program returned: 139
output.s: /app/example.cpp:49: auto gettype(const int &)::(anonymous class)::operator()() const: Assertion `false && "Ill-formed statement for chosen alternative!"' failed.
This is more complicated than that. These multiple constexpr ifs are there to eliminate cases when the evaluation of a branch is invalid for a specific inspected value/type.
I need to check if asserts will work for complex cases. For sure static_asserts were not an option.
l can capture s, but exact same lambda inside inspect cannot.
Same with s&$*
Cpp1 Error message is error: reference to local variable 's' declared in enclosing function 'main'
As far as I can tell it points at if constexpr( requires{[_0 = (&s)]() ....
Activity
JohelEGP commentedon May 7, 2023
The problem are those trailing
I think they should be replaced with a contract check or something along those lines.
The user wrote a statement for the chosen alternative, but it doesn't work for it!
JohelEGP commentedon May 7, 2023
See https://compiler-explorer.com/z/MKTTxoTn7.
I replaced the above with an assertion,
and dropped the
elsegenerated fromis _ ->to return unconditionally in order to silence warnings.realgdman commentedon May 7, 2023
Assert is good but I'm surprised that cpp1
if constexpr( requires{eats non-compilable code. Probably this can be addressed with some extra check.JohelEGP commentedon May 7, 2023
It's basically
std::invocable<closure_type>rather thanstd::invocable<closure_type, int>,so I think it's OK the branch is discarded.
JohelEGP commentedon May 8, 2023
Folded the is-convertible check into the requires expression: https://compiler-explorer.com/z/zvxn7Mea6.
filipsajdak commentedon May 8, 2023
This is more complicated than that. These multiple constexpr ifs are there to eliminate cases when the evaluation of a branch is invalid for a specific inspected value/type.
I need to check if asserts will work for complex cases. For sure static_asserts were not an option.
JohelEGP commentedon May 8, 2023
This single branch should be enough for an alternative's statement:
Followed by some kind of assertion in case the branch was discarded for the chosen alternative.
realgdman commentedon May 8, 2023
(Sorry I haven't tried any fixes)
Another observation, currently it's impossible to capture in lambda inside inspect
https://cpp2.godbolt.org/z/MGbxfTd6z
lcan captures, but exact same lambda insideinspectcannot.Same with
s&$*Cpp1 Error message is
error: reference to local variable 's' declared in enclosing function 'main'As far as I can tell it points at
if constexpr( requires{[_0 = (&s)]() ....JohelEGP commentedon Jun 3, 2023
Please, open a separate issue for that.