aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaStmt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r--lib/Sema/SemaStmt.cpp18
1 files changed, 16 insertions, 2 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 6801dd4c2e..3815deae58 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -1542,8 +1542,9 @@ StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, bool IsSimple,
if (!Info.hasTiedOperand()) continue;
unsigned TiedTo = Info.getTiedOperand();
+ unsigned InputOpNo = i+NumOutputs;
Expr *OutputExpr = Exprs[TiedTo];
- Expr *InputExpr = Exprs[i+NumOutputs];
+ Expr *InputExpr = Exprs[InputOpNo];
QualType InTy = InputExpr->getType();
QualType OutTy = OutputExpr->getType();
if (Context.hasSameType(InTy, OutTy))
@@ -1588,7 +1589,7 @@ StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, bool IsSimple,
// If this is a reference to the input and if the input was the smaller
// one, then we have to reject this asm.
- if (isOperandMentioned(i+NumOutputs, Pieces)) {
+ if (isOperandMentioned(InputOpNo, Pieces)) {
// This is a use in the asm string of the smaller operand. Since we
// codegen this by promoting to a wider value, the asm will get printed
// "wrong".
@@ -1607,6 +1608,19 @@ StmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, bool IsSimple,
OutputConstraintInfos[TiedTo].allowsRegister())
continue;
+ // Either both of the operands were mentioned or the smaller one was
+ // mentioned. One more special case that we'll allow: if the tied input is
+ // integer, unmentioned, and is a constant, then we'll allow truncating it
+ // down to the size of the destination.
+ if (InputDomain == AD_Int && OutputDomain == AD_Int &&
+ !isOperandMentioned(InputOpNo, Pieces) &&
+ InputExpr->isEvaluatable(Context)) {
+ ImpCastExprToType(InputExpr, OutTy, CK_IntegralCast);
+ Exprs[InputOpNo] = InputExpr;
+ NS->setInputExpr(i, InputExpr);
+ continue;
+ }
+
Diag(InputExpr->getLocStart(),
diag::err_asm_tying_incompatible_types)
<< InTy << OutTy << OutputExpr->getSourceRange()