[PATCH] D62624: [InstCombine] Avoid use after free in DenseMap, when built with GCC

Martin Storsjö via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed May 29 13:18:52 PDT 2019

mstorsjo created this revision.
mstorsjo added reviewers: sbaranga, rnk, chandlerc.
Herald added a project: LLVM.

In a statement like Map[A] = Map[B], first the right hand side is evaluated as a reference, then left hand side is evaluated. If the left hand side operator[] invocation grows the map, the previous reference may be invalidated.

GCC seems to dereference the right hand side reference only after evaluating the left hand side, while Clang dereferences it before. (If the value type is larger type, Clang also dereferences it after the left hand side operator[] call.)

With GCC, a cast to Value* isn't enough to make it dereference the right hand side reference before invoking (while that is enough to make Clang/LLVM do the right thing for larger types), but storing it in an intermediate variable in a separate statement works.




Index: lib/Transforms/InstCombine/InstCombineCompares.cpp
--- lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -703,7 +703,10 @@
     if (auto *CI = dyn_cast<CastInst>(Val)) {
-      NewInsts[CI] = NewInsts[CI->getOperand(0)];
+      // Don't get rid of the intermediate variable here; the store can grow
+      // the map which will invalidate the reference to the input value.
+      Value *V = NewInsts[CI->getOperand(0)];
+      NewInsts[CI] = V;
     if (auto *GEP = dyn_cast<GEPOperator>(Val)) {

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D62624.202039.patch
Type: text/x-patch
Size: 673 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190529/fca143ab/attachment.bin>

More information about the llvm-commits mailing list