From c128f3b34ceac52bd3b0e2473dbb2b27a0091fbf Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Wed, 30 Jul 2014 01:20:26 +0000 Subject: [PATCH] UseListOrder: Fix undefined behaviour This commit fixes undefined behaviour that caused the revert in r214249. The problem was two unsequenced operations on a `DenseMap<>`, giving different behaviour in GCC and Clang. This: DenseMap DM; for (auto &X : ...) DM[&X] = DM.size() + 1; should have been: DenseMap DM; for (auto &X : ...) { unsigned Size = DM.size(); DM[&X] = Size + 1; } Until r214242, this difference between compilers didn't matter. In r214242, `OrderMap::LastGlobalValueID` was introduced and compared against IDs, which in GCC were off-by-one my expectations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214270 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bitcode/Writer/ValueEnumerator.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index 5624e02a5c8..144e8fb08cd 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -34,6 +34,11 @@ struct OrderMap { std::pair lookup(const Value *V) const { return IDs.lookup(V); } + void index(const Value *V) { + // Explicitly sequence get-size and insert-value operations to avoid UB. + unsigned ID = IDs.size() + 1; + IDs[V].first = ID; + } }; } @@ -48,8 +53,8 @@ static void orderValue(const Value *V, OrderMap &OM) { orderValue(Op, OM); // Note: we cannot cache this lookup above, since inserting into the map - // changes the map's size, and thus affects the ID. - OM[V].first = OM.size() + 1; + // changes the map's size, and thus affects the other IDs. + OM.index(V); } static OrderMap orderModule(const Module *M) {