From 883b2edcd7ab348b0675fbfb7d14848d0f99b8f4 Mon Sep 17 00:00:00 2001 From: Shoaib Meenai Date: Wed, 18 Sep 2024 12:20:28 -0700 Subject: [PATCH] [CIR][ABI] Fix use after free from erasing while iterating The loop was erasing the user of a value while iterating on the value's users, which results in a use after free. We're already assuming (and asserting) that there's only one user, so we can just access it directly instead. CIR/Transforms/Target/x86_64/x86_64-call-conv-lowering-pass.cpp was failing with ASAN before this change. We're now ASAN-clean except for https://github.com/llvm/clangir/issues/829 (which is also in progress). --- .../Transforms/TargetLowering/LowerFunction.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerFunction.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerFunction.cpp index 831276ed5f27..9e90c44a7d76 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerFunction.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerFunction.cpp @@ -386,14 +386,11 @@ LowerFunction::buildFunctionProlog(const LowerFunctionInfo &FI, FuncOp Fn, // the argument is used only to be stored in a alloca. Value arg = SrcFn.getArgument(ArgNo); assert(arg.hasOneUse()); - for (auto *firstStore : arg.getUsers()) { - assert(isa(firstStore)); - auto argAlloca = cast(firstStore).getAddr(); - rewriter.replaceAllUsesWith(argAlloca, Alloca); - rewriter.eraseOp(firstStore); - rewriter.eraseOp(argAlloca.getDefiningOp()); - } - + auto *firstStore = *arg.user_begin(); + auto argAlloca = cast(firstStore).getAddr(); + rewriter.replaceAllUsesWith(argAlloca, Alloca); + rewriter.eraseOp(firstStore); + rewriter.eraseOp(argAlloca.getDefiningOp()); break; } default: