<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - "this requires expression will only be checked for syntactic validity" suggests bad fixit, is not emitted on equally dangerous code"
href="https://bugs.llvm.org/show_bug.cgi?id=47941">47941</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>"this requires expression will only be checked for syntactic validity" suggests bad fixit, is not emitted on equally dangerous code
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Hardware</th>
<td>All
</td>
</tr>
<tr>
<th>OS</th>
<td>All
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>-New Bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>arthur.j.odwyer@gmail.com
</td>
</tr>
<tr>
<th>CC</th>
<td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk
</td>
</tr></table>
<p>
<div>
<pre>// <a href="https://godbolt.org/z/hhWdzd">https://godbolt.org/z/hhWdzd</a>
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).</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>