[llvm-bugs] [Bug 47941] New: "this requires expression will only be checked for syntactic validity" suggests bad fixit, is not emitted on equally dangerous code
via llvm-bugs
llvm-bugs at lists.llvm.org
Wed Oct 21 21:34:25 PDT 2020
https://bugs.llvm.org/show_bug.cgi?id=47941
Bug ID: 47941
Summary: "this requires expression will only be checked for
syntactic validity" suggests bad fixit, is not emitted
on equally dangerous code
Product: clang
Version: unspecified
Hardware: All
OS: All
Status: NEW
Severity: enhancement
Priority: P
Component: -New Bugs
Assignee: unassignedclangbugs at nondot.org
Reporter: arthur.j.odwyer at gmail.com
CC: htmldeveloper at gmail.com, llvm-bugs at lists.llvm.org,
neeilans at live.com, richard-llvm at metafoo.co.uk
// https://godbolt.org/z/hhWdzd
template<class T>
concept Foo = requires {
{ requires { sizeof(T)==0; } };
};
static_assert(Foo<int>);
template<class T>
concept Bar = requires {
sizeof(T)==0;
};
static_assert(Bar<int>);
template<class T>
concept Baz = requires {
requires requires { sizeof(T)==0; };
};
static_assert(Baz<int>);
===
These are all correct C++20 behavior, but it's surprising that the
user-programmer can end up here by the usual "add/remove braces until the
compiler stops complaining" approach. Start with
template<class T>
concept Foo = requires {
requires { sizeof(T)==0 };
};
Clang complains:
<source>:3:28: error: expected ';' at end of requirement
requires { sizeof(T)==0 };
^
;
<source>:3:5: warning: this requires expression will only be checked for
syntactic validity; did you intend to place it in a nested requirement? (add
another 'requires' before the expression) [-Wrequires-expression]
requires { sizeof(T)==0 };
^
requires
That is, Clang is suggesting:
template<class T>
concept Foo = requires {
requires requires { sizeof(T)==0; };
};
(which, to be clear, ALSO does not do what the user intended!)
Or, we can throw braces around the whole thing instead, and Clang will be
equally satisfied:
template<class T>
concept Foo = requires {
{ requires { sizeof(T)==0; } };
};
Or, we can "cancel out" the two `requires requires` Clang suggested, and Clang
will be equally satisfied:
template<class T>
concept Foo = requires {
sizeof(T)==0;
};
Basically, I think Clang should continue to complain about all of these. The
only way to shut it up should be the universal signal, "redundant parentheses
around the condition."
template<class T>
concept Foo = requires {
((sizeof(T)==0)); // OK, I guess
(requires { sizeof(T)==0; }); // OK, I guess
};
The current diagnostics seem to be in a sour spot of moral hazard, where Clang
seems to be TRYING to help the user-programmer, but actually ignores a lot of
equally dangerous alternatives.
Is Clang clever enough to detect when the condition is guaranteed to be a
constant-expression for any T? e.g. sizeof(T)==0 is a constant-expression
regardless of T, because sizeof(T) is integral. When it's a constant
expression, I think the likelihood is high that the programmer intended to test
truthiness, not well-formedness.
Also notice that sizeof(T)==0 doesn't depend on any
requires-expression-parameters; that's an obvious difference between it and
e.g. `requires(T t) { sizeof(T)==t; }` (which arguably is clear enough in its
intent to test well-formedness instead of truthiness).
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20201022/e0edd90e/attachment.html>
More information about the llvm-bugs
mailing list