diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/IR/InlineAsm.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/IR/InlineAsm.cpp | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/contrib/llvm-project/llvm/lib/IR/InlineAsm.cpp b/contrib/llvm-project/llvm/lib/IR/InlineAsm.cpp index 203ad6dae1ff..c75b1aa7c1d6 100644 --- a/contrib/llvm-project/llvm/lib/IR/InlineAsm.cpp +++ b/contrib/llvm-project/llvm/lib/IR/InlineAsm.cpp @@ -19,6 +19,7 @@ #include "llvm/IR/Value.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Errc.h" #include <algorithm> #include <cassert> #include <cctype> @@ -33,9 +34,10 @@ InlineAsm::InlineAsm(FunctionType *FTy, const std::string &asmString, AsmString(asmString), Constraints(constraints), FTy(FTy), HasSideEffects(hasSideEffects), IsAlignStack(isAlignStack), Dialect(asmDialect), CanThrow(canThrow) { +#ifndef NDEBUG // Do various checks on the constraint string and type. - assert(Verify(getFunctionType(), constraints) && - "Function type not legal for constraints!"); + cantFail(verify(getFunctionType(), constraints)); +#endif } InlineAsm *InlineAsm::get(FunctionType *FTy, StringRef AsmString, @@ -248,15 +250,19 @@ InlineAsm::ParseConstraints(StringRef Constraints) { return Result; } -/// Verify - Verify that the specified constraint string is reasonable for the -/// specified function type, and otherwise validate the constraint string. -bool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) { - if (Ty->isVarArg()) return false; +static Error makeStringError(const char *Msg) { + return createStringError(errc::invalid_argument, Msg); +} + +Error InlineAsm::verify(FunctionType *Ty, StringRef ConstStr) { + if (Ty->isVarArg()) + return makeStringError("inline asm cannot be variadic"); ConstraintInfoVector Constraints = ParseConstraints(ConstStr); // Error parsing constraints. - if (Constraints.empty() && !ConstStr.empty()) return false; + if (Constraints.empty() && !ConstStr.empty()) + return makeStringError("failed to parse constraints"); unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0; unsigned NumIndirect = 0; @@ -265,7 +271,9 @@ bool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) { switch (Constraint.Type) { case InlineAsm::isOutput: if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0) - return false; // outputs before inputs and clobbers. + return makeStringError("output constraint occurs after input " + "or clobber constraint"); + if (!Constraint.isIndirect) { ++NumOutputs; break; @@ -273,7 +281,9 @@ bool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) { ++NumIndirect; LLVM_FALLTHROUGH; // We fall through for Indirect Outputs. case InlineAsm::isInput: - if (NumClobbers) return false; // inputs before clobbers. + if (NumClobbers) + return makeStringError("input constraint occurs after clobber " + "constraint"); ++NumInputs; break; case InlineAsm::isClobber: @@ -284,18 +294,23 @@ bool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) { switch (NumOutputs) { case 0: - if (!Ty->getReturnType()->isVoidTy()) return false; + if (!Ty->getReturnType()->isVoidTy()) + return makeStringError("inline asm without outputs must return void"); break; case 1: - if (Ty->getReturnType()->isStructTy()) return false; + if (Ty->getReturnType()->isStructTy()) + return makeStringError("inline asm with one output cannot return struct"); break; default: StructType *STy = dyn_cast<StructType>(Ty->getReturnType()); if (!STy || STy->getNumElements() != NumOutputs) - return false; + return makeStringError("number of output constraints does not match " + "number of return struct elements"); break; } - if (Ty->getNumParams() != NumInputs) return false; - return true; + if (Ty->getNumParams() != NumInputs) + return makeStringError("number of input constraints does not match number " + "of parameters"); + return Error::success(); } |