diff options
author | Tim Northover <tnorthover@apple.com> | 2013-06-07 00:04:50 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2013-06-07 00:04:50 +0000 |
commit | 0ae939182427c1f8b6db35bea33b07379ffdfacc (patch) | |
tree | 4c2e6b3310d6d5a2335c8f422fbe7ed58a30c90a /clang/lib/CodeGen | |
parent | 0b3175a6fccd4c8cb43627b2e834026d986828fb (diff) | |
download | bcm5719-llvm-0ae939182427c1f8b6db35bea33b07379ffdfacc.tar.gz bcm5719-llvm-0ae939182427c1f8b6db35bea33b07379ffdfacc.zip |
Diagnose malformed x86 inline asm using 'y' constraint.
X86's 'y' inline assembly constraint represents an MMX register, this change
prevents Clang from hitting an assertion when passed an incompatible type to
deal with.
llvm-svn: 183467
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGStmt.cpp | 15 | ||||
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 10 | ||||
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.h | 7 |
3 files changed, 27 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 353d6c3d396..3e9b8d47ea0 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -16,6 +16,7 @@ #include "CodeGenModule.h" #include "TargetInfo.h" #include "clang/AST/StmtVisitor.h" +#include "clang/Sema/SemaDiagnostic.h" #include "clang/Basic/PrettyStackTrace.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/StringExtras.h" @@ -1559,10 +1560,15 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { ResultRegTypes.back() = ConvertType(InputTy); } } - if (llvm::Type* AdjTy = + if (llvm::Type* AdjTy = getTargetHooks().adjustInlineAsmType(*this, OutputConstraint, ResultRegTypes.back())) ResultRegTypes.back() = AdjTy; + else { + CGM.getDiags().Report(S.getAsmLoc(), + diag::err_asm_invalid_type_in_input) + << OutExpr->getType() << OutputConstraint; + } } else { ArgTypes.push_back(Dest.getAddress()->getType()); Args.push_back(Dest.getAddress()); @@ -1578,8 +1584,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { InOutConstraints); if (llvm::Type* AdjTy = - getTargetHooks().adjustInlineAsmType(*this, OutputConstraint, - Arg->getType())) + getTargetHooks().adjustInlineAsmType(*this, OutputConstraint, + Arg->getType())) Arg = Builder.CreateBitCast(Arg, AdjTy); if (Info.allowsRegister()) @@ -1644,6 +1650,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { getTargetHooks().adjustInlineAsmType(*this, InputConstraint, Arg->getType())) Arg = Builder.CreateBitCast(Arg, AdjTy); + else + CGM.getDiags().Report(S.getAsmLoc(), diag::err_asm_invalid_type_in_input) + << InputExpr->getType() << InputConstraint; ArgTypes.push_back(Arg->getType()); Args.push_back(Arg); diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index c4ee7246a5b..6881ea7fec0 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -503,8 +503,16 @@ bool IsX86_MMXType(llvm::Type *IRType) { static llvm::Type* X86AdjustInlineAsmType(CodeGen::CodeGenFunction &CGF, StringRef Constraint, llvm::Type* Ty) { - if ((Constraint == "y" || Constraint == "&y") && Ty->isVectorTy()) + if ((Constraint == "y" || Constraint == "&y") && Ty->isVectorTy()) { + if (cast<llvm::VectorType>(Ty)->getBitWidth() != 64) { + // Invalid MMX constraint + return 0; + } + return llvm::Type::getX86_MMXTy(CGF.getLLVMContext()); + } + + // No operation needed return Ty; } diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index b0ddebc1a03..ab7b061aba8 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -111,8 +111,13 @@ namespace clang { return Address; } + /// Corrects the low-level LLVM type for a given constraint and "usual" + /// type. + /// + /// \returns A pointer to a new LLVM type, possibly the same as the original + /// on success; 0 on failure. virtual llvm::Type* adjustInlineAsmType(CodeGen::CodeGenFunction &CGF, - StringRef Constraint, + StringRef Constraint, llvm::Type* Ty) const { return Ty; } |