Cannot use lambda expression within MOZ_ASSERT
Categories
(Core :: MFBT, defect)
Tracking
()
People
(Reporter: sg, Unassigned)
Details
Attempting to use a lambda expression as the condition of MOZ_ASSERT results in error: lambda expression in an unevaluated operand
, e.g.
MOZ_ASSERT([] { return true; }());
This example is not useful, but I stripped it down to show that it is unrelated to any other constructs. A useful example that yields the same error might be:
MOZ_ASSERT(std::all_of(mObjectStores.cbegin(), mObjectStores.cend(),
[&name = aSpec.metadata().name()](const auto& objectStore) {
return objectStore->Name() != name;
}));
glibc's assert macro had a similar issue, which was solved by https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=assert/assert.h;h=640c95c06344ffbf1971793e8aaf283aad6679e2;hp=6801cfeb10debf7a9e0d6e425ecfb0c68b2ca42a;hb=b5889d25e9bf944a89fdd7bcabf3b6c6f6bb6f7c;hpb=41e673c1e771075f413f8e8ecd9e108f5ae096d9 but the situation is different for MOZ_ASSERT, since MOZ_VALIDATE_ASSERT_CONDITION_TYPE
involves decltype(cond)
. This issue will resolve with C++20 since it will incorporate a changed wording around lambdas in unevaluated contexts (cf. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0315r3.pdf), however for the time being, a solution would be good. If MOZ_VALIDATE_ASSERT_CONDITION_TYPE
should not be changed, maybe a variant of MOZ_ASSERT
could be introduced that specifically works around this issue, but should not be used in cases where no lambda expression is involved.
Hmph. This is awkward, because to a human it's obvious that type of std::all_of(...)
is bool
, but the compiler, in the process of following its rules very precisely, gets caught up on the lambda. I wonder if we can find a way to make the compiler admit to the overall-bool-ness without worrying about the details.
Can we rewrite the validation without decltype
? Maybe move the checks into a templated function like...
template <class T> bool CheckAssertType(T val) {
static_assert(!IsArray<T>, etc);
return val;
}
(We'd probably want to coordinate with MOZ_CHECK_ASSERT_ASSIGNMENT
somehow)
Comment 2•5 years ago
|
||
One quick problem with comment 1's approach -- I'm fairly sure -- is that because of array-to-pointer decay that particular static assertion would never fail. (Function pointer testing, at least, would probably still work.)
Another possibility that occurred to me is having a bool b { expr }; check b;
approach, on the theory that braced-init will forbid a narrowing conversion, but in practice it seems like function pointers can decay in such fashion. (Albeit with a warning in clang.) Maybe a warning is enough smell that such mistakes would get quickly sussed out, I dunno. Maybe?
There's probably some approach that works here, somehow or other.
Reporter | ||
Comment 3•5 years ago
|
||
I am wondering if we have tests that assert that certain code does not compile? If so, where can I find those?
We do that in clang-plugin tests: https://searchfox.org/mozilla-central/search?q=expected-error
In particular, TestAssertWithAssignment looks relevant to the problem at hand: https://searchfox.org/mozilla-central/source/build/clang-plugin/tests/TestAssertWithAssignment.cpp
Updated•2 years ago
|
Description
•