diff --git a/llvm/lib/MC/MCParser/AsmLexer.cpp b/llvm/lib/MC/MCParser/AsmLexer.cpp index e08404ae0ad92..778ca340e1248 100644 --- a/llvm/lib/MC/MCParser/AsmLexer.cpp +++ b/llvm/lib/MC/MCParser/AsmLexer.cpp @@ -646,7 +646,6 @@ AsmToken AsmLexer::LexQuote() { return AsmToken(AsmToken::String, StringRef(TokStart, CurPtr - TokStart)); } - // TODO: does gas allow multiline string constants? while (CurChar != '"') { if (CurChar == '\\') { // Allow \", etc. diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index ee5bebf324570..d05712bca73cd 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -3033,6 +3033,11 @@ bool AsmParser::parseEscapedString(std::string &Data) { StringRef Str = getTok().getStringContents(); for (unsigned i = 0, e = Str.size(); i != e; ++i) { if (Str[i] != '\\') { + if (Str[i] == '\n') { + SMLoc NewlineLoc = SMLoc::getFromPointer(Str.data() + i); + if (Warning(NewlineLoc, "unterminated string; newline inserted")) + return true; + } Data += Str[i]; continue; } diff --git a/llvm/test/MC/ELF/warn-newline-in-escaped-string.s b/llvm/test/MC/ELF/warn-newline-in-escaped-string.s new file mode 100644 index 0000000000000..64de13969ffb0 --- /dev/null +++ b/llvm/test/MC/ELF/warn-newline-in-escaped-string.s @@ -0,0 +1,55 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64 %s 2>&1 -o /dev/null \ +// RUN: | FileCheck %s --implicit-check-not=warning: + +.string "abcd\xFFefg +12345678" + +// CHECK: [[#@LINE-3]]:21: warning: unterminated string; newline inserted +// CHECK-NEXT: .string "abcd\xFFefg + +.ascii "some test ascii + +sequence +with +newlines\x0A +" + +// CHECK: [[#@LINE-7]]:24: warning: unterminated string; newline inserted +// CHECK-NEXT: .ascii "some test ascii +// CHECK: [[#@LINE-8]]:1: warning: unterminated string; newline inserted +// CHECK: [[#@LINE-8]]:9: warning: unterminated string; newline inserted +// CHECK-NEXT: sequence +// CHECK: [[#@LINE-9]]:5: warning: unterminated string; newline inserted +// CHECK-NEXT: with +// CHECK: [[#@LINE-10]]:13: warning: unterminated string; newline inserted +// CHECK-NEXT: newlines\x0A + +.asciz "another test string + +with +newline characters + + +" + +// CHECK: [[#@LINE-8]]:28: warning: unterminated string; newline inserted +// CHECK-NEXT: .asciz "another test string +// CHECK: [[#@LINE-9]]:1: warning: unterminated string; newline inserted +// CHECK: [[#@LINE-9]]:5: warning: unterminated string; newline inserted +// CHECK-NEXT: with +// CHECK: [[#@LINE-10]]:19: warning: unterminated string; newline inserted +// CHECK-NEXT: newline characters +// CHECK: [[#@LINE-11]]:1: warning: unterminated string; newline inserted +// CHECK: [[#@LINE-11]]:1: warning: unterminated string; newline inserted + +.file "warn-newline +.s" +// CHECK: [[#@LINE-2]]:20: warning: unterminated string; newline inserted + +.cv_file 1 "some_an +other_file.s" +// CHECK: [[#@LINE-2]]:20: warning: unterminated string; newline inserted + +.ascii "test\nvalid1_string\xFF\n\n\xFF" +.asciz "\n\n\nvalid2_string\x0A" +.string "1234\nvalid3_string\xFF\n\xFF\n"