diff options
author | Chris Lattner <sabre@nondot.org> | 2009-05-03 05:55:43 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-05-03 05:55:43 +0000 |
commit | 806503f8c839d7f5ebf3fbf7ee848c179be76dd2 (patch) | |
tree | 1550c36947976ef4f1f3d1375b1af51e36298c19 /lib/Sema/SemaStmt.cpp | |
parent | b77449cead63264650958c92cb30609c942cc5e9 (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.cpp | 52 |
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); } |