aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaStmt.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-05-03 05:55:43 +0000
committerChris Lattner <sabre@nondot.org>2009-05-03 05:55:43 +0000
commit806503f8c839d7f5ebf3fbf7ee848c179be76dd2 (patch)
tree1550c36947976ef4f1f3d1375b1af51e36298c19 /lib/Sema/SemaStmt.cpp
parentb77449cead63264650958c92cb30609c942cc5e9 (diff)
refactor matched operand type checking to happen after the AsmStmt is created,
no functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70662 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r--lib/Sema/SemaStmt.cpp52
1 files changed, 35 insertions, 17 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 243b5695c3..88c7690f86 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -951,6 +951,8 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
OutputConstraintInfos.push_back(Info);
}
+ llvm::SmallVector<TargetInfo::ConstraintInfo, 4> InputConstraintInfos;
+
for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) {
StringLiteral *Literal = Constraints[i];
if (Literal->isWide())
@@ -989,23 +991,7 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
DefaultFunctionArrayConversion(Exprs[i]);
- // If this is a tied constraint, verify that the output and input have
- // either exactly the same type, or that they are int/ptr operands with the
- // same size (int/long, int*/long, are ok etc).
- if (Info.hasTiedOperand()) {
- unsigned TiedTo = Info.getTiedOperand();
- QualType T1 = Exprs[TiedTo]->getType(), T2 = Exprs[i]->getType();
- if (!Context.hasSameType(T1, T2)) {
- // Int/ptr operands are ok if they are the same size.
- if (!(T1->isIntegerType() || T1->isPointerType()) ||
- !(T2->isIntegerType() || T2->isPointerType()) ||
- Context.getTypeSize(T1) != Context.getTypeSize(T2))
- return StmtError(Diag(InputExpr->getSubExpr()->getLocStart(),
- diag::err_asm_tying_incompatible_types)
- << T2 << T1 << Exprs[TiedTo]->getSourceRange()
- << Exprs[i]->getSourceRange());
- }
- }
+ InputConstraintInfos.push_back(Info);
}
// Check that the clobbers are valid.
@@ -1043,6 +1029,38 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc,
return StmtError();
}
+ // Validate tied input operands for type mismatches.
+ for (unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) {
+ TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i];
+
+ // If this is a tied constraint, verify that the output and input have
+ // either exactly the same type, or that they are int/ptr operands with the
+ // same size (int/long, int*/long, are ok etc).
+ if (!Info.hasTiedOperand()) continue;
+
+ unsigned TiedTo = Info.getTiedOperand();
+ Expr *OutputExpr = Exprs[TiedTo];
+ ParenExpr *InputExpr = cast<ParenExpr>(Exprs[i+NumOutputs]);
+ QualType T1 = OutputExpr->getType();
+ QualType T2 = InputExpr->getType();
+ if (Context.hasSameType(T1, T2))
+ continue; // All types can be tied to themselves.
+
+
+ // Int/ptr operands are ok if they are the same size.
+ if ((T1->isIntegerType() || T1->isPointerType()) &&
+ (T2->isIntegerType() || T2->isPointerType())) {
+ if (Context.getTypeSize(T1) == Context.getTypeSize(T2))
+ continue;
+ }
+
+ Diag(InputExpr->getSubExpr()->getLocStart(),
+ diag::err_asm_tying_incompatible_types)
+ << T2 << T1 << OutputExpr->getSourceRange()
+ << InputExpr->getSourceRange();
+ DeleteStmt(NS);
+ return StmtError();
+ }
return Owned(NS);
}