From: David Majnemer Date: Thu, 11 Dec 2014 01:00:48 +0000 (+0000) Subject: Parse: Concatenated string literals should be verified in inline asm X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=63d2f8d889e9b77e09205645bdc3bde41ace8305;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@223992 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 28ac96db91..c78aba4c5d 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/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/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 4ddc5bfdad..7119e9af76 100644 --- a/lib/Parse/Parser.cpp +++ b/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/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index a2e436ae7e..e0f3dfe6e0 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/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/test/Parser/asm.cpp b/test/Parser/asm.cpp index 35a497c83a..9f64dfea47 100644 --- a/test/Parser/asm.cpp +++ b/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'}}