19
19
#include " llvm/IR/Value.h"
20
20
#include " llvm/Support/Casting.h"
21
21
#include " llvm/Support/Compiler.h"
22
+ #include " llvm/Support/Errc.h"
22
23
#include < algorithm>
23
24
#include < cassert>
24
25
#include < cctype>
@@ -33,9 +34,10 @@ InlineAsm::InlineAsm(FunctionType *FTy, const std::string &asmString,
33
34
AsmString(asmString), Constraints(constraints), FTy(FTy),
34
35
HasSideEffects(hasSideEffects), IsAlignStack(isAlignStack),
35
36
Dialect(asmDialect), CanThrow(canThrow) {
37
+ #ifndef NDEBUG
36
38
// Do various checks on the constraint string and type.
37
- assert ( Verify (getFunctionType (), constraints) &&
38
- " Function type not legal for constraints! " );
39
+ cantFail ( verify (getFunctionType (), constraints));
40
+ # endif
39
41
}
40
42
41
43
InlineAsm *InlineAsm::get (FunctionType *FTy, StringRef AsmString,
@@ -248,15 +250,19 @@ InlineAsm::ParseConstraints(StringRef Constraints) {
248
250
return Result;
249
251
}
250
252
251
- // / Verify - Verify that the specified constraint string is reasonable for the
252
- // / specified function type, and otherwise validate the constraint string.
253
- bool InlineAsm::Verify (FunctionType *Ty, StringRef ConstStr) {
254
- if (Ty->isVarArg ()) return false ;
253
+ static Error makeStringError (const char *Msg) {
254
+ return createStringError (errc::invalid_argument, Msg);
255
+ }
256
+
257
+ Error InlineAsm::verify (FunctionType *Ty, StringRef ConstStr) {
258
+ if (Ty->isVarArg ())
259
+ return makeStringError (" inline asm cannot be variadic" );
255
260
256
261
ConstraintInfoVector Constraints = ParseConstraints (ConstStr);
257
262
258
263
// Error parsing constraints.
259
- if (Constraints.empty () && !ConstStr.empty ()) return false ;
264
+ if (Constraints.empty () && !ConstStr.empty ())
265
+ return makeStringError (" failed to parse constraints" );
260
266
261
267
unsigned NumOutputs = 0 , NumInputs = 0 , NumClobbers = 0 ;
262
268
unsigned NumIndirect = 0 ;
@@ -265,15 +271,19 @@ bool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) {
265
271
switch (Constraint.Type ) {
266
272
case InlineAsm::isOutput:
267
273
if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0 )
268
- return false ; // outputs before inputs and clobbers.
274
+ return makeStringError (" output constraint occurs after input "
275
+ " or clobber constraint" );
276
+
269
277
if (!Constraint.isIndirect ) {
270
278
++NumOutputs;
271
279
break ;
272
280
}
273
281
++NumIndirect;
274
282
LLVM_FALLTHROUGH; // We fall through for Indirect Outputs.
275
283
case InlineAsm::isInput:
276
- if (NumClobbers) return false ; // inputs before clobbers.
284
+ if (NumClobbers)
285
+ return makeStringError (" input constraint occurs after clobber "
286
+ " constraint" );
277
287
++NumInputs;
278
288
break ;
279
289
case InlineAsm::isClobber:
@@ -284,18 +294,23 @@ bool InlineAsm::Verify(FunctionType *Ty, StringRef ConstStr) {
284
294
285
295
switch (NumOutputs) {
286
296
case 0 :
287
- if (!Ty->getReturnType ()->isVoidTy ()) return false ;
297
+ if (!Ty->getReturnType ()->isVoidTy ())
298
+ return makeStringError (" inline asm without outputs must return void" );
288
299
break ;
289
300
case 1 :
290
- if (Ty->getReturnType ()->isStructTy ()) return false ;
301
+ if (Ty->getReturnType ()->isStructTy ())
302
+ return makeStringError (" inline asm with one output cannot return struct" );
291
303
break ;
292
304
default :
293
305
StructType *STy = dyn_cast<StructType>(Ty->getReturnType ());
294
306
if (!STy || STy->getNumElements () != NumOutputs)
295
- return false ;
307
+ return makeStringError (" number of output constraints does not match "
308
+ " number of return struct elements" );
296
309
break ;
297
310
}
298
311
299
- if (Ty->getNumParams () != NumInputs) return false ;
300
- return true ;
312
+ if (Ty->getNumParams () != NumInputs)
313
+ return makeStringError (" number of input constraints does not match number "
314
+ " of parameters" );
315
+ return Error::success ();
301
316
}
0 commit comments