Importing rustc-1.65.0
Bug: 250026064
Test: ./build.py --lto=thin
Change-Id: If144bbb779543363527e335b12d3ae6fbb4be8f0
diff --git a/src/llvm-project/llvm/lib/IR/InlineAsm.cpp b/src/llvm-project/llvm/lib/IR/InlineAsm.cpp
index 203ad6d..088fcfd 100644
--- a/src/llvm-project/llvm/lib/IR/InlineAsm.cpp
+++ b/src/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 @@
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,
@@ -91,6 +93,9 @@
} else if (*I == '=') {
++I;
Type = isOutput;
+ } else if (*I == '!') {
+ ++I;
+ Type = isLabel;
}
if (*I == '*') {
@@ -248,24 +253,30 @@
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;
+ unsigned NumIndirect = 0, NumLabels = 0;
for (const ConstraintInfo &Constraint : Constraints) {
switch (Constraint.Type) {
case InlineAsm::isOutput:
- if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0)
- return false; // outputs before inputs and clobbers.
+ if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0 || NumLabels != 0)
+ return makeStringError("output constraint occurs after input, "
+ "clobber or label constraint");
+
if (!Constraint.isIndirect) {
++NumOutputs;
break;
@@ -273,29 +284,45 @@
++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:
++NumClobbers;
break;
+ case InlineAsm::isLabel:
+ if (NumClobbers)
+ return makeStringError("label constraint occurs after clobber "
+ "constraint");
+
+ ++NumLabels;
+ break;
}
}
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");
+
+ // We don't have access to labels here, NumLabels will be checked separately.
+ return Error::success();
}