From b3e96f700e390164e3a99f64b236844a78ca331f Mon Sep 17 00:00:00 2001 From: David Majnemer Date: Thu, 11 Dec 2014 01:00:48 +0000 Subject: [PATCH] Parse: Concatenated string literals should be verified in inline asm While we would correctly handle asm("foo") and reject asm(L"bar"), we weren't careful to handle cases where an ascii literal could be concatenated with a wide literal. This fixes PR21822. llvm-svn: 223992 --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 1 - clang/lib/Parse/Parser.cpp | 29 +++++++++++------------- clang/lib/Sema/SemaStmtAsm.cpp | 16 ++++--------- clang/test/Parser/asm.cpp | 1 + 4 files changed, 18 insertions(+), 29 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 28ac96d..c78aba4 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6143,7 +6143,6 @@ def warn_cast_qual2 : Warning<"cast from %0 to %1 must have all intermediate " // inline asm. let CategoryName = "Inline Assembly Issue" in { - def err_asm_wide_character : Error<"wide string is invalid in 'asm'">; def err_asm_invalid_lvalue_in_output : Error<"invalid lvalue in asm output">; def err_asm_invalid_output_constraint : Error< "invalid output constraint '%0' in asm">; diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 4ddc5bf..7119e9a 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1224,26 +1224,23 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) { /// string-literal /// ExprResult Parser::ParseAsmStringLiteral() { - switch (Tok.getKind()) { - case tok::string_literal: - break; - case tok::utf8_string_literal: - case tok::utf16_string_literal: - case tok::utf32_string_literal: - case tok::wide_string_literal: { - SourceLocation L = Tok.getLocation(); + if (!isTokenStringLiteral()) { + Diag(Tok, diag::err_expected_string_literal) + << /*Source='in...'*/0 << "'asm'"; + return ExprError(); + } + + ExprResult AsmString(ParseStringLiteralExpression()); + if (!AsmString.isInvalid()) { + const auto *SL = cast(AsmString.get()); + if (!SL->isAscii()) { Diag(Tok, diag::err_asm_operand_wide_string_literal) - << (Tok.getKind() == tok::wide_string_literal) - << SourceRange(L, L); + << SL->isWide() + << SL->getSourceRange(); return ExprError(); } - default: - Diag(Tok, diag::err_expected_string_literal) - << /*Source='in...'*/0 << "'asm'"; - return ExprError(); } - - return ParseStringLiteralExpression(); + return AsmString; } /// ParseSimpleAsm diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index a2e436a..e0f3dfe 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -116,15 +116,11 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, SmallVector OutputConstraintInfos; // The parser verifies that there is a string literal here. - if (!AsmString->isAscii()) - return StmtError(Diag(AsmString->getLocStart(),diag::err_asm_wide_character) - << AsmString->getSourceRange()); + assert(AsmString->isAscii()); for (unsigned i = 0; i != NumOutputs; i++) { StringLiteral *Literal = Constraints[i]; - if (!Literal->isAscii()) - return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character) - << Literal->getSourceRange()); + assert(Literal->isAscii()); StringRef OutputName; if (Names[i]) @@ -172,9 +168,7 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) { StringLiteral *Literal = Constraints[i]; - if (!Literal->isAscii()) - return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character) - << Literal->getSourceRange()); + assert(Literal->isAscii()); StringRef InputName; if (Names[i]) @@ -240,9 +234,7 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, // Check that the clobbers are valid. for (unsigned i = 0; i != NumClobbers; i++) { StringLiteral *Literal = Clobbers[i]; - if (!Literal->isAscii()) - return StmtError(Diag(Literal->getLocStart(),diag::err_asm_wide_character) - << Literal->getSourceRange()); + assert(Literal->isAscii()); StringRef Clobber = Literal->getString(); diff --git a/clang/test/Parser/asm.cpp b/clang/test/Parser/asm.cpp index 35a497c..9f64dfe 100644 --- a/clang/test/Parser/asm.cpp +++ b/clang/test/Parser/asm.cpp @@ -6,3 +6,4 @@ int foo3 asm (u8"bar3"); // expected-error {{cannot use unicode string literal i int foo4 asm (u"bar4"); // expected-error {{cannot use unicode string literal in 'asm'}} int foo5 asm (U"bar5"); // expected-error {{cannot use unicode string literal in 'asm'}} int foo6 asm ("bar6"_x); // expected-error {{string literal with user-defined suffix cannot be used here}} +int foo6 asm ("" L"bar7"); // expected-error {{cannot use wide string literal in 'asm'}} -- 2.7.4