https://github.com/abhina-sree updated https://github.com/llvm/llvm-project/pull/201413
>From 48e2f214a3864b0136817497fb2684fd93673774 Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Wed, 3 Jun 2026 13:09:51 -0400 Subject: [PATCH 1/6] change line and digit directive to be unevaluated strings --- clang/lib/Lex/PPDirectives.cpp | 6 ++++-- clang/test/Preprocessor/line-directive-output.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index eb21a510dcf83..20f2575254e7b 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -1646,7 +1646,8 @@ void Preprocessor::HandleLineDirective() { return; } else { // Parse and validate the string, converting it into a unique ID. - StringLiteralParser Literal(StrTok, *this); + StringLiteralParser Literal(StrTok, *this, + StringLiteralEvalMethod::Unevaluated); assert(Literal.isOrdinary() && "Didn't allow wide strings in"); if (Literal.hadError) { DiscardUntilEndOfDirective(); @@ -1797,7 +1798,8 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) { return; } else { // Parse and validate the string, converting it into a unique ID. - StringLiteralParser Literal(StrTok, *this); + StringLiteralParser Literal(StrTok, *this, + StringLiteralEvalMethod::Unevaluated); assert(Literal.isOrdinary() && "Didn't allow wide strings in"); if (Literal.hadError) { DiscardUntilEndOfDirective(); diff --git a/clang/test/Preprocessor/line-directive-output.c b/clang/test/Preprocessor/line-directive-output.c index 5e3dec155cad4..0e66487bd20c9 100644 --- a/clang/test/Preprocessor/line-directive-output.c +++ b/clang/test/Preprocessor/line-directive-output.c @@ -76,7 +76,7 @@ extern int z; # 49 "A.c" // CHECK: # 50 "a\n.c" -# 50 "a\012.c" +# 50 "a\n.c" # 1 "system.h" 3 # 2 >From 6ddbf0349cda71cdcba2b6db335ab16fa6a749da Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Wed, 3 Jun 2026 14:37:27 -0400 Subject: [PATCH 2/6] add more tests --- clang/test/Preprocessor/line-directive.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clang/test/Preprocessor/line-directive.c b/clang/test/Preprocessor/line-directive.c index 676e07a5571ab..4fb05a4ea2f6e 100644 --- a/clang/test/Preprocessor/line-directive.c +++ b/clang/test/Preprocessor/line-directive.c @@ -125,3 +125,8 @@ undefined t; // expected-error {{unknown type name 'undefined'}} # 121 "" 2 // pop to "main": expected-warning {{this style of line directive is a GNU extension}} #error MAIN2 // expected-error@-1{{MAIN2}} + +#line 129 L"wide" // expected-error {{invalid filename for #line directive}} +#line 130 "\x12" // expected-error {{invalid escape sequence '\x12' in an unevaluated string literal}} +# 131 U"hello" // expected-error {{invalid filename for line marker directive}} +# 132 "\x13" // expected-error {{invalid escape sequence '\x13' in an unevaluated string literal}} >From 38b8b2f27cc0444e5878d8b0b24d8ab99ab7eccd Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Wed, 3 Jun 2026 15:12:01 -0400 Subject: [PATCH 3/6] change more to unevaluated --- clang/lib/Frontend/FrontendAction.cpp | 3 ++- clang/lib/Lex/Pragma.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index 7754861fabaf0..55e3877384622 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -525,7 +525,8 @@ static SourceLocation ReadOriginalFileName(CompilerInstance &CI, if (T.isAtStartOfLine() || T.getKind() != tok::string_literal) return SourceLocation(); - StringLiteralParser Literal(T, CI.getPreprocessor()); + StringLiteralParser Literal(T, CI.getPreprocessor(), + StringLiteralEvalMethod::Unevaluated); if (Literal.hadError) return SourceLocation(); RawLexer->LexFromRawLexer(T); diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp index 60577ef77dba7..9b48a45ade668 100644 --- a/clang/lib/Lex/Pragma.cpp +++ b/clang/lib/Lex/Pragma.cpp @@ -779,7 +779,7 @@ static bool LexModuleNameComponent(Preprocessor &PP, Token &Tok, bool First) { PP.LexUnexpandedToken(Tok); if (Tok.is(tok::string_literal) && !Tok.hasUDSuffix()) { - StringLiteralParser Literal(Tok, PP); + StringLiteralParser Literal(Tok, PP, StringLiteralEvalMethod::Unevaluated); if (Literal.hadError) return true; ModuleNameComponent = IdentifierLoc( >From ae0603bc53e0f39477c30a57b2200e9a5d6a4532 Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Thu, 25 Jun 2026 08:54:48 -0400 Subject: [PATCH 4/6] add testcase for invalid filename with escape character --- clang/test/Frontend/linemarker-invalid-escape.c | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 clang/test/Frontend/linemarker-invalid-escape.c diff --git a/clang/test/Frontend/linemarker-invalid-escape.c b/clang/test/Frontend/linemarker-invalid-escape.c new file mode 100644 index 0000000000000..a8239f81f152d --- /dev/null +++ b/clang/test/Frontend/linemarker-invalid-escape.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -emit-llvm -o - -verify %s + +# 1 "original\x12source.c" // expected-error {{invalid escape sequence '\x12' in an unevaluated string literal}} + +int x = 0; >From 61ccc6f42a03cbbd4f6b1074f4f1eb316bfd3159 Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Thu, 25 Jun 2026 09:08:53 -0400 Subject: [PATCH 5/6] add another testcase for change in LexModuleNameComponent --- clang/test/Preprocessor/pragma_module.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/test/Preprocessor/pragma_module.c b/clang/test/Preprocessor/pragma_module.c index 2d86b989411fd..b3b2e5f3bbcc1 100644 --- a/clang/test/Preprocessor/pragma_module.c +++ b/clang/test/Preprocessor/pragma_module.c @@ -12,6 +12,8 @@ #pragma clang module import foo ? bar // expected-warning {{extra tokens at end of #pragma}} #pragma clang module import foo. // expected-error {{expected identifier after '.' in module name}} #pragma clang module import foo.bar.baz.quux // expected-error {{no submodule named 'bar' in module 'foo'}} +#pragma clang module import "\x41" // expected-error {{invalid escape sequence '\x41' in an unevaluated string literal}} +#pragma clang module import "foo"."\x41" // expected-error {{invalid escape sequence '\x41' in an unevaluated string literal}} #pragma clang module begin ! // expected-error {{expected module name}} >From 31fc7147c7cfc18c28e7c8a752207ec774233250 Mon Sep 17 00:00:00 2001 From: Abhina Sreeskantharajan <[email protected]> Date: Fri, 26 Jun 2026 08:57:32 -0400 Subject: [PATCH 6/6] add a release note since this is a potential breaking change --- clang/docs/ReleaseNotes.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 8bb17755b28f5..b49c86abd63de 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -71,6 +71,16 @@ C/C++ Language Potentially Breaking Changes Clang would previously ``break`` out of the ``while`` loop, whereas GCC (since version 9) would ``break`` out of the ``for`` loop here. Now, Clang and GCC both break out of the ``for`` loop. +- Clang now parses line and digit directives, module names, and original filenames as unevaluated + strings. This means that code containing strings with escape sequences such as + + .. code-block:: c++ + # 1 "original\x12source.c" + #pragma clang module import "\x41" + # 50 "a\012.c" + + are now ill-formed. + C++ Specific Potentially Breaking Changes ----------------------------------------- _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
