Llvm 断言失败:(使用“U empty()”在值被销毁时保留使用!“ for(Module::global_迭代器I=M.global_begin(),E=M.global_end();I!=E;++I){ 全局变量*GV=I; 如果(!GV->hasInitializer()) 继续; ConstantArray*array=dyn_cast(GV->getInitializer()); if(数组){ for(无符号整数i=0;igetNumPerands();i++){ ConstantExpr*ce=dyn_cast(数组->获取操作数(i)); 如果(ce==0) 继续; ce->getAsInstruction();//如果添加,则获取错误!!! } 继续; } }

Llvm 断言失败:(使用“U empty()”在值被销毁时保留使用!“ for(Module::global_迭代器I=M.global_begin(),E=M.global_end();I!=E;++I){ 全局变量*GV=I; 如果(!GV->hasInitializer()) 继续; ConstantArray*array=dyn_cast(GV->getInitializer()); if(数组){ for(无符号整数i=0;igetNumPerands();i++){ ConstantExpr*ce=dyn_cast(数组->获取操作数(i)); 如果(ce==0) 继续; ce->getAsInstruction();//如果添加,则获取错误!!! } 继续; } },llvm,llvm-ir,Llvm,Llvm Ir,为什么ce->getAsInstruction()会导致在值被销毁时保留使用 getAsInstruction创建新的指令,但不将其插入任何位置。如果转储模块,您会发现没有看到它创建的指令,这也是因为它没有添加到基本块。你需要选择指令的去向,比如 指令*I=ce->getAsInstruction() I->insertBefore(其他说明) 由于您没有这样做,当常量被销毁时,这些指令仍将在内存中,并且它们使用(包含指向)作为ce操作数的常量。因此,“当值[在本例中,原始常量的操作数]被销毁时

为什么ce->getAsInstruction()会导致在值被销毁时保留使用

getAsInstruction
创建新的
指令
,但不将其插入任何位置。如果转储
模块
,您会发现没有看到它创建的
指令
,这也是因为它没有添加到
基本块
。你需要选择指令的去向,比如

指令*I=ce->getAsInstruction()
I->insertBefore(其他说明)

由于您没有这样做,当
常量
被销毁时,这些
指令
仍将在内存中,并且它们使用(包含指向)作为
ce
操作数的
常量
。因此,“当值[在本例中,原始常量的操作数]被销毁时,使用剩余值”


如果我使用opt加载这个过程,当一个值被销毁时,它将导致使用保持不变。但是使用clang-mllvm-xxx来使用pass,它运行得很好

那是因为叮当声作弊;为了提高性能,它跳过了所有llvm内存清理阶段,只退出到操作系统。对未发送指令的检查永远不会运行


如果您感兴趣,您实际上可以阻止clang跳过该阶段。Clang使用不同的命令行(Clang-cc1[其他标志])运行,您需要修改第二个命令。要获取-cc1行,请在叮当声之后立即放置“-####”标志。这一定是clang的第一个论点,####是位置敏感的。这将使clean将其-cc1命令打印到终端,而不是运行它。编辑该行以删除“-disable free”,然后自己运行该行,并且clang应给出与opt相同的错误。

如果我使用opt加载此过程,则在销毁某个值时将导致保留使用。但是使用clang-mllvm-xxx来使用pass,它运行得很好。
for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) {
    GlobalVariable* GV = I;
    if(!GV->hasInitializer())  
        continue;

    ConstantArray* array = dyn_cast<ConstantArray>(GV->getInitializer());      
    if(array){
        for(unsigned int i = 0; i < array->getNumOperands(); i++){
            ConstantExpr* ce = dyn_cast<ConstantExpr>(array->getOperand(i));
            if(ce == 0)
                continue;

            ce->getAsInstruction();  //if add, get error!!!

        }
        continue;
    }
}