<div dir="ltr"><div dir="ltr"> On Mon, 18 Oct 2021 at 12:48, Aaron Ballman <<a href="mailto:aaron@aaronballman.com">aaron@aaronballman.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Mon, Oct 18, 2021 at 3:33 PM Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:<br>
><br>
> On Sun, 17 Oct 2021 at 04:58, Aaron Ballman via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:<br>
>><br>
>><br>
>> Author: Aaron Ballman<br>
>> Date: 2021-10-17T07:54:48-04:00<br>
>> New Revision: 2edb89c746848c52964537268bf03e7906bf2542<br>
>><br>
>> URL: <a href="https://github.com/llvm/llvm-project/commit/2edb89c746848c52964537268bf03e7906bf2542" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/2edb89c746848c52964537268bf03e7906bf2542</a><br>
>> DIFF: <a href="https://github.com/llvm/llvm-project/commit/2edb89c746848c52964537268bf03e7906bf2542.diff" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/2edb89c746848c52964537268bf03e7906bf2542.diff</a><br>
>><br>
>> LOG: Lex arguments for __has_cpp_attribute and friends as expanded tokens<br>
>><br>
>> The C and C++ standards require the argument to __has_cpp_attribute and<br>
>> __has_c_attribute to be expanded ([cpp.cond]p5). It would make little sense<br>
>> to expand the argument to those operators but not expand the argument to<br>
>> __has_attribute and __has_declspec, so those were both also changed in this<br>
>> patch.<br>
>><br>
>> Note that it might make sense for the other builtins to also expand their<br>
>> argument, but it wasn't as clear to me whether the behavior would be correct<br>
>> there, and so they were left for a future revision.<br>
>><br>
>> Added:<br>
>> clang/test/Preprocessor/has_attribute_errors.cpp<br>
>><br>
>> Modified:<br>
>> clang/docs/ReleaseNotes.rst<br>
>> clang/lib/Lex/PPMacroExpansion.cpp<br>
>> clang/test/Preprocessor/has_attribute.c<br>
>> clang/test/Preprocessor/has_attribute.cpp<br>
>> clang/test/Preprocessor/has_c_attribute.c<br>
>><br>
>> Removed:<br>
>><br>
>><br>
>><br>
>> ################################################################################<br>
>> diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst<br>
>> index 6501a4870e2a6..263eae83036df 100644<br>
>> --- a/clang/docs/ReleaseNotes.rst<br>
>> +++ b/clang/docs/ReleaseNotes.rst<br>
>> @@ -110,6 +110,13 @@ Attribute Changes in Clang<br>
>> attribute is handled instead, e.g. in ``handleDeclAttribute``.<br>
>> (This was changed in order to better support attributes in code completion).<br>
>><br>
>> +- __has_cpp_attribute, __has_c_attribute, __has_attribute, and __has_declspec<br>
>> + will now macro expand their argument. This causes a change in behavior for<br>
>> + code using ``__has_cpp_attribute(__clang__::attr)`` (and same for<br>
>> + ``__has_c_attribute``) where it would previously expand to ``0`` for all<br>
>> + attributes, but will now issue an error due to the expansion of the<br>
>> + predefined ``__clang__`` macro.<br>
>> +<br>
>> Windows Support<br>
>> ---------------<br>
>><br>
>><br>
>> diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp<br>
>> index bf19f538647e6..5a0fa5184e38b 100644<br>
>> --- a/clang/lib/Lex/PPMacroExpansion.cpp<br>
>> +++ b/clang/lib/Lex/PPMacroExpansion.cpp<br>
>> @@ -1293,7 +1293,7 @@ static bool EvaluateHasIncludeNext(Token &Tok,<br>
>> /// integer values.<br>
>> static void EvaluateFeatureLikeBuiltinMacro(llvm::raw_svector_ostream& OS,<br>
>> Token &Tok, IdentifierInfo *II,<br>
>> - Preprocessor &PP,<br>
>> + Preprocessor &PP, bool ExpandArgs,<br>
>> llvm::function_ref<<br>
>> int(Token &Tok,<br>
>> bool &HasLexedNextTok)> Op) {<br>
>> @@ -1319,7 +1319,10 @@ static void EvaluateFeatureLikeBuiltinMacro(llvm::raw_svector_ostream& OS,<br>
>> bool SuppressDiagnostic = false;<br>
>> while (true) {<br>
>> // Parse next token.<br>
>> - PP.LexUnexpandedToken(Tok);<br>
>> + if (ExpandArgs)<br>
>> + PP.Lex(Tok);<br>
>> + else<br>
>> + PP.LexUnexpandedToken(Tok);<br>
><br>
><br>
> How does this handle things like:<br>
><br>
> #define RPAREN )<br>
> #if __has_attribute(clang::fallthrough RPAREN<br>
><br>
> ? I think that should be an error: the ) token should not be produced by macro expansion, analogous to the behavior of function-like macros. But I imagine unless we're careful here, we'll allow that macro expansion to terminate the "macro".<br>
<br>
I agree, I think that should be an error. We handle it reasonably too; I get:<br>
<br>
error: missing ')' after 'clang'<br>
<br>
though it appears there is some compiler divergence here:<br>
<a href="https://godbolt.org/z/c84cb3PW7" rel="noreferrer" target="_blank">https://godbolt.org/z/c84cb3PW7</a></blockquote><div><br></div><div>Oops, I meant __has_cpp_attribute, not __has_attribute. We mishandle that one just like GCC: <a href="https://godbolt.org/z/Ej84Kca16">https://godbolt.org/z/Ej84Kca16</a> </div></div></div>