Skip to content

Commit 9a1ece2

Browse files
authored
[clang] Clear NeedsCleaning flag after ExpandBuiltinMacro (#133574)
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 retrieves the spelling of the token in `getSpellingSlow`. This commit adds an `Tok.clearFlag(Token::NeedsCleaning)` call to the end of `ExpandBuiltinMacro`. Closes #128384
1 parent 8f25e43 commit 9a1ece2

File tree

8 files changed

+252
-0
lines changed

8 files changed

+252
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,8 @@ Bug Fixes in This Version
404404
- Defining an integer literal suffix (e.g., ``LL``) before including
405405
``<stdint.h>`` in a freestanding build no longer causes invalid token pasting
406406
when using the ``INTn_C`` macros. (#GH85995)
407+
- Fixed an assertion failure in the expansion of builtin macros like ``__has_embed()`` with line breaks before the
408+
closing paren. (#GH133574)
407409
- Clang no longer accepts invalid integer constants which are too large to fit
408410
into any (standard or extended) integer type when the constant is unevaluated.
409411
Merely forming the token is sufficient to render the program invalid. Code

clang/lib/Lex/PPMacroExpansion.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2089,6 +2089,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
20892089
CreateString(OS.str(), Tok, Tok.getLocation(), Tok.getLocation());
20902090
Tok.setFlagValue(Token::StartOfLine, IsAtStartOfLine);
20912091
Tok.setFlagValue(Token::LeadingSpace, HasLeadingSpace);
2092+
Tok.clearFlag(Token::NeedsCleaning);
20922093
}
20932094

20942095
void Preprocessor::markMacroAsUsed(MacroInfo *MI) {

clang/test/Preprocessor/embed___has_embed.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,22 @@ unsigned char buffer[] = {
5858
#else
5959
#error 17
6060
#endif
61+
62+
#if __has_embed(__FILE__\
63+
)
64+
#else
65+
#error 18
66+
#endif
67+
68+
#define F __FI\
69+
LE__
70+
#if __has_embed(F)
71+
#else
72+
#error 19
73+
#endif
74+
75+
#if __has_embed(F\
76+
)
77+
#else
78+
#error 20
79+
#endif

clang/test/Preprocessor/has_attribute.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,23 @@ int has_no_volatile_attribute();
6868
int has_fallthrough;
6969
#endif
7070
// CHECK: int has_fallthrough;
71+
72+
#if __has_attribute(F\
73+
)
74+
int has_fallthrough_2;
75+
#endif
76+
// CHECK: int has_fallthrough_2;
77+
78+
#define F_2 fall\
79+
through
80+
81+
#if __has_attribute(F_2)
82+
int has_fallthrough_3;
83+
#endif
84+
// CHECK: int has_fallthrough_3;
85+
86+
#if __has_attribute(F_2\
87+
)
88+
int has_fallthrough_4;
89+
#endif
90+
// CHECK: int has_fallthrough_4;

clang/test/Preprocessor/has_attribute.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,26 @@ int funclike_1;
116116
int funclike_2;
117117
#endif
118118
// CHECK: int funclike_2;
119+
120+
#if __has_cpp_attribute(CF\
121+
)
122+
int has_clang_falthrough_5;
123+
#endif
124+
// CHECK: int has_clang_falthrough_5;
125+
126+
#define CF_2 clang::\
127+
fallthrough
128+
129+
#if __has_cpp_attribute(CF_2)
130+
int has_clang_falthrough_6;
131+
#endif
132+
// CHECK: int has_clang_falthrough_6;
133+
134+
#if __has_cpp_attribute(CF_2\
135+
)
136+
int has_clang_falthrough_7;
137+
#endif
138+
// CHECK: int has_clang_falthrough_7;
119139
}
120140

121141
// Test for Microsoft __declspec attributes

clang/test/Preprocessor/has_c_attribute.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,23 @@ int funclike_1;
8484
int funclike_2;
8585
#endif
8686
// CHECK: int funclike_2;
87+
88+
#if __has_c_attribute(CL\
89+
)
90+
int has_clang_likely_5;
91+
#endif
92+
// CHECK: int has_clang_likely_5;
93+
94+
#define CL_2 clang::\
95+
likely
96+
97+
#if __has_c_attribute(CL_2)
98+
int has_clang_likely_6;
99+
#endif
100+
// CHECK: int has_clang_likely_6;
101+
102+
#if __has_c_attribute(CL_2\
103+
)
104+
int has_clang_likely_7;
105+
#endif
106+
// CHECK: int has_clang_likely_7;

clang/test/Preprocessor/has_include.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,3 +197,52 @@ __has_include
197197
#ifdef FOO
198198
#elif __has_include(<foo>)
199199
#endif
200+
201+
#if __has_include(<stdint.h>\
202+
)
203+
#else
204+
#error "__has_include failed (10)."
205+
#endif
206+
207+
#define MACRO6 <stdint.h>
208+
#if __has_include(MACRO6\
209+
)
210+
#else
211+
#error "__has_include failed (11)."
212+
#endif
213+
214+
#if __has_include_next(<stdint.h>/*expected-warning {{#include_next in primary source file}}*/\
215+
)
216+
#else
217+
#error "__has_include_next failed (9)."
218+
#endif
219+
220+
#if __has_include_next(MACRO6/*expected-warning {{#include_next in primary source file}}*/\
221+
)
222+
#else
223+
#error "__has_include_next failed (10)."
224+
#endif
225+
226+
#define MACRO7 <std\
227+
int.h>
228+
#if __has_include(MACRO7)
229+
#else
230+
#error "__has_include failed (12)."
231+
#endif
232+
233+
#if __has_include(MACRO7\
234+
)
235+
#else
236+
#error "__has_include failed (13)."
237+
#endif
238+
239+
#if __has_include_next(MACRO7) //expected-warning {{#include_next in primary source file}}
240+
#else
241+
#error "__has_include_next failed (11)."
242+
#endif
243+
244+
#if __has_include_next(MACRO7/*expected-warning {{#include_next in primary source file}}*/\
245+
)
246+
#else
247+
#error "__has_include_next failed (12)."
248+
#endif

clang/test/Preprocessor/pr133574.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
// RUN: %clang_cc1 -E -verify %s
2+
// expected-no-diagnostics
3+
4+
#define DATE_LBR __D\
5+
ATE__
6+
7+
const char* test1(void) {
8+
return __DATE\
9+
__;
10+
}
11+
const char* test2(void) {
12+
return DATE_LBR;
13+
}
14+
15+
#define TIME_LBR __TIME_\
16+
_
17+
18+
const char* test3(void) {
19+
return __TIM\
20+
E__;
21+
}
22+
23+
const char* test4(void) {
24+
return TIME_LBR;
25+
}
26+
27+
#define LINE_LBR __LI\
28+
NE__
29+
30+
int test5(void) {
31+
return _\
32+
_LINE__;
33+
}
34+
35+
int test6(void) {
36+
return LINE_LBR;
37+
}
38+
39+
#define FILE_LBR __FI\
40+
LE__
41+
42+
const char* test7(void) {
43+
return __\
44+
FILE__;
45+
}
46+
47+
const char* test8(void) {
48+
return FILE_LBR;
49+
}
50+
51+
#define FILE_NAME_LBR __FILE_NA\
52+
ME__
53+
54+
const char* test9(void) {
55+
return __FILE_NAM\
56+
E__;
57+
}
58+
59+
const char* test10(void) {
60+
return FILE_NAME_LBR;
61+
}
62+
63+
#define BASE_FILE_LBR __BASE_FIL\
64+
E__
65+
66+
const char* test11(void) {
67+
return __BASE_\
68+
FILE__;
69+
}
70+
71+
const char* test12(void) {
72+
return BASE_FILE_LBR;
73+
}
74+
75+
#define INCLUDE_LEVEL_LBR __INCLUDE\
76+
_LEVEL__
77+
78+
int test13(void) {
79+
return __IN\
80+
CLUDE_LEVEL__;
81+
}
82+
83+
int test14(void) {
84+
return INCLUDE_LEVEL_LBR;
85+
}
86+
87+
#define TIMESTAMP_LBR __TIMESTA\
88+
MP__
89+
90+
const char* test15(void) {
91+
return __TIMESTA\
92+
MP__;
93+
}
94+
95+
const char* test16(void) {
96+
return TIMESTAMP_LBR;
97+
}
98+
99+
#define FLT_EVAL_METHOD_LBR __FLT_EVAL_METH\
100+
OD__
101+
102+
int test17(void) {
103+
return __FL\
104+
T_EVAL_METHOD__;
105+
}
106+
107+
int test18(void) {
108+
return FLT_EVAL_METHOD_LBR;
109+
}
110+
111+
#define COUNTER_LBR __COUNTE\
112+
R__
113+
114+
int test19(void) {
115+
return _\
116+
_COUNTER__;
117+
}
118+
119+
int test20(void) {
120+
return COUNTER_LBR;
121+
}

0 commit comments

Comments
 (0)