From: Chris Lattner Date: Wed, 23 Jul 2008 06:46:56 +0000 (+0000) Subject: Fix rdar://6094010 various asserts happening with wide strings in inline asm. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6bc52112dbc54551bd8e215d95bba4791b2275f7;p=clang Fix rdar://6094010 various asserts happening with wide strings in inline asm. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53947 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 549c77beae..e0218918c8 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -985,6 +985,8 @@ DIAG(warn_unused_expr, WARNING, "expression result unused") DIAG(err_pascal_string_too_long, ERROR, "Pascal string is too long") +DIAG(err_asm_wide_character, ERROR, + "wide string is invalid in 'asm'") DIAG(err_invalid_lvalue_in_asm_output, ERROR, "invalid lvalue in asm output") DIAG(err_invalid_output_constraint_in_asm, ERROR, diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index a1ec7d9930..5b2da08784 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -676,28 +676,33 @@ Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, std::string *Names, ExprTy **Constraints, ExprTy **Exprs, - ExprTy *AsmString, + ExprTy *asmString, unsigned NumClobbers, ExprTy **Clobbers, SourceLocation RParenLoc) { - Expr *E = (Expr *)AsmString; - + // The parser verifies that there is a string literal here. + StringLiteral *AsmString = cast((Expr *)asmString); + if (AsmString->isWide()) + // FIXME: We currently leak memory here. + return Diag(AsmString->getLocStart(), diag::err_asm_wide_character, + AsmString->getSourceRange()); + + for (unsigned i = 0; i < NumOutputs; i++) { StringLiteral *Literal = cast((Expr *)Constraints[i]); - assert(!Literal->isWide() && - "Output constraint strings should not be wide!"); - + if (Literal->isWide()) + // FIXME: We currently leak memory here. + return Diag(Literal->getLocStart(), diag::err_asm_wide_character, + Literal->getSourceRange()); + std::string OutputConstraint(Literal->getStrData(), Literal->getByteLength()); TargetInfo::ConstraintInfo info; - if (!Context.Target.validateOutputConstraint(OutputConstraint.c_str(), - info)) { + if (!Context.Target.validateOutputConstraint(OutputConstraint.c_str(),info)) // FIXME: We currently leak memory here. - Diag(Literal->getLocStart(), - diag::err_invalid_output_constraint_in_asm); - return true; - } + return Diag(Literal->getLocStart(), + diag::err_invalid_output_constraint_in_asm); // Check that the output exprs are valid lvalues. Expr *OutputExpr = (Expr *)Exprs[i]; @@ -705,19 +710,19 @@ Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, if (Result != Expr::LV_Valid) { ParenExpr *PE = cast(OutputExpr); - Diag(PE->getSubExpr()->getLocStart(), - diag::err_invalid_lvalue_in_asm_output, - PE->getSubExpr()->getSourceRange()); - // FIXME: We currently leak memory here. - return true; + return Diag(PE->getSubExpr()->getLocStart(), + diag::err_invalid_lvalue_in_asm_output, + PE->getSubExpr()->getSourceRange()); } } for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) { StringLiteral *Literal = cast((Expr *)Constraints[i]); - assert(!Literal->isWide() && - "Output constraint strings should not be wide!"); + if (Literal->isWide()) + // FIXME: We currently leak memory here. + return Diag(Literal->getLocStart(), diag::err_asm_wide_character, + Literal->getSourceRange()); std::string InputConstraint(Literal->getStrData(), Literal->getByteLength()); @@ -727,9 +732,8 @@ Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, NumOutputs, info)) { // FIXME: We currently leak memory here. - Diag(Literal->getLocStart(), - diag::err_invalid_input_constraint_in_asm); - return true; + return Diag(Literal->getLocStart(), + diag::err_invalid_input_constraint_in_asm); } // Check that the input exprs aren't of type void. @@ -737,33 +741,30 @@ Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, if (InputExpr->getType()->isVoidType()) { ParenExpr *PE = cast(InputExpr); - Diag(PE->getSubExpr()->getLocStart(), - diag::err_invalid_type_in_asm_input, - PE->getType().getAsString(), - PE->getSubExpr()->getSourceRange()); - // FIXME: We currently leak memory here. - return true; + return Diag(PE->getSubExpr()->getLocStart(), + diag::err_invalid_type_in_asm_input, + PE->getType().getAsString(), + PE->getSubExpr()->getSourceRange()); } } // Check that the clobbers are valid. for (unsigned i = 0; i < NumClobbers; i++) { StringLiteral *Literal = cast((Expr *)Clobbers[i]); - assert(!Literal->isWide() && "Clobber strings should not be wide!"); + if (Literal->isWide()) + // FIXME: We currently leak memory here. + return Diag(Literal->getLocStart(), diag::err_asm_wide_character, + Literal->getSourceRange()); llvm::SmallString<16> Clobber(Literal->getStrData(), Literal->getStrData() + Literal->getByteLength()); - if (!Context.Target.isValidGCCRegisterName(Clobber.c_str())) { - Diag(Literal->getLocStart(), - diag::err_unknown_register_name_in_asm, - Clobber.c_str()); - + if (!Context.Target.isValidGCCRegisterName(Clobber.c_str())) // FIXME: We currently leak memory here. - return true; - } + return Diag(Literal->getLocStart(), + diag::err_unknown_register_name_in_asm, Clobber.c_str()); } return new AsmStmt(AsmLoc, @@ -774,8 +775,7 @@ Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, Names, reinterpret_cast(Constraints), reinterpret_cast(Exprs), - cast(E), - NumClobbers, + AsmString, NumClobbers, reinterpret_cast(Clobbers), RParenLoc); } diff --git a/test/Sema/asm.c b/test/Sema/asm.c index 360af015ce..d29335a924 100644 --- a/test/Sema/asm.c +++ b/test/Sema/asm.c @@ -25,3 +25,11 @@ clobbers() asm ("nop" : : : "-1"); // expected-error {{unknown register name '-1' in asm}} asm ("nop" : : : "+1"); // expected-error {{unknown register name '+1' in asm}} } + +// rdar://6094010 +void test3() { + int x; + asm(L"foo" : "=r"(x)); // expected-error {{wide string}} + asm("foo" : L"=r"(x)); // expected-error {{wide string}} +} +