Check asm input and output expressions.

llvm-svn: 44289
This commit is contained in:
Anders Carlsson 2007-11-23 19:43:50 +00:00
parent 8a3e9d2bee
commit 80a5ea3552
3 changed files with 51 additions and 1 deletions

View File

@ -655,8 +655,40 @@ Sema::StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
ExprTy **Clobbers,
SourceLocation RParenLoc) {
Expr *E = (Expr *)AsmString;
// Check that the output exprs are valid lvalues.
for (unsigned i = 0; i < NumOutputs; i++) {
Expr *OutputExpr = (Expr *)Exprs[i];
Expr::isLvalueResult Result = OutputExpr->isLvalue();
// FIXME: Make sure that the expressions are valid.
if (Result != Expr::LV_Valid) {
ParenExpr *PE = cast<ParenExpr>(OutputExpr);
Diag(PE->getSubExpr()->getLocStart(),
diag::err_invalid_lvalue_in_asm_output,
PE->getSubExpr()->getSourceRange());
// FIXME: We currently leak memory here.
return true;
}
}
// Check that the input exprs aren't of type void.
for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) {
Expr *InputExpr = (Expr *)Exprs[i];
if (InputExpr->getType()->isVoidType()) {
ParenExpr *PE = cast<ParenExpr>(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 new AsmStmt(AsmLoc,
NumOutputs,

View File

@ -789,6 +789,10 @@ DIAG(warn_unused_expr, WARNING,
"expression result unused")
DIAG(err_pascal_string_too_long, ERROR,
"Pascal string is too long")
DIAG(err_invalid_lvalue_in_asm_output, ERROR,
"invalid lvalue in asm output")
DIAG(err_invalid_type_in_asm_input, ERROR,
"invalid type '%0' in asm input")
// CHECK: printf format string errors
DIAG(warn_printf_not_string_constant, WARNING,

14
clang/test/Sema/asm.c Normal file
View File

@ -0,0 +1,14 @@
// RUN: clang %s -verify -fsyntax-only
void
f()
{
int i;
asm ("foo\n" : : "a" (i + 2));
asm ("foo\n" : : "a" (f())); // expected-error {{invalid type 'void' in asm input}}
asm ("foo\n" : "=a" (f())); // expected-error {{invalid lvalue in asm output}}
asm ("foo\n" : "=a" (i + 2)); // expected-error {{invalid lvalue in asm output}}
}