diff options
author | Bill Wendling <isanbard@gmail.com> | 2012-10-25 00:05:55 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2012-10-25 00:05:55 +0000 |
commit | a0b9ce03880b7dbab766ec80817eb17a20eba508 (patch) | |
tree | 285becf92ea1e0c73c19952bef97f8b194039a5e /lib/Sema/SemaStmtAsm.cpp | |
parent | 53aec2a2770afc242c70fd88975cd0ea389087c0 (diff) |
Add some support for diagnosing possibly mismatched constraint, type size and
modifiers. (From an idea by Eric...)
<rdar://problem/12284092>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166647 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmtAsm.cpp')
-rw-r--r-- | lib/Sema/SemaStmtAsm.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp index 3a5f40c74f..138d671470 100644 --- a/lib/Sema/SemaStmtAsm.cpp +++ b/lib/Sema/SemaStmtAsm.cpp @@ -208,6 +208,54 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, return StmtError(); } + // Validate constraints and modifiers. + for (unsigned i = 0, e = Pieces.size(); i != e; ++i) { + GCCAsmStmt::AsmStringPiece &Piece = Pieces[i]; + if (!Piece.isOperand()) continue; + + // Look for the correct constraint index. + unsigned Idx = 0; + unsigned ConstraintIdx = 0; + for (unsigned i = 0, e = NS->getNumOutputs(); i != e; ++i, ++ConstraintIdx) { + TargetInfo::ConstraintInfo &Info = OutputConstraintInfos[i]; + if (Idx == Piece.getOperandNo()) + break; + ++Idx; + + if (Info.isReadWrite()) { + if (Idx == Piece.getOperandNo()) + break; + ++Idx; + } + } + + for (unsigned i = 0, e = NS->getNumInputs(); i != e; ++i, ++ConstraintIdx) { + TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i]; + if (Idx == Piece.getOperandNo()) + break; + ++Idx; + + if (Info.isReadWrite()) { + if (Idx == Piece.getOperandNo()) + break; + ++Idx; + } + } + + // Now that we have the right indexes go ahead and check. + StringLiteral *Literal = Constraints[ConstraintIdx]; + const Type *Ty = Exprs[ConstraintIdx]->getType().getTypePtr(); + if (Ty->isDependentType() || Ty->isIncompleteType()) + continue; + + unsigned Size = Context.getTypeSize(Ty); + if (!Context.getTargetInfo() + .validateConstraintModifier(Literal->getString(), + Piece.getModifier(), Size)) + Diag(Exprs[ConstraintIdx]->getLocStart(), + diag::warn_mismatched_size_modifier); + } + // Validate tied input operands for type mismatches. for (unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) { TargetInfo::ConstraintInfo &Info = InputConstraintInfos[i]; |