Use a worklist to avoid a sneaky iterator invalidation.

The iterator could be invalidated when it's recursively deleting a whole bunch
of constant expressions in a constant initializer.

Note: This was only reproducible if `opt' was run on a `.bc' file. If `opt' was
run on a `.ll' file, it wouldn't crash. This is why the test first pushes the
`.ll' file through `llvm-as' before feeding it to `opt'.

PR15440

llvm-svn: 178531
This commit is contained in:
Bill Wendling 2013-04-02 08:16:45 +00:00
parent aeabcf24df
commit 88d06c3b2d
2 changed files with 22 additions and 3 deletions

View File

@ -470,8 +470,9 @@ static bool CleanupPointerRootUsers(GlobalVariable *GV,
static bool CleanupConstantGlobalUsers(Value *V, Constant *Init,
DataLayout *TD, TargetLibraryInfo *TLI) {
bool Changed = false;
for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;) {
User *U = *UI++;
SmallVector<User*, 8> WorkList(V->use_begin(), V->use_end());
while (!WorkList.empty()) {
User *U = WorkList.pop_back_val();
if (LoadInst *LI = dyn_cast<LoadInst>(U)) {
if (Init) {
@ -534,7 +535,6 @@ static bool CleanupConstantGlobalUsers(Value *V, Constant *Init,
// us, and if they are all dead, nuke them without remorse.
if (SafeToDestroyConstant(C)) {
C->destroyConstant();
// This could have invalidated UI, start over from scratch.
CleanupConstantGlobalUsers(V, Init, TD, TLI);
return true;
}

File diff suppressed because one or more lines are too long