@@ -3233,21 +3233,21 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
3233
3233
void visitCallSite (CallSite CS) {
3234
3234
Instruction &I = *CS.getInstruction ();
3235
3235
assert (!I.getMetadata (" nosanitize" ));
3236
- assert ((CS.isCall () || CS.isInvoke ()) && " Unknown type of CallSite" );
3236
+ assert ((CS.isCall () || CS.isInvoke () || CS.isCallBr ()) &&
3237
+ " Unknown type of CallSite" );
3238
+ if (CS.isCallBr () || (CS.isCall () && cast<CallInst>(&I)->isInlineAsm ())) {
3239
+ // For inline asm (either a call to asm function, or callbr instruction),
3240
+ // do the usual thing: check argument shadow and mark all outputs as
3241
+ // clean. Note that any side effects of the inline asm that are not
3242
+ // immediately visible in its constraints are not handled.
3243
+ if (ClHandleAsmConservative && MS.CompileKernel )
3244
+ visitAsmInstruction (I);
3245
+ else
3246
+ visitInstruction (I);
3247
+ return ;
3248
+ }
3237
3249
if (CS.isCall ()) {
3238
3250
CallInst *Call = cast<CallInst>(&I);
3239
-
3240
- // For inline asm, do the usual thing: check argument shadow and mark all
3241
- // outputs as clean. Note that any side effects of the inline asm that are
3242
- // not immediately visible in its constraints are not handled.
3243
- if (Call->isInlineAsm ()) {
3244
- if (ClHandleAsmConservative && MS.CompileKernel )
3245
- visitAsmInstruction (I);
3246
- else
3247
- visitInstruction (I);
3248
- return ;
3249
- }
3250
-
3251
3251
assert (!isa<IntrinsicInst>(&I) && " intrinsics are handled elsewhere" );
3252
3252
3253
3253
// We are going to insert code that relies on the fact that the callee
@@ -3624,10 +3624,10 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
3624
3624
}
3625
3625
3626
3626
// / Get the number of output arguments returned by pointers.
3627
- int getNumOutputArgs (InlineAsm *IA, CallInst *CI ) {
3627
+ int getNumOutputArgs (InlineAsm *IA, CallBase *CB ) {
3628
3628
int NumRetOutputs = 0 ;
3629
3629
int NumOutputs = 0 ;
3630
- Type *RetTy = dyn_cast<Value>(CI )->getType ();
3630
+ Type *RetTy = dyn_cast<Value>(CB )->getType ();
3631
3631
if (!RetTy->isVoidTy ()) {
3632
3632
// Register outputs are returned via the CallInst return value.
3633
3633
StructType *ST = dyn_cast_or_null<StructType>(RetTy);
@@ -3667,24 +3667,24 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
3667
3667
// corresponding CallInst has nO+nI+1 operands (the last operand is the
3668
3668
// function to be called).
3669
3669
const DataLayout &DL = F.getParent ()->getDataLayout ();
3670
- CallInst *CI = dyn_cast<CallInst >(&I);
3670
+ CallBase *CB = dyn_cast<CallBase >(&I);
3671
3671
IRBuilder<> IRB (&I);
3672
- InlineAsm *IA = cast<InlineAsm>(CI ->getCalledValue ());
3673
- int OutputArgs = getNumOutputArgs (IA, CI );
3672
+ InlineAsm *IA = cast<InlineAsm>(CB ->getCalledValue ());
3673
+ int OutputArgs = getNumOutputArgs (IA, CB );
3674
3674
// The last operand of a CallInst is the function itself.
3675
- int NumOperands = CI ->getNumOperands () - 1 ;
3675
+ int NumOperands = CB ->getNumOperands () - 1 ;
3676
3676
3677
3677
// Check input arguments. Doing so before unpoisoning output arguments, so
3678
3678
// that we won't overwrite uninit values before checking them.
3679
3679
for (int i = OutputArgs; i < NumOperands; i++) {
3680
- Value *Operand = CI ->getOperand (i);
3680
+ Value *Operand = CB ->getOperand (i);
3681
3681
instrumentAsmArgument (Operand, I, IRB, DL, /* isOutput*/ false );
3682
3682
}
3683
3683
// Unpoison output arguments. This must happen before the actual InlineAsm
3684
3684
// call, so that the shadow for memory published in the asm() statement
3685
3685
// remains valid.
3686
3686
for (int i = 0 ; i < OutputArgs; i++) {
3687
- Value *Operand = CI ->getOperand (i);
3687
+ Value *Operand = CB ->getOperand (i);
3688
3688
instrumentAsmArgument (Operand, I, IRB, DL, /* isOutput*/ true );
3689
3689
}
3690
3690
0 commit comments