diff options
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 21 |
1 files changed, 20 insertions, 1 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(), |