diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp index 4c9250236a3b54..2f749bf7a6989e 100644 --- a/llvm/lib/Support/CommandLine.cpp +++ b/llvm/lib/Support/CommandLine.cpp @@ -1008,7 +1008,7 @@ tokenizeWindowsCommandLineImpl(StringRef Src, StringSaver &Saver, } } - if (State == UNQUOTED) + if (State != INIT) AddToken(Saver.save(Token.str())); } diff --git a/llvm/lib/Support/Windows/Process.inc b/llvm/lib/Support/Windows/Process.inc index dfaab1613de185..b1af298d9e83ea 100644 --- a/llvm/lib/Support/Windows/Process.inc +++ b/llvm/lib/Support/Windows/Process.inc @@ -255,6 +255,9 @@ windows::GetCommandLineArguments(SmallVectorImpl &Args, return EC; } + if (Args.size() == 0) + return std::make_error_code(std::errc::invalid_argument); + SmallVector Arg0(Args[0], Args[0] + strlen(Args[0])); SmallVector Filename; sys::path::remove_filename(Arg0); diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp index dd02d920126520..7f751e5e101bd3 100644 --- a/llvm/unittests/Support/CommandLineTest.cpp +++ b/llvm/unittests/Support/CommandLineTest.cpp @@ -237,12 +237,24 @@ TEST(CommandLineTest, TokenizeWindowsCommandLine2) { } TEST(CommandLineTest, TokenizeWindowsCommandLineQuotedLastArgument) { + // Whitespace at the end of the command line doesn't cause an empty last word + const char Input0[] = R"(a b c d )"; + const char *const Output0[] = {"a", "b", "c", "d"}; + testCommandLineTokenizer(cl::TokenizeWindowsCommandLine, Input0, Output0); + + // But an explicit "" does const char Input1[] = R"(a b c d "")"; const char *const Output1[] = {"a", "b", "c", "d", ""}; testCommandLineTokenizer(cl::TokenizeWindowsCommandLine, Input1, Output1); + + // An unterminated quoted string is also emitted as an argument word, empty + // or not const char Input2[] = R"(a b c d ")"; - const char *const Output2[] = {"a", "b", "c", "d"}; + const char *const Output2[] = {"a", "b", "c", "d", ""}; testCommandLineTokenizer(cl::TokenizeWindowsCommandLine, Input2, Output2); + const char Input3[] = R"(a b c d "text)"; + const char *const Output3[] = {"a", "b", "c", "d", "text"}; + testCommandLineTokenizer(cl::TokenizeWindowsCommandLine, Input3, Output3); } TEST(CommandLineTest, TokenizeAndMarkEOLs) {