@@ -356,6 +356,62 @@ static uint64_t getUniqueCaseValue(SmallSet<uint64_t, 4> &CasesTaken,
356
356
return tmp;
357
357
}
358
358
359
+ // / Determines whether a function is unsupported by the current mutator's
360
+ // / implementation. The function returns true if any of the following criteria
361
+ // / are met:
362
+ // / * The function accepts metadata or token types as arguments.
363
+ // / * The function has ABI attributes that could cause UB.
364
+ // / * The function uses a non-callable CC that may result in UB.
365
+ static bool isUnsupportedFunction (Function *F) {
366
+ // Some functions accept metadata type or token type as arguments.
367
+ // We don't call those functions for now.
368
+ // For example, `@llvm.dbg.declare(metadata, metadata, metadata)`
369
+ // https://llvm.org/docs/SourceLevelDebugging.html#llvm-dbg-declare
370
+ auto IsUnsupportedTy = [](Type *T) {
371
+ return T->isMetadataTy () || T->isTokenTy ();
372
+ };
373
+
374
+ if (IsUnsupportedTy (F->getReturnType ()) ||
375
+ any_of (F->getFunctionType ()->params (), IsUnsupportedTy)) {
376
+ return true ;
377
+ }
378
+
379
+ // ABI attributes must be specified both at the function
380
+ // declaration/definition and call-site, otherwise the
381
+ // behavior may be undefined.
382
+ // We don't call those functions for now to prevent UB from happening.
383
+ auto IsABIAttribute = [](AttributeSet A) {
384
+ static const Attribute::AttrKind ABIAttrs[] = {
385
+ Attribute::StructRet, Attribute::ByVal,
386
+ Attribute::InAlloca, Attribute::InReg,
387
+ Attribute::StackAlignment, Attribute::SwiftSelf,
388
+ Attribute::SwiftAsync, Attribute::SwiftError,
389
+ Attribute::Preallocated, Attribute::ByRef,
390
+ Attribute::ZExt, Attribute::SExt};
391
+
392
+ return std::any_of (
393
+ std::begin (ABIAttrs), std::end (ABIAttrs),
394
+ [&](Attribute::AttrKind kind) { return A.hasAttribute (kind); });
395
+ };
396
+
397
+ auto FuncAttrs = F->getAttributes ();
398
+ if (IsABIAttribute (FuncAttrs.getRetAttrs ())) {
399
+ return true ;
400
+ }
401
+ for (size_t i = 0 ; i < F->arg_size (); i++) {
402
+ if (IsABIAttribute (FuncAttrs.getParamAttrs (i))) {
403
+ return true ;
404
+ }
405
+ }
406
+
407
+ // If it is not satisfied, the IR will be invalid.
408
+ if (!isCallableCC (F->getCallingConv ())) {
409
+ return true ;
410
+ }
411
+
412
+ return false ;
413
+ }
414
+
359
415
void InsertFunctionStrategy::mutate (BasicBlock &BB, RandomIRBuilder &IB) {
360
416
Module *M = BB.getParent ()->getParent ();
361
417
// If nullptr is selected, we will create a new function declaration.
@@ -366,16 +422,8 @@ void InsertFunctionStrategy::mutate(BasicBlock &BB, RandomIRBuilder &IB) {
366
422
367
423
auto RS = makeSampler (IB.Rand , Functions);
368
424
Function *F = RS.getSelection ();
369
- // Some functions accept metadata type or token type as arguments.
370
- // We don't call those functions for now.
371
- // For example, `@llvm.dbg.declare(metadata, metadata, metadata)`
372
- // https://llvm.org/docs/SourceLevelDebugging.html#llvm-dbg-declare
373
- auto IsUnsupportedTy = [](Type *T) {
374
- return T->isMetadataTy () || T->isTokenTy ();
375
- };
376
- if (!F || IsUnsupportedTy (F->getReturnType ()) ||
377
- any_of (F->getFunctionType ()->params (), IsUnsupportedTy) ||
378
- !isCallableCC (F->getCallingConv ())) {
425
+
426
+ if (!F || isUnsupportedFunction (F)) {
379
427
F = IB.createFunctionDeclaration (*M);
380
428
}
381
429
0 commit comments