diff options
author | Samira Bazuzi <bazuzi@google.com> | 2024-12-05 09:37:46 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-05 09:37:46 -0500 |
commit | f7e8be7c66b53a126c8cba9ac81b5b77d873aa1e (patch) | |
tree | abc1bd3b038c0081f25df6801c9c657940411e41 /clang/unittests/Lex/LexerTest.cpp | |
parent | 3a4b9f38915625c68c78b62de48a3de8b97c5043 (diff) | |
download | llvm-f7e8be7c66b53a126c8cba9ac81b5b77d873aa1e.zip llvm-f7e8be7c66b53a126c8cba9ac81b5b77d873aa1e.tar.gz llvm-f7e8be7c66b53a126c8cba9ac81b5b77d873aa1e.tar.bz2 |
Skip escaped newlines before checking for whitespace in Lexer::getRawToken. (#117548)
The Lexer used in getRawToken is not told to keep whitespace, so when it
skips over escaped newlines, it also ignores whitespace, regardless of
getRawToken's IgnoreWhiteSpace parameter.
Instead of letting this case fall through to lexing, check
for whitespace after skipping over any escaped newlines.
Diffstat (limited to 'clang/unittests/Lex/LexerTest.cpp')
-rw-r--r-- | clang/unittests/Lex/LexerTest.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/clang/unittests/Lex/LexerTest.cpp b/clang/unittests/Lex/LexerTest.cpp index 47aa2c1..aead7fb 100644 --- a/clang/unittests/Lex/LexerTest.cpp +++ b/clang/unittests/Lex/LexerTest.cpp @@ -652,6 +652,38 @@ TEST_F(LexerTest, RawAndNormalLexSameForLineComments) { EXPECT_TRUE(ToksView.empty()); } +TEST_F(LexerTest, GetRawTokenOnEscapedNewLineChecksWhitespace) { + const llvm::StringLiteral Source = R"cc( + #define ONE \ + 1 + + int i = ONE; + )cc"; + std::vector<Token> Toks = + CheckLex(Source, {tok::kw_int, tok::identifier, tok::equal, + tok::numeric_constant, tok::semi}); + + // Set up by getting the raw token for the `1` in the macro definition. + const Token &OneExpanded = Toks[3]; + Token Tok; + ASSERT_FALSE( + Lexer::getRawToken(OneExpanded.getLocation(), Tok, SourceMgr, LangOpts)); + // The `ONE`. + ASSERT_EQ(Tok.getKind(), tok::raw_identifier); + ASSERT_FALSE( + Lexer::getRawToken(SourceMgr.getSpellingLoc(OneExpanded.getLocation()), + Tok, SourceMgr, LangOpts)); + // The `1` in the macro definition. + ASSERT_EQ(Tok.getKind(), tok::numeric_constant); + + // Go back 4 characters: two spaces, one newline, and the backslash. + SourceLocation EscapedNewLineLoc = Tok.getLocation().getLocWithOffset(-4); + // Expect true (=failure) because the whitespace immediately after the + // escaped newline is not ignored. + EXPECT_TRUE(Lexer::getRawToken(EscapedNewLineLoc, Tok, SourceMgr, LangOpts, + /*IgnoreWhiteSpace=*/false)); +} + TEST(LexerPreambleTest, PreambleBounds) { std::vector<std::string> Cases = { R"cc([[ |