<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>