https://github.com/mariusdr updated https://github.com/llvm/llvm-project/pull/133574
>From bcf038103c717edfdcf633ac8f3f6f1f306d927a Mon Sep 17 00:00:00 2001 From: marius doerner <marius.doern...@icloud.com> Date: Sat, 29 Mar 2025 09:21:20 +0100 Subject: [PATCH 1/3] [clang] Clear `NeedsCleaning` flag after `ExpandBuiltinMacro` After builtin macro expansion in `Preprocessor::ExpandBuiltinMacro` the result token may have the `Token::NeedsCleaning` flag set which causes an assertion failure later on when the lexer retrives the spelling of the token in `getSpellingSlow` in Lexer.cpp. --- clang/lib/Lex/PPMacroExpansion.cpp | 2 +- clang/test/Preprocessor/embed___has_embed.c | 19 ++++++++ clang/test/Preprocessor/has_attribute.c | 20 +++++++++ clang/test/Preprocessor/has_attribute.cpp | 20 +++++++++ clang/test/Preprocessor/has_c_attribute.c | 20 +++++++++ clang/test/Preprocessor/has_include.c | 49 +++++++++++++++++++++ 6 files changed, 129 insertions(+), 1 deletion(-) diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 8e35d56d3f1a6..107d5c31e039d 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -1646,7 +1646,6 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { // Set up the return result. Tok.setIdentifierInfo(nullptr); - Tok.clearFlag(Token::NeedsCleaning); bool IsAtStartOfLine = Tok.isAtStartOfLine(); bool HasLeadingSpace = Tok.hasLeadingSpace(); @@ -2089,6 +2088,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { CreateString(OS.str(), Tok, Tok.getLocation(), Tok.getLocation()); Tok.setFlagValue(Token::StartOfLine, IsAtStartOfLine); Tok.setFlagValue(Token::LeadingSpace, HasLeadingSpace); + Tok.clearFlag(Token::NeedsCleaning); } void Preprocessor::markMacroAsUsed(MacroInfo *MI) { diff --git a/clang/test/Preprocessor/embed___has_embed.c b/clang/test/Preprocessor/embed___has_embed.c index 43a3068b5f53a..2705b5ef6fd5b 100644 --- a/clang/test/Preprocessor/embed___has_embed.c +++ b/clang/test/Preprocessor/embed___has_embed.c @@ -58,3 +58,22 @@ unsigned char buffer[] = { #else #error 17 #endif + +#if __has_embed(__FILE__\ +) +#else +#error 18 +#endif + +#define F __FI\ +LE__ +#if __has_embed(F) +#else +#error 19 +#endif + +#if __has_embed(F\ +) +#else +#error 20 +#endif diff --git a/clang/test/Preprocessor/has_attribute.c b/clang/test/Preprocessor/has_attribute.c index 0ba664a53e649..6f6f519bd299d 100644 --- a/clang/test/Preprocessor/has_attribute.c +++ b/clang/test/Preprocessor/has_attribute.c @@ -68,3 +68,23 @@ int has_no_volatile_attribute(); int has_fallthrough; #endif // CHECK: int has_fallthrough; + +#if __has_attribute(F\ +) +int has_fallthrough_2; +#endif +// CHECK: int has_fallthrough_2; + +#define F_2 fall\ +through + +#if __has_attribute(F_2) +int has_fallthrough_3; +#endif +// CHECK: int has_fallthrough_3; + +#if __has_attribute(F_2\ +) +int has_fallthrough_4; +#endif +// CHECK: int has_fallthrough_4; diff --git a/clang/test/Preprocessor/has_attribute.cpp b/clang/test/Preprocessor/has_attribute.cpp index 00ec57615c84b..72af6de27e8bb 100644 --- a/clang/test/Preprocessor/has_attribute.cpp +++ b/clang/test/Preprocessor/has_attribute.cpp @@ -116,6 +116,26 @@ int funclike_1; int funclike_2; #endif // CHECK: int funclike_2; + +#if __has_cpp_attribute(CF\ +) +int has_clang_falthrough_5; +#endif +// CHECK: int has_clang_falthrough_5; + +#define CF_2 clang::\ +fallthrough + +#if __has_cpp_attribute(CF_2) +int has_clang_falthrough_6; +#endif +// CHECK: int has_clang_falthrough_6; + +#if __has_cpp_attribute(CF_2\ +) +int has_clang_falthrough_7; +#endif +// CHECK: int has_clang_falthrough_7; } // Test for Microsoft __declspec attributes diff --git a/clang/test/Preprocessor/has_c_attribute.c b/clang/test/Preprocessor/has_c_attribute.c index 3332571d758c8..d8be13f5898a9 100644 --- a/clang/test/Preprocessor/has_c_attribute.c +++ b/clang/test/Preprocessor/has_c_attribute.c @@ -84,3 +84,23 @@ int funclike_1; int funclike_2; #endif // CHECK: int funclike_2; + +#if __has_c_attribute(CL\ +) +int has_clang_likely_5; +#endif +// CHECK: int has_clang_likely_5; + +#define CL_2 clang::\ +likely + +#if __has_c_attribute(CL_2) +int has_clang_likely_6; +#endif +// CHECK: int has_clang_likely_6; + +#if __has_c_attribute(CL_2\ +) +int has_clang_likely_7; +#endif +// CHECK: int has_clang_likely_7; diff --git a/clang/test/Preprocessor/has_include.c b/clang/test/Preprocessor/has_include.c index c95025d83860a..ff199bf23063f 100644 --- a/clang/test/Preprocessor/has_include.c +++ b/clang/test/Preprocessor/has_include.c @@ -197,3 +197,52 @@ __has_include #ifdef FOO #elif __has_include(<foo>) #endif + +#if __has_include(<stdint.h>\ +) +#else + #error "__has_include failed (10)." +#endif + +#define MACRO6 <stdint.h> +#if __has_include(MACRO6\ +) +#else + #error "__has_include failed (11)." +#endif + +#if __has_include_next(<stdint.h>/*expected-warning {{#include_next in primary source file}}*/\ +) +#else + #error "__has_include_next failed (9)." +#endif + +#if __has_include_next(MACRO6/*expected-warning {{#include_next in primary source file}}*/\ +) +#else + #error "__has_include_next failed (10)." +#endif + +#define MACRO7 <std\ +int.h> +#if __has_include(MACRO7) +#else + #error "__has_include failed (12)." +#endif + +#if __has_include(MACRO7\ +) +#else + #error "__has_include failed (13)." +#endif + +#if __has_include_next(MACRO7) //expected-warning {{#include_next in primary source file}} +#else + #error "__has_include_next failed (11)." +#endif + +#if __has_include_next(MACRO7/*expected-warning {{#include_next in primary source file}}*/\ +) +#else + #error "__has_include_next failed (12)." +#endif >From 0c9a1d413eed4e07332e0d42784ec27c41e2a1ab Mon Sep 17 00:00:00 2001 From: marius doerner <marius.doern...@icloud.com> Date: Mon, 31 Mar 2025 21:46:17 +0200 Subject: [PATCH 2/3] Blunder keep clearFlag(Token::NeedsCleaning) at the beginning of ExpandBuiltinMacro to account for early returns (e.g..in __DATE__ or __TIME__ expansion). --- clang/lib/Lex/PPMacroExpansion.cpp | 1 + clang/test/Preprocessor/pr133574.c | 121 +++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 clang/test/Preprocessor/pr133574.c diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 107d5c31e039d..37ac1bf07e9c0 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -1646,6 +1646,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { // Set up the return result. Tok.setIdentifierInfo(nullptr); + Tok.clearFlag(Token::NeedsCleaning); bool IsAtStartOfLine = Tok.isAtStartOfLine(); bool HasLeadingSpace = Tok.hasLeadingSpace(); diff --git a/clang/test/Preprocessor/pr133574.c b/clang/test/Preprocessor/pr133574.c new file mode 100644 index 0000000000000..a34073e63b760 --- /dev/null +++ b/clang/test/Preprocessor/pr133574.c @@ -0,0 +1,121 @@ +// RUN: %clang_cc1 -E -verify %s +// expected-no-diagnostics + +#define DATE_LBR __D\ +ATE__ + +const char* test1(void) { + return __DATE\ +__; +} +const char* test2(void) { + return DATE_LBR; +} + +#define TIME_LBR __TIME_\ +_ + +const char* test3(void) { + return __TIM\ +E__; +} + +const char* test4(void) { + return TIME_LBR; +} + +#define LINE_LBR __LI\ +NE__ + +int test5(void) { + return _\ +_LINE__; +} + +int test6(void) { + return LINE_LBR; +} + +#define FILE_LBR __FI\ +LE__ + +const char* test7(void) { + return __\ +FILE__; +} + +const char* test8(void) { + return FILE_LBR; +} + +#define FILE_NAME_LBR __FILE_NA\ +ME__ + +const char* test9(void) { + return __FILE_NAM\ +E__; +} + +const char* test10(void) { + return FILE_NAME_LBR; +} + +#define BASE_FILE_LBR __BASE_FIL\ +E__ + +const char* test11(void) { + return __BASE_\ +FILE__; +} + +const char* test12(void) { + return BASE_FILE_LBR; +} + +#define INCLUDE_LEVEL_LBR __INCLUDE\ +_LEVEL__ + +int test13(void) { + return __IN\ +CLUDE_LEVEL__; +} + +int test14(void) { + return INCLUDE_LEVEL_LBR; +} + +#define TIMESTAMP_LBR __TIMESTA\ +MP__ + +const char* test15(void) { + return __TIMESTA\ +MP__; +} + +const char* test16(void) { + return TIMESTAMP_LBR; +} + +#define FLT_EVAL_METHOD_LBR __FLT_EVAL_METH\ +OD__ + +int test17(void) { + return __FL\ +T_EVAL_METHOD__; +} + +int test18(void) { + return FLT_EVAL_METHOD_LBR; +} + +#define COUNTER_LBR __COUNTE\ +R__ + +int test19(void) { + return _\ +_COUNTER__; +} + +int test20(void) { + return COUNTER_LBR; +} >From 686c0857d5398c85d1e4b2dd4458e6484ce4aae6 Mon Sep 17 00:00:00 2001 From: marius doerner <marius.doern...@icloud.com> Date: Wed, 2 Apr 2025 19:36:26 +0200 Subject: [PATCH 3/3] add release notes --- clang/docs/ReleaseNotes.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 7978df0cc71cc..337ea90dc2a28 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -344,6 +344,8 @@ Bug Fixes in This Version - Defining an integer literal suffix (e.g., ``LL``) before including ``<stdint.h>`` in a freestanding build no longer causes invalid token pasting when using the ``INTn_C`` macros. (#GH85995) +- Fixed an assertion failure in the expansion of builtin macros like ``__has_embed()`` with line breaks before the + closing paren. (#GH133574) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits