<div dir="ltr">I don't think the compile line of the test matters. If it does, the CL is fundamentally broken. I think it's the compile line of LLDB vs LLVM. I also don't see *why* that should matter. I get that it does, but I'm not sure it's reasonable to mandate that you only link TU's against LLVM that have compiled with the same value of NDEBUG.<br></div><br><div class="gmail_quote">On Wed, Mar 4, 2015 at 11:37 AM Rick Foos <<a href="mailto:rfoos@codeaurora.org">rfoos@codeaurora.org</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000">
I see a lot of _DEBUG, DEBUG, and NDEBUG used, and passed in on the
compile line of some tests.<br>
<br>
Nothing ties them to an LLVM Debug/Release build.<br>
<br>
I can't think of the right answer to force them to be consistent:
overriding the compiler line would involve an everywhere include
file; or overriding the LLVM build type, not what the user
intended...Maybe an Ugly Warning Message?<br>
<br>
--- From Ted<br>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">When
LLDB quits, it prints this out:<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">MI:
Program exited OK<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">Which
seems to be from here:<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">#if
_DEBUG<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">
CMICmnStreamStdout::Instance().Write( MIRSRC( IDE_MI_APP_EXIT_OK
) ); // Both stdout and Log<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">#else<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">
CMICmnLog::WriteLog( MIRSRC( IDE_MI_APP_EXIT_OK ) ); // Just to
the Log<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d">#endif
// _DEBUG<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri",sans-serif;color:#1f497d"><u></u> <u></u>It
looks like _DEBUG is defined. I’m not sure where or why.<u></u><u></u></span></p></div><div bgcolor="#FFFFFF" text="#000000">
<br>
<br>
<div>On 03/04/2015 11:43 AM, Zachary Turner
wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">How necessary to this change is the ABI
incompatibility between the cases where NDEBUG is and isn't
defined? Is it possible to make them ABI compatible while still
keeping the meat of the change intact?<br>
<div><br>
</div>
<div>It doesn't really seem like a "nice" thing to do to require
that people who use LLVM as a library use the same compilation
flags as LLVM. </div>
</div>
<br>
<div class="gmail_quote">On Wed, Mar 4, 2015 at 9:30 AM Duncan P.
N. Exon Smith <<a href="mailto:dexonsmith@apple.com" target="_blank">dexonsmith@apple.com</a>>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">><br>
> On 2015-Mar-04, at 02:23, Sanjoy Das <<a href="mailto:sanjoy@playingwithpointers.com" target="_blank">sanjoy@playingwithpointers.com</a>>
wrote:<br>
><br>
> As an example, ClangASTType.h will include clang headers
without<br>
> #defining NDEBUG while ClangExternalASTSourceCommon.h
will include<br>
> clang headers *after* #defining NDEBUG.<br>
><br>
<br>
I've looked up rdar://8691220 for you, which is referenced in
the<br>
comments around LLDB_DEFINED_NDEBUG_FOR_CLANG.<br>
<br>
This was apparently fixed by a series of CFE commits ending
with<br>
r120708 back in 2011, but the workaround was never removed.<br>
<br>
Nevertheless you probably need to propagate the workaround
further,<br>
or come up with a different approach -- what I've learned is
that<br>
lldb likes to build in debug mode and link against a clang
built in<br>
release mode. (Another option is to convince the lldb folks
not to<br>
mix configurations.)<br>
<br>
> Also, where is LLVM_NDEBUG_OFF set? When building with a<br>
> Release+Asserts llvm it should have been #defined, but it
does not<br>
> seem to be. I could not find anything with a
straightforward grep.<br>
<br>
It looks like this logic was added in r143036, but I can't
find<br>
anything that actually sets it (even in the build systems).
Seems<br>
like dead code to me too.<br>
<br>
> On Wed, Mar 4, 2015 at 1:17 AM, Sanjoy Das<br>
> <<a href="mailto:sanjoy@playingwithpointers.com" target="_blank">sanjoy@playingwithpointers.com</a>>
wrote:<br>
>> The problem is very likely due to inconsistencies in
how lldb treats<br>
>> the NDEBUG macro. For instance<br>
>><br>
>> (lldb) p sizeof(llvm::DenseMapBase<llvm::DenseMap<clang::ExternalASTSource*,<br>
>> lldb_private::ClangExternalASTSourceCommon*,<br>
>> llvm::DenseMapInfo<clang::ExternalASTSource*>,<br>
>> llvm::detail::DenseMapPair<clang::ExternalASTSource*,<br>
>> lldb_private::ClangExternalASTSourceCommon*> >,<br>
>> clang::ExternalASTSource*,<br>
>> lldb_private::ClangExternalASTSourceCommon*,<br>
>> llvm::DenseMapInfo<clang::ExternalASTSource*>,<br>
>> llvm::detail::DenseMapPair<clang::ExternalASTSource*,<br>
>> lldb_private::ClangExternalASTSourceCommon*> >)<br>
>> (unsigned long) $8 = 1<br>
>> (lldb) p sizeof(DebugEpochBase)<br>
>> (unsigned long) $9 = 8<br>
>><br>
>> when DenseMapBase<...> inherits
DebugEpochBase. This is the reason<br>
>> why incrementEpoch() ends up incrementing the
"Buckets" pointer<br>
>> instead of the actual Epoch word.<br>
>><br>
>><br>
>> On Wed, Mar 4, 2015 at 12:21 AM, Sanjoy Das<br>
>> <<a href="mailto:sanjoy@playingwithpointers.com" target="_blank">sanjoy@playingwithpointers.com</a>>
wrote:<br>
>>> I'm at a loss as to how this could have
happened. Looks like we<br>
>>> somehow end up with DenseMap::Buckets as 0x1
which is clearly not a<br>
>>> valid pointer.<br>
>>><br>
>>> I have a few theories that I've already discussed
with Zachary on IRC:<br>
>>><br>
>>> * there is some racy accesses going on to the
DenseMap and that is<br>
>>> producing incorrect behavior<br>
>>><br>
>>> * some dlopen oddity that leads to an improperly
constructed DenseMap<br>
>>><br>
>>> * for some reason the incrementEpoch(); in
InsertIntoBucketImpl bumps<br>
>>> the "Buckets" pointer by 1 instead of Epoch. I
don't see how this<br>
>>> could happen except maybe due to a bug in the C++
compiler.<br>
>>><br>
>>> Anyway, I'll try to reproduce this tomorrow
(explicit directions on<br>
>>> how to do so will be very helpful). Please let
me know if you have<br>
>>> any other ideas.<br>
>>><br>
>>> Thanks,<br>
>>> -- Sanjoy<br>
>>><br>
>>> On Tue, Mar 3, 2015 at 10:05 PM, Chaoren Lin <<a href="mailto:chaorenl@google.com" target="_blank">chaorenl@google.com</a>> wrote:<br>
>>>> Author: chaoren<br>
>>>> Date: Wed Mar 4 00:05:37 2015<br>
>>>> New Revision: 231214<br>
>>>><br>
>>>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=231214&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=231214&view=rev</a><br>
>>>> Log:<br>
>>>> Revert "[ADT] fail-fast iterators for
DenseMap"<br>
>>>><br>
>>>> This reverts commit
4b7263d855006988854036b4a4891fcf19aebe65.<br>
>>>><br>
>>>> r231125 <a href="http://reviews.llvm.org/D7931" target="_blank">http://reviews.llvm.org/D7931</a><br>
>>>><br>
>>>> This was causing many LLDB tests to fail on
OS X, Linux, and FreeBSD.<br>
>>>><br>
>>>> <a href="https://bpaste.net/show/6a23e1f53623" target="_blank">https://bpaste.net/show/6a23e1f53623</a><br>
>>>><br>
>>>> Removed:<br>
>>>> llvm/trunk/include/llvm/ADT/EpochTracker.h<br>
>>>> Modified:<br>
>>>> llvm/trunk/include/llvm/ADT/DenseMap.h<br>
>>>><br>
>>>> Modified: llvm/trunk/include/llvm/ADT/DenseMap.h<br>
>>>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseMap.h?rev=231214&r1=231213&r2=231214&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseMap.h?rev=231214&r1=231213&r2=231214&view=diff</a><br>
>>>> ==============================================================================<br>
>>>> --- llvm/trunk/include/llvm/ADT/DenseMap.h
(original)<br>
>>>> +++ llvm/trunk/include/llvm/ADT/DenseMap.h
Wed Mar 4 00:05:37 2015<br>
>>>> @@ -15,7 +15,6 @@<br>
>>>> #define LLVM_ADT_DENSEMAP_H<br>
>>>><br>
>>>> #include "llvm/ADT/DenseMapInfo.h"<br>
>>>> -#include "llvm/ADT/EpochTracker.h"<br>
>>>> #include "llvm/Support/AlignOf.h"<br>
>>>> #include "llvm/Support/Compiler.h"<br>
>>>> #include "llvm/Support/MathExtras.h"<br>
>>>> @@ -51,7 +50,7 @@ class DenseMapIterator;<br>
>>>><br>
>>>> template <typename DerivedT, typename
KeyT, typename ValueT, typename KeyInfoT,<br>
>>>> typename BucketT><br>
>>>> -class DenseMapBase : public DebugEpochBase {<br>
>>>> +class DenseMapBase {<br>
>>>> public:<br>
>>>> typedef unsigned size_type;<br>
>>>> typedef KeyT key_type;<br>
>>>> @@ -63,17 +62,16 @@ public:<br>
>>>> const_iterator;<br>
>>>> inline iterator begin() {<br>
>>>> // When the map is empty, avoid the
overhead of AdvancePastEmptyBuckets().<br>
>>>> - return empty() ? end() :
iterator(getBuckets(), getBucketsEnd(), *this);<br>
>>>> + return empty() ? end() :
iterator(getBuckets(), getBucketsEnd());<br>
>>>> }<br>
>>>> inline iterator end() {<br>
>>>> - return iterator(getBucketsEnd(),
getBucketsEnd(), *this, true);<br>
>>>> + return iterator(getBucketsEnd(),
getBucketsEnd(), true);<br>
>>>> }<br>
>>>> inline const_iterator begin() const {<br>
>>>> - return empty() ? end()<br>
>>>> - :
const_iterator(getBuckets(), getBucketsEnd(), *this);<br>
>>>> + return empty() ? end() :
const_iterator(getBuckets(), getBucketsEnd());<br>
>>>> }<br>
>>>> inline const_iterator end() const {<br>
>>>> - return const_iterator(getBucketsEnd(),
getBucketsEnd(), *this, true);<br>
>>>> + return const_iterator(getBucketsEnd(),
getBucketsEnd(), true);<br>
>>>> }<br>
>>>><br>
>>>> bool LLVM_ATTRIBUTE_UNUSED_RESULT empty()
const {<br>
>>>> @@ -83,13 +81,11 @@ public:<br>
>>>><br>
>>>> /// Grow the densemap so that it has at
least Size buckets. Does not shrink<br>
>>>> void resize(size_type Size) {<br>
>>>> - incrementEpoch();<br>
>>>> if (Size > getNumBuckets())<br>
>>>> grow(Size);<br>
>>>> }<br>
>>>><br>
>>>> void clear() {<br>
>>>> - incrementEpoch();<br>
>>>> if (getNumEntries() == 0 &&
getNumTombstones() == 0) return;<br>
>>>><br>
>>>> // If the capacity of the array is huge,
and the # elements used is small,<br>
>>>> @@ -122,13 +118,13 @@ public:<br>
>>>> iterator find(const KeyT &Val) {<br>
>>>> BucketT *TheBucket;<br>
>>>> if (LookupBucketFor(Val, TheBucket))<br>
>>>> - return iterator(TheBucket,
getBucketsEnd(), *this, true);<br>
>>>> + return iterator(TheBucket,
getBucketsEnd(), true);<br>
>>>> return end();<br>
>>>> }<br>
>>>> const_iterator find(const KeyT &Val)
const {<br>
>>>> const BucketT *TheBucket;<br>
>>>> if (LookupBucketFor(Val, TheBucket))<br>
>>>> - return const_iterator(TheBucket,
getBucketsEnd(), *this, true);<br>
>>>> + return const_iterator(TheBucket,
getBucketsEnd(), true);<br>
>>>> return end();<br>
>>>> }<br>
>>>><br>
>>>> @@ -141,14 +137,14 @@ public:<br>
>>>> iterator find_as(const LookupKeyT &Val)
{<br>
>>>> BucketT *TheBucket;<br>
>>>> if (LookupBucketFor(Val, TheBucket))<br>
>>>> - return iterator(TheBucket,
getBucketsEnd(), *this, true);<br>
>>>> + return iterator(TheBucket,
getBucketsEnd(), true);<br>
>>>> return end();<br>
>>>> }<br>
>>>> template<class LookupKeyT><br>
>>>> const_iterator find_as(const LookupKeyT
&Val) const {<br>
>>>> const BucketT *TheBucket;<br>
>>>> if (LookupBucketFor(Val, TheBucket))<br>
>>>> - return const_iterator(TheBucket,
getBucketsEnd(), *this, true);<br>
>>>> + return const_iterator(TheBucket,
getBucketsEnd(), true);<br>
>>>> return end();<br>
>>>> }<br>
>>>><br>
>>>> @@ -167,13 +163,12 @@ public:<br>
>>>> std::pair<iterator, bool>
insert(const std::pair<KeyT, ValueT> &KV) {<br>
>>>> BucketT *TheBucket;<br>
>>>> if (LookupBucketFor(KV.first, TheBucket))<br>
>>>> - return std::make_pair(iterator(TheBucket,
getBucketsEnd(), *this, true),<br>
>>>> + return std::make_pair(iterator(TheBucket,
getBucketsEnd(), true),<br>
>>>> false); //
Already in map.<br>
>>>><br>
>>>> // Otherwise, insert the new element.<br>
>>>> TheBucket = InsertIntoBucket(KV.first,
KV.second, TheBucket);<br>
>>>> - return std::make_pair(iterator(TheBucket,
getBucketsEnd(), *this, true),<br>
>>>> - true);<br>
>>>> + return std::make_pair(iterator(TheBucket,
getBucketsEnd(), true), true);<br>
>>>> }<br>
>>>><br>
>>>> // Inserts key,value pair into the map if
the key isn't already in the map.<br>
>>>> @@ -182,15 +177,14 @@ public:<br>
>>>> std::pair<iterator, bool>
insert(std::pair<KeyT, ValueT> &&KV) {<br>
>>>> BucketT *TheBucket;<br>
>>>> if (LookupBucketFor(KV.first, TheBucket))<br>
>>>> - return std::make_pair(iterator(TheBucket,
getBucketsEnd(), *this, true),<br>
>>>> + return std::make_pair(iterator(TheBucket,
getBucketsEnd(), true),<br>
>>>> false); //
Already in map.<br>
>>>> -<br>
>>>> +<br>
>>>> // Otherwise, insert the new element.<br>
>>>> TheBucket =
InsertIntoBucket(std::move(KV.first),<br>
>>>>
std::move(KV.second),<br>
>>>> TheBucket);<br>
>>>> - return std::make_pair(iterator(TheBucket,
getBucketsEnd(), *this, true),<br>
>>>> - true);<br>
>>>> + return std::make_pair(iterator(TheBucket,
getBucketsEnd(), true), true);<br>
>>>> }<br>
>>>><br>
>>>> /// insert - Range insertion of pairs.<br>
>>>> @@ -437,8 +431,6 @@ private:<br>
>>>> }<br>
>>>><br>
>>>> BucketT *InsertIntoBucketImpl(const KeyT
&Key, BucketT *TheBucket) {<br>
>>>> - incrementEpoch();<br>
>>>> -<br>
>>>> // If the load of the hash table is more
than 3/4, or if fewer than 1/8 of<br>
>>>> // the buckets are empty (meaning that
many are filled with tombstones),<br>
>>>> // grow the table.<br>
>>>> @@ -995,10 +987,9 @@ private:<br>
>>>><br>
>>>> template <typename KeyT, typename ValueT,
typename KeyInfoT, typename Bucket,<br>
>>>> bool IsConst><br>
>>>> -class DenseMapIterator :
DebugEpochBase::HandleBase {<br>
>>>> +class DenseMapIterator {<br>
>>>> typedef DenseMapIterator<KeyT, ValueT,
KeyInfoT, Bucket, true> ConstIterator;<br>
>>>> friend class DenseMapIterator<KeyT,
ValueT, KeyInfoT, Bucket, true>;<br>
>>>> - friend class DenseMapIterator<KeyT,
ValueT, KeyInfoT, Bucket, false>;<br>
>>>><br>
>>>> public:<br>
>>>> typedef ptrdiff_t difference_type;<br>
>>>> @@ -1012,10 +1003,8 @@ private:<br>
>>>> public:<br>
>>>> DenseMapIterator() : Ptr(nullptr),
End(nullptr) {}<br>
>>>><br>
>>>> - DenseMapIterator(pointer Pos, pointer E,
const DebugEpochBase &Epoch,<br>
>>>> - bool NoAdvance = false)<br>
>>>> - : DebugEpochBase::HandleBase(&Epoch),
Ptr(Pos), End(E) {<br>
>>>> - assert(isHandleInSync() &&
"invalid construction!");<br>
>>>> + DenseMapIterator(pointer Pos, pointer E,
bool NoAdvance = false)<br>
>>>> + : Ptr(Pos), End(E) {<br>
>>>> if (!NoAdvance)
AdvancePastEmptyBuckets();<br>
>>>> }<br>
>>>><br>
>>>> @@ -1026,40 +1015,28 @@ public:<br>
>>>> typename = typename
std::enable_if<!IsConstSrc && IsConst>::type><br>
>>>> DenseMapIterator(<br>
>>>> const DenseMapIterator<KeyT, ValueT,
KeyInfoT, Bucket, IsConstSrc> &I)<br>
>>>> - : DebugEpochBase::HandleBase(I),
Ptr(I.Ptr), End(I.End) {}<br>
>>>> + : Ptr(I.Ptr), End(I.End) {}<br>
>>>><br>
>>>> reference operator*() const {<br>
>>>> - assert(isHandleInSync() &&
"invalid iterator access!");<br>
>>>> return *Ptr;<br>
>>>> }<br>
>>>> pointer operator->() const {<br>
>>>> - assert(isHandleInSync() &&
"invalid iterator access!");<br>
>>>> return Ptr;<br>
>>>> }<br>
>>>><br>
>>>> bool operator==(const ConstIterator
&RHS) const {<br>
>>>> - assert((!Ptr || isHandleInSync())
&& "handle not in sync!");<br>
>>>> - assert((!RHS.Ptr ||
RHS.isHandleInSync()) && "handle not in sync!");<br>
>>>> - assert(getEpochAddress() ==
RHS.getEpochAddress() &&<br>
>>>> - "comparing incomparable
iterators!");<br>
>>>> - return Ptr == RHS.Ptr;<br>
>>>> + return Ptr == RHS.operator->();<br>
>>>> }<br>
>>>> bool operator!=(const ConstIterator
&RHS) const {<br>
>>>> - assert((!Ptr || isHandleInSync())
&& "handle not in sync!");<br>
>>>> - assert((!RHS.Ptr ||
RHS.isHandleInSync()) && "handle not in sync!");<br>
>>>> - assert(getEpochAddress() ==
RHS.getEpochAddress() &&<br>
>>>> - "comparing incomparable
iterators!");<br>
>>>> - return Ptr != RHS.Ptr;<br>
>>>> + return Ptr != RHS.operator->();<br>
>>>> }<br>
>>>><br>
>>>> inline DenseMapIterator& operator++()
{ // Preincrement<br>
>>>> - assert(isHandleInSync() &&
"invalid iterator access!");<br>
>>>> ++Ptr;<br>
>>>> AdvancePastEmptyBuckets();<br>
>>>> return *this;<br>
>>>> }<br>
>>>> DenseMapIterator operator++(int) { //
Postincrement<br>
>>>> - assert(isHandleInSync() &&
"invalid iterator access!");<br>
>>>> DenseMapIterator tmp = *this; ++*this;
return tmp;<br>
>>>> }<br>
>>>><br>
>>>><br>
>>>> Removed: llvm/trunk/include/llvm/ADT/EpochTracker.h<br>
>>>> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/EpochTracker.h?rev=231213&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/EpochTracker.h?rev=231213&view=auto</a><br>
>>>> ==============================================================================<br>
>>>> --- llvm/trunk/include/llvm/ADT/EpochTracker.h
(original)<br>
>>>> +++ llvm/trunk/include/llvm/ADT/EpochTracker.h
(removed)<br>
>>>> @@ -1,95 +0,0 @@<br>
>>>> -//===- llvm/ADT/EpochTracker.h - ADT epoch
tracking --------------*- C++ -*-==//<br>
>>>> -//<br>
>>>> -// The LLVM Compiler
Infrastructure<br>
>>>> -//<br>
>>>> -// This file is distributed under the
University of Illinois Open Source<br>
>>>> -// License. See LICENSE.TXT for details.<br>
>>>> -//<br>
>>>> -//===----------------------------------------------------------------------===//<br>
>>>> -//<br>
>>>> -// This file defines the DebugEpochBase and
DebugEpochBase::HandleBase classes.<br>
>>>> -// These can be used to write iterators that
are fail-fast when LLVM is built<br>
>>>> -// with asserts enabled.<br>
>>>> -//<br>
>>>> -//===----------------------------------------------------------------------===//<br>
>>>> -<br>
>>>> -#ifndef LLVM_ADT_EPOCH_TRACKER_H<br>
>>>> -#define LLVM_ADT_EPOCH_TRACKER_H<br>
>>>> -<br>
>>>> -#include <cstdint><br>
>>>> -<br>
>>>> -namespace llvm {<br>
>>>> -<br>
>>>> -#ifdef NDEBUG<br>
>>>> -<br>
>>>> -class DebugEpochBase {<br>
>>>> -public:<br>
>>>> - void incrementEpoch() {}<br>
>>>> -<br>
>>>> - class HandleBase {<br>
>>>> - public:<br>
>>>> - HandleBase() {}<br>
>>>> - explicit HandleBase(const DebugEpochBase
*) {}<br>
>>>> - bool isHandleInSync() { return true; }<br>
>>>> - };<br>
>>>> -};<br>
>>>> -<br>
>>>> -#else<br>
>>>> -<br>
>>>> -/// \brief A base class for data structure
classes wishing to make iterators<br>
>>>> -/// ("handles") pointing into themselves
fail-fast. When building without<br>
>>>> -/// asserts, this class is empty and does
nothing.<br>
>>>> -///<br>
>>>> -/// DebugEpochBase does not by itself track
handles pointing into itself. The<br>
>>>> -/// expectation is that routines touching
the handles will poll on<br>
>>>> -/// isHandleInSync at appropriate points to
assert that the handle they're using<br>
>>>> -/// is still valid.<br>
>>>> -///<br>
>>>> -class DebugEpochBase {<br>
>>>> - uint64_t Epoch;<br>
>>>> -<br>
>>>> -public:<br>
>>>> - DebugEpochBase() : Epoch(0) {}<br>
>>>> -<br>
>>>> - /// \brief Calling incrementEpoch
invalidates all handles pointing into the<br>
>>>> - /// calling instance.<br>
>>>> - void incrementEpoch() { ++Epoch; }<br>
>>>> -<br>
>>>> - /// \brief The destructor calls
incrementEpoch to make use-after-free bugs<br>
>>>> - /// more likely to crash
deterministically.<br>
>>>> - ~DebugEpochBase() { incrementEpoch(); }<br>
>>>> -<br>
>>>> - /// \brief A base class for iterator
classes ("handles") that wish to poll for<br>
>>>> - /// iterator invalidating modifications in
the underlying data structure.<br>
>>>> - /// When LLVM is built without asserts,
this class is empty and does nothing.<br>
>>>> - ///<br>
>>>> - /// HandleBase does not track the parent
data structure by itself. It expects<br>
>>>> - /// the routines modifying the data
structure to call incrementEpoch when they<br>
>>>> - /// make an iterator-invalidating
modification.<br>
>>>> - ///<br>
>>>> - class HandleBase {<br>
>>>> - const uint64_t *EpochAddress;<br>
>>>> - uint64_t EpochAtCreation;<br>
>>>> -<br>
>>>> - public:<br>
>>>> - HandleBase() : EpochAddress(nullptr),
EpochAtCreation(UINT64_MAX) {}<br>
>>>> -<br>
>>>> - explicit HandleBase(const DebugEpochBase
*Parent)<br>
>>>> - :
EpochAddress(&Parent->Epoch),
EpochAtCreation(Parent->Epoch) {}<br>
>>>> -<br>
>>>> - /// \brief Returns true if the
DebugEpochBase this Handle is linked to has<br>
>>>> - /// not called incrementEpoch on itself
since the creation of this<br>
>>>> - /// HandleBase instance.<br>
>>>> - bool isHandleInSync() const { return
*EpochAddress == EpochAtCreation; }<br>
>>>> -<br>
>>>> - /// \brief Returns a pointer to the
epoch word stored in the data structure<br>
>>>> - /// this handle points into.<br>
>>>> - const uint64_t *getEpochAddress() const
{ return EpochAddress; }<br>
>>>> - };<br>
>>>> -};<br>
>>>> -<br>
>>>> -#endif<br>
>>>> -<br>
>>>> -} // namespace llvm<br>
>>>> -<br>
>>>> -#endif<br>
>>>><br>
>>>><br>
>>>> _______________________________________________<br>
>>>> llvm-commits mailing list<br>
>>>> <a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
>>>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br>
</blockquote>
</div>
<br>
<fieldset></fieldset>
<br>
<pre>_______________________________________________
llvm-commits mailing list
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a>
</pre>
</blockquote>
<br>
</div><div bgcolor="#FFFFFF" text="#000000"><pre cols="72">--
Rick Foos
Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project</pre>
</div>
______________________________<u></u>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/llvm-commits</a><br>
</blockquote></div>