Author: Shafik Yaghmour Date: 2023-02-17T14:57:32-08:00 New Revision: d6d59e660bc75d14f423fb3817834f832bbf4543
URL: https://github.com/llvm/llvm-project/commit/d6d59e660bc75d14f423fb3817834f832bbf4543 DIFF: https://github.com/llvm/llvm-project/commit/d6d59e660bc75d14f423fb3817834f832bbf4543.diff LOG: [Clang] Fix __VA_OPT__ implementation so that it treats the concatenation of a non-placemaker token and placemaker token as a non-placemaker token Currently the implementation of __VA_OPT__ will treat the concatenation of a non-placemaker token and placemaker token as a placemaker token which is not correct. This will fix the implementation and treat the result as a non-placemaker token. This fixes: https://github.com/llvm/llvm-project/issues/60268 Differential Revision: https://reviews.llvm.org/D142604 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/Lex/TokenLexer.cpp clang/test/Preprocessor/macro_vaopt_p1042r1.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index b6d3473929551..fbd729548f697 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -144,6 +144,9 @@ Bug Fixes in This Version - Fix assert that fails when the expression causing the this pointer to be captured by a block is part of a constexpr if statement's branch and instantiation of the enclosing method causes the branch to be discarded. +- Fix __VA_OPT__ implementation so that it treats the concatenation of a + non-placemaker token and placemaker token as a non-placemaker token. + (`#60268 <https://github.com/llvm/llvm-project/issues/60268>`_) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp index c6968b9f417e1..e0cd77b0db8f0 100644 --- a/clang/lib/Lex/TokenLexer.cpp +++ b/clang/lib/Lex/TokenLexer.cpp @@ -500,8 +500,7 @@ void TokenLexer::ExpandFunctionArguments() { // the first token in a __VA_OPT__ after a ##, delete the ##. assert(VCtx.isInVAOpt() && "should only happen inside a __VA_OPT__"); VCtx.hasPlaceholderAfterHashhashAtStart(); - } - if (RParenAfter) + } else if (RParenAfter) VCtx.hasPlaceholderBeforeRParen(); } continue; @@ -567,7 +566,7 @@ void TokenLexer::ExpandFunctionArguments() { continue; } - if (RParenAfter) + if (RParenAfter && !NonEmptyPasteBefore) VCtx.hasPlaceholderBeforeRParen(); // If this is on the RHS of a paste operator, we've already copied the diff --git a/clang/test/Preprocessor/macro_vaopt_p1042r1.cpp b/clang/test/Preprocessor/macro_vaopt_p1042r1.cpp index f12dd20b82113..c0c4b90f0f53a 100644 --- a/clang/test/Preprocessor/macro_vaopt_p1042r1.cpp +++ b/clang/test/Preprocessor/macro_vaopt_p1042r1.cpp @@ -1,30 +1,36 @@ - RUN: %clang_cc1 -E %s -pedantic -std=c++2a | FileCheck -strict-whitespace %s - -#define LPAREN() ( -#define G(Q) 42 -#define F1(R, X, ...) __VA_OPT__(G R X) ) -1: int x = F1(LPAREN(), 0, <:-); -// CHECK: 1: int x = 42; - -#define F2(...) f(0 __VA_OPT__(,) __VA_ARGS__) -#define EMP -2: F2(EMP) -// CHECK: 2: f(0 ) - -#define H3(X, ...) #__VA_OPT__(X##X X##X) -3: H3(, 0) -// CHECK: 3: "" - -#define H4(X, ...) __VA_OPT__(a X ## X) ## b -4: H4(, 1) -// CHECK: 4: a b - -#define H4B(X, ...) a ## __VA_OPT__(X ## X b) -4B: H4B(, 1) -// CHECK: 4B: a b - -#define H5A(...) __VA_OPT__()/**/__VA_OPT__() -#define H5B(X) a ## X ## b -#define H5C(X) H5B(X) -5: H5C(H5A()) -// CHECK: 5: ab + RUN: %clang_cc1 -E %s -pedantic -std=c++2a | FileCheck -strict-whitespace %s + +#define LPAREN() ( +#define G(Q) 42 +#define F1(R, X, ...) __VA_OPT__(G R X) ) +1: int x = F1(LPAREN(), 0, <:-); +// CHECK: 1: int x = 42; + +#define F2(...) f(0 __VA_OPT__(,) __VA_ARGS__) +#define EMP +2: F2(EMP) +// CHECK: 2: f(0 ) + +#define H3(X, ...) #__VA_OPT__(X##X X##X) +3: H3(, 0) +// CHECK: 3: "" + +#define H4(X, ...) __VA_OPT__(a X ## X) ## b +4: H4(, 1) +// CHECK: 4: a b + +#define H4B(X, ...) a ## __VA_OPT__(X ## X b) +4B: H4B(, 1) +// CHECK: 4B: a b + +#define H5A(...) __VA_OPT__()/**/__VA_OPT__() +#define H5B(X) a ## X ## b +#define H5C(X) H5B(X) +5: H5C(H5A()) +// CHECK: 5: ab + +namespace GH60268 { +#define H6(X, ...) __VA_OPT__(a ## X) ## b +6: H6(, 1); +// CHECK: 6: ab +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits