aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-05-03 07:04:21 +0000
committerChris Lattner <sabre@nondot.org>2009-05-03 07:04:21 +0000
commitf69fcaeb3843297757251a19f0a6f5bbffed7f32 (patch)
treece12cd54e42c236839d1df901b6cc61779b492c5
parentfa780fc4a4983003633c9b560387266101839923 (diff)
If we have mismatched integer tied operands, but the operand
number is not mentioned in the asm string, let it past sema. Right now these are currently rejected by the llvm code generator but this will be fixed next. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70670 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaStmt.cpp21
-rw-r--r--test/Sema/asm.c2
2 files changed, 21 insertions, 2 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 02f6840415..d1246d28b6 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -1039,7 +1039,7 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
if (!Info.hasTiedOperand()) continue;
unsigned TiedTo = Info.getTiedOperand();
- Expr *OutputExpr = Exprs[TiedTo];
+ Expr *OutputExpr = Exprs[TiedTo];
Expr *InputExpr = Exprs[i+NumOutputs];
QualType InTy = InputExpr->getType();
QualType OutTy = OutputExpr->getType();
@@ -1055,6 +1055,25 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
// int*.
if (Context.getTypeSize(OutTy) == Context.getTypeSize(InTy))
continue;
+
+ // If the input and output operands are not mentioned in the asm string,
+ // then we can promote them and the asm string won't notice. Check this
+ // case now.
+ bool MentionedInput = false;
+ bool MentionedOutput = false;
+ for (unsigned i = 0, e = Pieces.size(); i != e; ++i) {
+ if (!Pieces[i].isOperand()) continue;
+ MentionedInput |= Pieces[i].getOperandNo() == i+NumOutputs;
+ MentionedOutput |= Pieces[i].getOperandNo() == TiedTo;
+ }
+
+ // If neither the input nor the output was mentioned in the asm string,
+ // and if the output was a register, just extend the shorter one to the
+ // size of the larger one.
+ // TODO: if only the larger one is mentioned, we could also support this.
+ if (!MentionedInput && !MentionedOutput &&
+ OutputConstraintInfos[TiedTo].allowsRegister())
+ continue;
}
Diag(InputExpr->getLocStart(),
diff --git a/test/Sema/asm.c b/test/Sema/asm.c
index 602b77388a..cc25fd89b0 100644
--- a/test/Sema/asm.c
+++ b/test/Sema/asm.c
@@ -73,6 +73,6 @@ void asm_string_tests(int i) {
// PR4077
int test7(unsigned long long b) {
int a;
- asm volatile("foo " : "=a" (a) :"0" (b)); // expected-error {{input with type 'unsigned long long' matching output with type 'int'}}
+ asm volatile("foo %0 %1" : "=a" (a) :"0" (b)); // expected-error {{input with type 'unsigned long long' matching output with type 'int'}}
return a;
}