[llvm] r233310 - [ADT][CMake][AutoConf] Fail-fast iterators for DenseMap

Eric Fiselier eric at efcs.ca
Tue May 12 15:54:36 PDT 2015


Committed a modified version of the original fix as r237204. It allows
LLVM_ABI_BREAKING_CHECKS to be undefined but not empty.

/Eric

On Tue, May 12, 2015 at 5:17 PM, Sanjoy Das
<sanjoy at playingwithpointers.com> wrote:
> On Tue, May 12, 2015 at 1:56 PM, Eric Fiselier <eric at efcs.ca> wrote:
>>> I have a question: if you don't use LLVMConfig.cmake.in then how do
>>> you get the values for build variables like LLVM_INCLUDE_DIRS,
>>> LLVM_ENABLE_THREADS LLVM_ENABLE_RTTI etc.?
>>
>> The standalone libc++abi build uses LLVM's CMake files without
>> configuring LLVM. We don't *need* values for those variables because:
>> 1. libc++abi doesn't use any LLVM_*  CMake variables directly.
>> 2. AddLLVM.cmake and HandleLLVMOptions.cmake do not require those
>> variables to be set in order to work.
>
> Hm, so it is (2) that LLVM_ENABLE_ABI_BREAKING_CHECKS violates.  Given
> that, I think the original fix is okay to check in.
>
> -- Sanjoy
>
>>
>> However if the values are set by the user during configuration then
>> libc++abi uses the LLVM CMake modules to add the appropriate
>> compile/link flags.
>>
>> /Eric
>>
>>
>>
>> On Tue, May 12, 2015 at 4:37 PM, Sanjoy Das
>> <sanjoy at playingwithpointers.com> wrote:
>>> I have a question: if you don't use LLVMConfig.cmake.in then how do
>>> you get the values for build variables like LLVM_INCLUDE_DIRS,
>>> LLVM_ENABLE_THREADS LLVM_ENABLE_RTTI etc.?
>>>
>>> I was talking about this reply by Daniel:
>>>
>>> '''
>>> That patch works for me, thanks. I can add that to LLVMLinux's clang
>>> patches to get the buildbot working again for now. I'm not sure it's
>>> the correct change to commit though (see below).
>>>
>>>> Ideally, clang should not need to worry about this option at all -- it
>>>> is handled entirely within LLVM and is used to generate a "#define
>>>> LLVM_ENABLE_ABI_BREAKING_CHECKS" (or not) in
>>>> llvm/Config/llvm-config.h, and that header is included by all headers
>>>> from LLVM that need it.  Does building clang with an existing llvm
>>>> re-generate llvm/Config/llvm-config.h?
>>>
>>> I don't think it's re-generating llvm-config.h. From what I can tell,
>>> HandleLLVMOptions.cmake is installed at
>>> $prefix/share/llvm/cmake/HandleLLVMOptions.cmake. This file is
>>> included by clang's CMakeLists.txt without LLVM_ABI_BREAKING_CHECKS
>>> being set beforehand. I think that we need to add
>>> 'set(LLVM_ABI_BREAKING_CHECKS @LLVM_ABI_BREAKING_CHECKS@)' to
>>> cmake/modules/LLVMConfig.cmake.in so that the value is available in
>>> $prefix/share/llvm/cmake/LLVMConfig.cmake as well as llvm-config.h. Do
>>> you agree? I've already tested this and it works for me.
>>> '''
>>>
>>> On Tue, May 12, 2015 at 1:09 PM, Eric Fiselier <eric at efcs.ca> wrote:
>>>> I don't see Daniel's objection in this mail thread. Could you restate
>>>> his concern?
>>>>
>>>> On Tue, May 12, 2015 at 4:06 PM, Sanjoy Das
>>>> <sanjoy at playingwithpointers.com> wrote:
>>>>> This somehow slipped through the cracks -- apologies for the delay.
>>>>>
>>>>> I don't have any issues with checking in your fix, but Daniel did and
>>>>> I'm no CMake expert, so I'd rather wait for him to weigh in on this.
>>>>>
>>>>> -- Sanjoy
>>>>>
>>>>> On Tue, May 12, 2015 at 1:03 PM, Eric Fiselier <eric at efcs.ca> wrote:
>>>>>> Ping? Does anybody have an objection for me checking in Sanjoy's original fix?
>>>>>>
>>>>>> On Fri, May 1, 2015 at 12:17 AM, Eric Fiselier <eric at efcs.ca> wrote:
>>>>>>> Daniel's fix doesn't work for me because LLVMConfig.cmake.in isn't
>>>>>>> used when building with libc++ or libc++abi out of tree.
>>>>>>> Could you apply your original fix as well?
>>>>>>>
>>>>>>> /Eric
>>>>>>>
>>>>>>> On Wed, Apr 1, 2015 at 3:45 PM, Daniel Sanders
>>>>>>> <Daniel.Sanders at imgtec.com> wrote:
>>>>>>>> The LLVMLinux builder that was failing is currently running and according to the logs it has successfully compiled and installed clang. Thanks.
>>>>>>>> ________________________________________
>>>>>>>> From: Sanjoy Das [sanjoy at playingwithpointers.com]
>>>>>>>> Sent: 01 April 2015 04:20
>>>>>>>> To: Eric Fiselier
>>>>>>>> Cc: Daniel Sanders; llvm-commits at cs.uiuc.edu
>>>>>>>> Subject: Re: [llvm] r233310 - [ADT][CMake][AutoConf] Fail-fast iterators for DenseMap
>>>>>>>>
>>>>>>>> I fixed this in r233784 (using Daniel's approach).  Please let me know
>>>>>>>> if the fix does not work.
>>>>>>>>
>>>>>>>> Thanks!
>>>>>>>> -- Sanjoy
>>>>>>>>
>>>>>>>> On Tue, Mar 31, 2015 at 12:53 PM, Eric Fiselier <eric at efcs.ca> wrote:
>>>>>>>>> I'm having a similar problem when building libc++abi out of tree.
>>>>>>>>> libc++abi includes the HandleLLVMOptions.cmake file without including
>>>>>>>>> LLVM's top level CMakeLists.txt so LLVM_ABI_BREAKING_CHECKS is not
>>>>>>>>> defined. Your new patch fixes this for me as well.
>>>>>>>>>
>>>>>>>>> /Eric
>>>>>>>>>
>>>>>>>>> On Tue, Mar 31, 2015 at 6:35 AM, Daniel Sanders
>>>>>>>>> <Daniel.Sanders at imgtec.com> wrote:
>>>>>>>>>> That patch works for me, thanks. I can add that to LLVMLinux's clang patches to get the buildbot working again for now. I'm not sure it's the correct change to commit though (see below).
>>>>>>>>>>
>>>>>>>>>>> Ideally, clang should not need to worry about this option at all -- it
>>>>>>>>>>> is handled entirely within LLVM and is used to generate a "#define
>>>>>>>>>>> LLVM_ENABLE_ABI_BREAKING_CHECKS" (or not) in
>>>>>>>>>>> llvm/Config/llvm-config.h, and that header is included by all headers
>>>>>>>>>>> from LLVM that need it.  Does building clang with an existing llvm
>>>>>>>>>>> re-generate llvm/Config/llvm-config.h?
>>>>>>>>>>
>>>>>>>>>> I don't think it's re-generating llvm-config.h. From what I can tell, HandleLLVMOptions.cmake is installed at $prefix/share/llvm/cmake/HandleLLVMOptions.cmake. This file is included by clang's CMakeLists.txt without LLVM_ABI_BREAKING_CHECKS being set beforehand. I think that we need to add 'set(LLVM_ABI_BREAKING_CHECKS @LLVM_ABI_BREAKING_CHECKS@)' to cmake/modules/LLVMConfig.cmake.in so that the value is available in $prefix/share/llvm/cmake/LLVMConfig.cmake as well as llvm-config.h. Do you agree? I've already tested this and it works for me.
>>>>>>>>>>
>>>>>>>>>>> -----Original Message-----
>>>>>>>>>>> From: Sanjoy Das [mailto:sanjoy at playingwithpointers.com]
>>>>>>>>>>> Sent: 30 March 2015 17:32
>>>>>>>>>>> To: Daniel Sanders
>>>>>>>>>>> Cc: llvm-commits at cs.uiuc.edu
>>>>>>>>>>> Subject: Re: [llvm] r233310 - [ADT][CMake][AutoConf] Fail-fast iterators for
>>>>>>>>>>> DenseMap
>>>>>>>>>>>
>>>>>>>>>>> Ideally, clang should not need to worry about this option at all -- it
>>>>>>>>>>> is handled entirely within LLVM and is used to generate a "#define
>>>>>>>>>>> LLVM_ENABLE_ABI_BREAKING_CHECKS" (or not) in
>>>>>>>>>>> llvm/Config/llvm-config.h, and that header is included by all headers
>>>>>>>>>>> from LLVM that need it.  Does building clang with an existing llvm
>>>>>>>>>>> re-generate llvm/Config/llvm-config.h?
>>>>>>>>>>>
>>>>>>>>>>> In any case, I think the safest bet is to pretend
>>>>>>>>>>> LLVM_ABI_BREAKING_CHECKS="" is
>>>>>>>>>>> LLVM_ABI_BREAKING_CHECKS="FORCE_OFF".
>>>>>>>>>>> If you have an easy way to test this, can you please try this patch:
>>>>>>>>>>>
>>>>>>>>>>> diff --git a/cmake/modules/HandleLLVMOptions.cmake
>>>>>>>>>>> b/cmake/modules/HandleLLVMOptions.cmake
>>>>>>>>>>> index 67f86a6..898af87 100644
>>>>>>>>>>> --- a/cmake/modules/HandleLLVMOptions.cmake
>>>>>>>>>>> +++ b/cmake/modules/HandleLLVMOptions.cmake
>>>>>>>>>>> @@ -88,6 +88,10 @@ elseif( uppercase_LLVM_ABI_BREAKING_CHECKS
>>>>>>>>>>> STREQUAL
>>>>>>>>>>> "FORCE_ON" )
>>>>>>>>>>>    set( LLVM_ENABLE_ABI_BREAKING_CHECKS 1 )
>>>>>>>>>>>  elseif( uppercase_LLVM_ABI_BREAKING_CHECKS STREQUAL "FORCE_OFF" )
>>>>>>>>>>>    # We don't need to do anything special to turn off ABI breaking checks.
>>>>>>>>>>> +elseif ( uppercase_LLVM_ABI_BREAKING_CHECKS STREQUAL "" )
>>>>>>>>>>> +  # We're being run with a cached value of LLVM_ABI_BREAKING_CHECKS
>>>>>>>>>>> that is an
>>>>>>>>>>> +  # empty string.  This means we're building against an LLVM that did not
>>>>>>>>>>> have
>>>>>>>>>>> +  # this enabled when configured, so treat this like "FORCE_OFF"
>>>>>>>>>>>  else()
>>>>>>>>>>>    message(FATAL_ERROR "Unknown value for
>>>>>>>>>>> LLVM_ABI_BREAKING_CHECKS:
>>>>>>>>>>> "${LLVM_ABI_BREAKING_CHECKS}"!")
>>>>>>>>>>>  endif()
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> If not, please let me know, I'll try reproducing this myself.
>>>>>>>>>>>
>>>>>>>>>>> -- Sanjoy
>>>>>>>>>>>
>>>>>>>>>>> On Mon, Mar 30, 2015 at 2:24 AM, Daniel Sanders
>>>>>>>>>>> <Daniel.Sanders at imgtec.com> wrote:
>>>>>>>>>>> > Hi,
>>>>>>>>>>> >
>>>>>>>>>>> > It seems that this change has broken clang builds where clang is built for an
>>>>>>>>>>> already-compiled llvm. See
>>>>>>>>>>> http://buildbot.llvm.linuxfoundation.org/builders/malta/builds/87/steps/sh
>>>>>>>>>>> ell_3/logs/stdio for the full log but the relevant part is:
>>>>>>>>>>> >         -- Found LLVM_CONFIG as /home/das/llvm-
>>>>>>>>>>> linux/llvmlinux/toolchain/clang/head/install/bin/llvm-config
>>>>>>>>>>> >         CMake Error at /home/das/llvm-
>>>>>>>>>>> linux/llvmlinux/toolchain/clang/head/install/share/llvm/cmake/HandleLLVM
>>>>>>>>>>> Options.cmake:92 (message):
>>>>>>>>>>> >           Unknown value for LLVM_ABI_BREAKING_CHECKS: ""!
>>>>>>>>>>> >         Call Stack (most recent call first):
>>>>>>>>>>> >           CMakeLists.txt:102 (include)
>>>>>>>>>>> >
>>>>>>>>>>> > Should clang be setting this cmake variable from llvm-config or should it be
>>>>>>>>>>> setting it itself?
>>>>>>>>>>> >
>>>>>>>>>>> >> -----Original Message-----
>>>>>>>>>>> >> From: llvm-commits-bounces at cs.uiuc.edu [mailto:llvm-commits-
>>>>>>>>>>> >> bounces at cs.uiuc.edu] On Behalf Of Sanjoy Das
>>>>>>>>>>> >> Sent: 26 March 2015 19:25
>>>>>>>>>>> >> To: llvm-commits at cs.uiuc.edu
>>>>>>>>>>> >> Subject: [llvm] r233310 - [ADT][CMake][AutoConf] Fail-fast iterators for
>>>>>>>>>>> >> DenseMap
>>>>>>>>>>> >>
>>>>>>>>>>> >> Author: sanjoy
>>>>>>>>>>> >> Date: Thu Mar 26 14:25:01 2015
>>>>>>>>>>> >> New Revision: 233310
>>>>>>>>>>> >>
>>>>>>>>>>> >> URL: http://llvm.org/viewvc/llvm-project?rev=233310&view=rev
>>>>>>>>>>> >> Log:
>>>>>>>>>>> >> [ADT][CMake][AutoConf] Fail-fast iterators for DenseMap
>>>>>>>>>>> >>
>>>>>>>>>>> >> Summary:
>>>>>>>>>>> >> This patch is an attempt at making `DenseMapIterator`s "fail-fast".
>>>>>>>>>>> >> Fail-fast iterators that have been invalidated due to insertion into
>>>>>>>>>>> >> the host `DenseMap` deterministically trip an assert (in debug mode)
>>>>>>>>>>> >> on access, instead of non-deterministically hitting memory corruption
>>>>>>>>>>> >> issues.
>>>>>>>>>>> >>
>>>>>>>>>>> >> Enabling fail-fast iterators breaks the LLVM C++ ABI, so they are
>>>>>>>>>>> >> predicated on `LLVM_ENABLE_ABI_BREAKING_CHECKS`.
>>>>>>>>>>> >> `LLVM_ENABLE_ABI_BREAKING_CHECKS` by default flips with
>>>>>>>>>>> >> `LLVM_ENABLE_ASSERTS`, but can be clamped to ON or OFF using the
>>>>>>>>>>> CMake
>>>>>>>>>>> >> /
>>>>>>>>>>> >> autoconf build system.
>>>>>>>>>>> >>
>>>>>>>>>>> >> Reviewers: chandlerc, dexonsmith, rnk, zturner
>>>>>>>>>>> >>
>>>>>>>>>>> >> Subscribers: llvm-commits
>>>>>>>>>>> >>
>>>>>>>>>>> >> Differential Revision: http://reviews.llvm.org/D8351
>>>>>>>>>>> >>
>>>>>>>>>>> >> Added:
>>>>>>>>>>> >>     llvm/trunk/include/llvm/ADT/EpochTracker.h
>>>>>>>>>>> >> Modified:
>>>>>>>>>>> >>     llvm/trunk/CMakeLists.txt
>>>>>>>>>>> >>     llvm/trunk/autoconf/configure.ac
>>>>>>>>>>> >>     llvm/trunk/cmake/modules/HandleLLVMOptions.cmake
>>>>>>>>>>> >>     llvm/trunk/configure
>>>>>>>>>>> >>     llvm/trunk/docs/CMake.rst
>>>>>>>>>>> >>     llvm/trunk/docs/ProgrammersManual.rst
>>>>>>>>>>> >>     llvm/trunk/include/llvm/ADT/DenseMap.h
>>>>>>>>>>> >>     llvm/trunk/include/llvm/Config/config.h.in
>>>>>>>>>>> >>     llvm/trunk/include/llvm/Config/llvm-config.h.cmake
>>>>>>>>>>> >>     llvm/trunk/include/llvm/Config/llvm-config.h.in
>>>>>>>>>>> >>
>>>>>>>>>>> >> Modified: llvm/trunk/CMakeLists.txt
>>>>>>>>>>> >> URL: http://llvm.org/viewvc/llvm-
>>>>>>>>>>> >>
>>>>>>>>>>> project/llvm/trunk/CMakeLists.txt?rev=233310&r1=233309&r2=233310&view
>>>>>>>>>>> >> =diff
>>>>>>>>>>> >>
>>>>>>>>>>> ==========================================================
>>>>>>>>>>> >> ====================
>>>>>>>>>>> >> --- llvm/trunk/CMakeLists.txt (original)
>>>>>>>>>>> >> +++ llvm/trunk/CMakeLists.txt Thu Mar 26 14:25:01 2015
>>>>>>>>>>> >> @@ -252,6 +252,9 @@ else()
>>>>>>>>>>> >>    option(LLVM_ENABLE_ASSERTIONS "Enable assertions" ON)
>>>>>>>>>>> >>  endif()
>>>>>>>>>>> >>
>>>>>>>>>>> >> +set(LLVM_ABI_BREAKING_CHECKS "WITH_ASSERTS" CACHE STRING
>>>>>>>>>>> >> +  "Enable abi-breaking checks.  Can be WITH_ASSERTS, FORCE_ON or
>>>>>>>>>>> >> FORCE_OFF.")
>>>>>>>>>>> >> +
>>>>>>>>>>> >>  option(LLVM_FORCE_USE_OLD_HOST_TOOLCHAIN
>>>>>>>>>>> >>         "Set to ON to force using an old, unsupported host toolchain." OFF)
>>>>>>>>>>> >>
>>>>>>>>>>> >>
>>>>>>>>>>> >> Modified: llvm/trunk/autoconf/configure.ac
>>>>>>>>>>> >> URL: http://llvm.org/viewvc/llvm-
>>>>>>>>>>> >>
>>>>>>>>>>> project/llvm/trunk/autoconf/configure.ac?rev=233310&r1=233309&r2=23331
>>>>>>>>>>> >> 0&view=diff
>>>>>>>>>>> >>
>>>>>>>>>>> ==========================================================
>>>>>>>>>>> >> ====================
>>>>>>>>>>> >> --- llvm/trunk/autoconf/configure.ac (original)
>>>>>>>>>>> >> +++ llvm/trunk/autoconf/configure.ac Thu Mar 26 14:25:01 2015
>>>>>>>>>>> >> @@ -701,8 +701,10 @@ AC_ARG_ENABLE(assertions,AS_HELP_STRING(
>>>>>>>>>>> >>    --enable-assertions,[Compile with assertion checks enabled (default is
>>>>>>>>>>> >> YES)]),, enableval="yes")
>>>>>>>>>>> >>  if test ${enableval} = "yes" ; then
>>>>>>>>>>> >>    AC_SUBST(DISABLE_ASSERTIONS,[[]])
>>>>>>>>>>> >> +  assertions_enabled="yes"
>>>>>>>>>>> >>  else
>>>>>>>>>>> >>    AC_SUBST(DISABLE_ASSERTIONS,[[DISABLE_ASSERTIONS=1]])
>>>>>>>>>>> >> +  assertions_enabled="no"
>>>>>>>>>>> >>  fi
>>>>>>>>>>> >>
>>>>>>>>>>> >>  dnl --enable-werror : check whether we want Werror on by default
>>>>>>>>>>> >> @@ -726,6 +728,20 @@ else
>>>>>>>>>>> >>    AC_SUBST(EXPENSIVE_CHECKS,[[no]])
>>>>>>>>>>> >>  fi
>>>>>>>>>>> >>
>>>>>>>>>>> >> +dnl --enable-abi-breaking-checks : decide whether we should compile in
>>>>>>>>>>> >> asserts and
>>>>>>>>>>> >> +dnl checks that make the build ABI incompatible with an llvm built
>>>>>>>>>>> without
>>>>>>>>>>> >> these
>>>>>>>>>>> >> +dnl checks enabled.
>>>>>>>>>>> >> +AC_ARG_ENABLE(abi-breaking-checks,AS_HELP_STRING(
>>>>>>>>>>> >> +  --enable-abi-breaking-checks,[Compile with abi-breaking asserts
>>>>>>>>>>> support
>>>>>>>>>>> >> (default is with-asserts)]),, enableval="with-asserts")
>>>>>>>>>>> >> +case "$enableval" in
>>>>>>>>>>> >> +  with-asserts)  if test ${assertions_enabled} = "yes" ; then
>>>>>>>>>>> >> +
>>>>>>>>>>> AC_DEFINE([LLVM_ENABLE_ABI_BREAKING_CHECKS],[1],[Define
>>>>>>>>>>> >> to enable checks that alter the LLVM C++ ABI])
>>>>>>>>>>> >> +              fi ;;
>>>>>>>>>>> >> +  yes) AC_DEFINE([LLVM_ENABLE_ABI_BREAKING_CHECKS],[1],[Define
>>>>>>>>>>> to
>>>>>>>>>>> >> enable checks that alter the LLVM C++ ABI]) ;;
>>>>>>>>>>> >> +  no) ;;
>>>>>>>>>>> >> +  *) AC_MSG_ERROR([Invalid setting for --enable-abi-breaking-checks.
>>>>>>>>>>> Use
>>>>>>>>>>> >> "with-asserts", "yes" or "no"])
>>>>>>>>>>> >> +esac
>>>>>>>>>>> >> +
>>>>>>>>>>> >>  dnl --enable-debug-runtime : should runtime libraries have debug
>>>>>>>>>>> symbols?
>>>>>>>>>>> >>  AC_ARG_ENABLE(debug-runtime,
>>>>>>>>>>> >>     AS_HELP_STRING(--enable-debug-runtime,[Build runtime libs with
>>>>>>>>>>> debug
>>>>>>>>>>> >> symbols (default is NO)]),,enableval=no)
>>>>>>>>>>> >>
>>>>>>>>>>> >> Modified: llvm/trunk/cmake/modules/HandleLLVMOptions.cmake
>>>>>>>>>>> >> URL: http://llvm.org/viewvc/llvm-
>>>>>>>>>>> >>
>>>>>>>>>>> project/llvm/trunk/cmake/modules/HandleLLVMOptions.cmake?rev=23331
>>>>>>>>>>> >> 0&r1=233309&r2=233310&view=diff
>>>>>>>>>>> >>
>>>>>>>>>>> ==========================================================
>>>>>>>>>>> >> ====================
>>>>>>>>>>> >> --- llvm/trunk/cmake/modules/HandleLLVMOptions.cmake (original)
>>>>>>>>>>> >> +++ llvm/trunk/cmake/modules/HandleLLVMOptions.cmake Thu Mar 26
>>>>>>>>>>> >> 14:25:01 2015
>>>>>>>>>>> >> @@ -78,6 +78,20 @@ if( LLVM_ENABLE_ASSERTIONS )
>>>>>>>>>>> >>    endif()
>>>>>>>>>>> >>  endif()
>>>>>>>>>>> >>
>>>>>>>>>>> >> +string(TOUPPER "${LLVM_ABI_BREAKING_CHECKS}"
>>>>>>>>>>> >> uppercase_LLVM_ABI_BREAKING_CHECKS)
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +if( uppercase_LLVM_ABI_BREAKING_CHECKS STREQUAL
>>>>>>>>>>> "WITH_ASSERTS" )
>>>>>>>>>>> >> +  if( LLVM_ENABLE_ASSERTIONS )
>>>>>>>>>>> >> +    set( LLVM_ENABLE_ABI_BREAKING_CHECKS 1 )
>>>>>>>>>>> >> +  endif()
>>>>>>>>>>> >> +elseif( uppercase_LLVM_ABI_BREAKING_CHECKS STREQUAL
>>>>>>>>>>> "FORCE_ON" )
>>>>>>>>>>> >> +  set( LLVM_ENABLE_ABI_BREAKING_CHECKS 1 )
>>>>>>>>>>> >> +elseif( uppercase_LLVM_ABI_BREAKING_CHECKS STREQUAL
>>>>>>>>>>> "FORCE_OFF"
>>>>>>>>>>> >> )
>>>>>>>>>>> >> +  # We don't need to do anything special to turn off ABI breaking checks.
>>>>>>>>>>> >> +else()
>>>>>>>>>>> >> +  message(FATAL_ERROR "Unknown value for
>>>>>>>>>>> >> LLVM_ABI_BREAKING_CHECKS: \"${LLVM_ABI_BREAKING_CHECKS}\"!")
>>>>>>>>>>> >> +endif()
>>>>>>>>>>> >> +
>>>>>>>>>>> >>  if(WIN32)
>>>>>>>>>>> >>    set(LLVM_HAVE_LINK_VERSION_SCRIPT 0)
>>>>>>>>>>> >>    if(CYGWIN)
>>>>>>>>>>> >>
>>>>>>>>>>> >> Modified: llvm/trunk/configure
>>>>>>>>>>> >> URL: http://llvm.org/viewvc/llvm-
>>>>>>>>>>> >>
>>>>>>>>>>> project/llvm/trunk/configure?rev=233310&r1=233309&r2=233310&view=diff
>>>>>>>>>>> >>
>>>>>>>>>>> ==========================================================
>>>>>>>>>>> >> ====================
>>>>>>>>>>> >> --- llvm/trunk/configure (original)
>>>>>>>>>>> >> +++ llvm/trunk/configure Thu Mar 26 14:25:01 2015
>>>>>>>>>>> >> @@ -1426,6 +1426,9 @@ Optional Features:
>>>>>>>>>>> >>    --enable-expensive-checks
>>>>>>>>>>> >>                            Compile with expensive debug checks enabled (default
>>>>>>>>>>> >>                            is NO)
>>>>>>>>>>> >> +  --enable-abi-breaking-checks
>>>>>>>>>>> >> +                          Compile with abi-breaking asserts support (default
>>>>>>>>>>> >> +                          is with-asserts)
>>>>>>>>>>> >>    --enable-debug-runtime  Build runtime libs with debug symbols (default
>>>>>>>>>>> is
>>>>>>>>>>> >>                            NO)
>>>>>>>>>>> >>    --enable-debug-symbols  Build compiler with debug symbols (default is
>>>>>>>>>>> NO
>>>>>>>>>>> >> if
>>>>>>>>>>> >> @@ -4980,9 +4983,11 @@ fi
>>>>>>>>>>> >>  if test ${enableval} = "yes" ; then
>>>>>>>>>>> >>    DISABLE_ASSERTIONS=
>>>>>>>>>>> >>
>>>>>>>>>>> >> +  assertions_enabled="yes"
>>>>>>>>>>> >>  else
>>>>>>>>>>> >>    DISABLE_ASSERTIONS=DISABLE_ASSERTIONS=1
>>>>>>>>>>> >>
>>>>>>>>>>> >> +  assertions_enabled="no"
>>>>>>>>>>> >>  fi
>>>>>>>>>>> >>
>>>>>>>>>>> >>  # Check whether --enable-werror was given.
>>>>>>>>>>> >> @@ -5023,6 +5028,32 @@ else
>>>>>>>>>>> >>
>>>>>>>>>>> >>  fi
>>>>>>>>>>> >>
>>>>>>>>>>> >> +# Check whether --enable-abi-breaking-checks was given.
>>>>>>>>>>> >> +if test "${enable_abi_breaking_checks+set}" = set; then
>>>>>>>>>>> >> +  enableval=$enable_abi_breaking_checks;
>>>>>>>>>>> >> +else
>>>>>>>>>>> >> +  enableval="with-asserts"
>>>>>>>>>>> >> +fi
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +case "$enableval" in
>>>>>>>>>>> >> +  with-asserts)  if test ${assertions_enabled} = "yes" ; then
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +cat >>confdefs.h <<\_ACEOF
>>>>>>>>>>> >> +#define LLVM_ENABLE_ABI_BREAKING_CHECKS 1
>>>>>>>>>>> >> +_ACEOF
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +              fi ;;
>>>>>>>>>>> >> +  yes)
>>>>>>>>>>> >> +cat >>confdefs.h <<\_ACEOF
>>>>>>>>>>> >> +#define LLVM_ENABLE_ABI_BREAKING_CHECKS 1
>>>>>>>>>>> >> +_ACEOF
>>>>>>>>>>> >> + ;;
>>>>>>>>>>> >> +  no) ;;
>>>>>>>>>>> >> +  *) { { echo "$as_me:$LINENO: error: Invalid setting for --enable-abi-
>>>>>>>>>>> >> breaking-checks.  Use \"with-asserts\", \"yes\" or \"no\"" >&5
>>>>>>>>>>> >> +echo "$as_me: error: Invalid setting for --enable-abi-breaking-checks.
>>>>>>>>>>> Use
>>>>>>>>>>> >> \"with-asserts\", \"yes\" or \"no\"" >&2;}
>>>>>>>>>>> >> +   { (exit 1); exit 1; }; }
>>>>>>>>>>> >> +esac
>>>>>>>>>>> >> +
>>>>>>>>>>> >>  # Check whether --enable-debug-runtime was given.
>>>>>>>>>>> >>  if test "${enable_debug_runtime+set}" = set; then
>>>>>>>>>>> >>    enableval=$enable_debug_runtime;
>>>>>>>>>>> >>
>>>>>>>>>>> >> Modified: llvm/trunk/docs/CMake.rst
>>>>>>>>>>> >> URL: http://llvm.org/viewvc/llvm-
>>>>>>>>>>> >>
>>>>>>>>>>> project/llvm/trunk/docs/CMake.rst?rev=233310&r1=233309&r2=233310&vie
>>>>>>>>>>> >> w=diff
>>>>>>>>>>> >>
>>>>>>>>>>> ==========================================================
>>>>>>>>>>> >> ====================
>>>>>>>>>>> >> --- llvm/trunk/docs/CMake.rst (original)
>>>>>>>>>>> >> +++ llvm/trunk/docs/CMake.rst Thu Mar 26 14:25:01 2015
>>>>>>>>>>> >> @@ -270,6 +270,15 @@ LLVM-specific variables
>>>>>>>>>>> >>  **LLVM_ENABLE_WERROR**:BOOL
>>>>>>>>>>> >>    Stop and fail build, if a compiler warning is triggered. Defaults to OFF.
>>>>>>>>>>> >>
>>>>>>>>>>> >> +**LLVM_ABI_BREAKING_CHECKS**:STRING
>>>>>>>>>>> >> +  Used to decide if LLVM should be built with ABI breaking checks or
>>>>>>>>>>> >> +  not.  Allowed values are `WITH_ASSERTS` (default), `FORCE_ON` and
>>>>>>>>>>> >> +  `FORCE_OFF`.  `WITH_ASSERTS` turns on ABI breaking checks in an
>>>>>>>>>>> >> +  assertion enabled build.  `FORCE_ON` (`FORCE_OFF`) turns them on
>>>>>>>>>>> >> +  (off) irrespective of whether normal (`NDEBUG` based) assertions are
>>>>>>>>>>> >> +  enabled or not.  A version of LLVM built with ABI breaking checks
>>>>>>>>>>> >> +  is not ABI compatible with a version built without it.
>>>>>>>>>>> >> +
>>>>>>>>>>> >>  **LLVM_BUILD_32_BITS**:BOOL
>>>>>>>>>>> >>    Build 32-bits executables and libraries on 64-bits systems. This option is
>>>>>>>>>>> >>    available only on some 64-bits unix systems. Defaults to OFF.
>>>>>>>>>>> >>
>>>>>>>>>>> >> Modified: llvm/trunk/docs/ProgrammersManual.rst
>>>>>>>>>>> >> URL: http://llvm.org/viewvc/llvm-
>>>>>>>>>>> >>
>>>>>>>>>>> project/llvm/trunk/docs/ProgrammersManual.rst?rev=233310&r1=233309&r
>>>>>>>>>>> >> 2=233310&view=diff
>>>>>>>>>>> >>
>>>>>>>>>>> ==========================================================
>>>>>>>>>>> >> ====================
>>>>>>>>>>> >> --- llvm/trunk/docs/ProgrammersManual.rst (original)
>>>>>>>>>>> >> +++ llvm/trunk/docs/ProgrammersManual.rst Thu Mar 26 14:25:01 2015
>>>>>>>>>>> >> @@ -2553,6 +2553,22 @@ section on :ref:`isa and dyn_cast <isa>`
>>>>>>>>>>> >>  <HowToSetUpLLVMStyleRTTI>` which describes how you can implement
>>>>>>>>>>> this
>>>>>>>>>>> >>  pattern for use with the LLVM helpers.
>>>>>>>>>>> >>
>>>>>>>>>>> >> +.. _abi_breaking_checks:
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +ABI Breaking Checks
>>>>>>>>>>> >> +-------------------
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +Checks and asserts that alter the LLVM C++ ABI are predicated on the
>>>>>>>>>>> >> +preprocessor symbol `LLVM_ENABLE_ABI_BREAKING_CHECKS` -- LLVM
>>>>>>>>>>> >> +libraries built with `LLVM_ENABLE_ABI_BREAKING_CHECKS` are not ABI
>>>>>>>>>>> >> +compatible LLVM libraries built without it defined.  By default,
>>>>>>>>>>> >> +turning on assertions also turns on
>>>>>>>>>>> >> `LLVM_ENABLE_ABI_BREAKING_CHECKS`
>>>>>>>>>>> >> +so a default +Asserts build is not ABI compatible with a
>>>>>>>>>>> >> +default -Asserts build.  Clients that want ABI compatibility
>>>>>>>>>>> >> +between +Asserts and -Asserts builds should use the CMake or autoconf
>>>>>>>>>>> >> +build systems to set `LLVM_ENABLE_ABI_BREAKING_CHECKS`
>>>>>>>>>>> >> independently
>>>>>>>>>>> >> +of `LLVM_ENABLE_ASSERTIONS`.
>>>>>>>>>>> >> +
>>>>>>>>>>> >>  .. _coreclasses:
>>>>>>>>>>> >>
>>>>>>>>>>> >>  The Core LLVM Class Hierarchy Reference
>>>>>>>>>>> >>
>>>>>>>>>>> >> Modified: llvm/trunk/include/llvm/ADT/DenseMap.h
>>>>>>>>>>> >> URL: http://llvm.org/viewvc/llvm-
>>>>>>>>>>> >>
>>>>>>>>>>> project/llvm/trunk/include/llvm/ADT/DenseMap.h?rev=233310&r1=233309&
>>>>>>>>>>> >> r2=233310&view=diff
>>>>>>>>>>> >>
>>>>>>>>>>> ==========================================================
>>>>>>>>>>> >> ====================
>>>>>>>>>>> >> --- llvm/trunk/include/llvm/ADT/DenseMap.h (original)
>>>>>>>>>>> >> +++ llvm/trunk/include/llvm/ADT/DenseMap.h Thu Mar 26 14:25:01 2015
>>>>>>>>>>> >> @@ -15,6 +15,7 @@
>>>>>>>>>>> >>  #define LLVM_ADT_DENSEMAP_H
>>>>>>>>>>> >>
>>>>>>>>>>> >>  #include "llvm/ADT/DenseMapInfo.h"
>>>>>>>>>>> >> +#include "llvm/ADT/EpochTracker.h"
>>>>>>>>>>> >>  #include "llvm/Support/AlignOf.h"
>>>>>>>>>>> >>  #include "llvm/Support/Compiler.h"
>>>>>>>>>>> >>  #include "llvm/Support/MathExtras.h"
>>>>>>>>>>> >> @@ -50,7 +51,7 @@ class DenseMapIterator;
>>>>>>>>>>> >>
>>>>>>>>>>> >>  template <typename DerivedT, typename KeyT, typename ValueT,
>>>>>>>>>>> >> typename KeyInfoT,
>>>>>>>>>>> >>            typename BucketT>
>>>>>>>>>>> >> -class DenseMapBase {
>>>>>>>>>>> >> +class DenseMapBase : public DebugEpochBase {
>>>>>>>>>>> >>  public:
>>>>>>>>>>> >>    typedef unsigned size_type;
>>>>>>>>>>> >>    typedef KeyT key_type;
>>>>>>>>>>> >> @@ -62,16 +63,17 @@ public:
>>>>>>>>>>> >>        const_iterator;
>>>>>>>>>>> >>    inline iterator begin() {
>>>>>>>>>>> >>      // When the map is empty, avoid the overhead of
>>>>>>>>>>> >> AdvancePastEmptyBuckets().
>>>>>>>>>>> >> -    return empty() ? end() : iterator(getBuckets(), getBucketsEnd());
>>>>>>>>>>> >> +    return empty() ? end() : iterator(getBuckets(), getBucketsEnd(),
>>>>>>>>>>> *this);
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>    inline iterator end() {
>>>>>>>>>>> >> -    return iterator(getBucketsEnd(), getBucketsEnd(), true);
>>>>>>>>>>> >> +    return iterator(getBucketsEnd(), getBucketsEnd(), *this, true);
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>    inline const_iterator begin() const {
>>>>>>>>>>> >> -    return empty() ? end() : const_iterator(getBuckets(),
>>>>>>>>>>> getBucketsEnd());
>>>>>>>>>>> >> +    return empty() ? end()
>>>>>>>>>>> >> +                   : const_iterator(getBuckets(), getBucketsEnd(), *this);
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>    inline const_iterator end() const {
>>>>>>>>>>> >> -    return const_iterator(getBucketsEnd(), getBucketsEnd(), true);
>>>>>>>>>>> >> +    return const_iterator(getBucketsEnd(), getBucketsEnd(), *this, true);
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>
>>>>>>>>>>> >>    bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const {
>>>>>>>>>>> >> @@ -81,11 +83,13 @@ public:
>>>>>>>>>>> >>
>>>>>>>>>>> >>    /// Grow the densemap so that it has at least Size buckets. Does not
>>>>>>>>>>> shrink
>>>>>>>>>>> >>    void resize(size_type Size) {
>>>>>>>>>>> >> +    incrementEpoch();
>>>>>>>>>>> >>      if (Size > getNumBuckets())
>>>>>>>>>>> >>        grow(Size);
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>
>>>>>>>>>>> >>    void clear() {
>>>>>>>>>>> >> +    incrementEpoch();
>>>>>>>>>>> >>      if (getNumEntries() == 0 && getNumTombstones() == 0) return;
>>>>>>>>>>> >>
>>>>>>>>>>> >>      // If the capacity of the array is huge, and the # elements used is small,
>>>>>>>>>>> >> @@ -118,13 +122,13 @@ public:
>>>>>>>>>>> >>    iterator find(const KeyT &Val) {
>>>>>>>>>>> >>      BucketT *TheBucket;
>>>>>>>>>>> >>      if (LookupBucketFor(Val, TheBucket))
>>>>>>>>>>> >> -      return iterator(TheBucket, getBucketsEnd(), true);
>>>>>>>>>>> >> +      return iterator(TheBucket, getBucketsEnd(), *this, true);
>>>>>>>>>>> >>      return end();
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>    const_iterator find(const KeyT &Val) const {
>>>>>>>>>>> >>      const BucketT *TheBucket;
>>>>>>>>>>> >>      if (LookupBucketFor(Val, TheBucket))
>>>>>>>>>>> >> -      return const_iterator(TheBucket, getBucketsEnd(), true);
>>>>>>>>>>> >> +      return const_iterator(TheBucket, getBucketsEnd(), *this, true);
>>>>>>>>>>> >>      return end();
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>
>>>>>>>>>>> >> @@ -137,14 +141,14 @@ public:
>>>>>>>>>>> >>    iterator find_as(const LookupKeyT &Val) {
>>>>>>>>>>> >>      BucketT *TheBucket;
>>>>>>>>>>> >>      if (LookupBucketFor(Val, TheBucket))
>>>>>>>>>>> >> -      return iterator(TheBucket, getBucketsEnd(), true);
>>>>>>>>>>> >> +      return iterator(TheBucket, getBucketsEnd(), *this, true);
>>>>>>>>>>> >>      return end();
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>    template<class LookupKeyT>
>>>>>>>>>>> >>    const_iterator find_as(const LookupKeyT &Val) const {
>>>>>>>>>>> >>      const BucketT *TheBucket;
>>>>>>>>>>> >>      if (LookupBucketFor(Val, TheBucket))
>>>>>>>>>>> >> -      return const_iterator(TheBucket, getBucketsEnd(), true);
>>>>>>>>>>> >> +      return const_iterator(TheBucket, getBucketsEnd(), *this, true);
>>>>>>>>>>> >>      return end();
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>
>>>>>>>>>>> >> @@ -163,12 +167,13 @@ public:
>>>>>>>>>>> >>    std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
>>>>>>>>>>> >>      BucketT *TheBucket;
>>>>>>>>>>> >>      if (LookupBucketFor(KV.first, TheBucket))
>>>>>>>>>>> >> -      return std::make_pair(iterator(TheBucket, getBucketsEnd(), true),
>>>>>>>>>>> >> +      return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this,
>>>>>>>>>>> true),
>>>>>>>>>>> >>                              false); // Already in map.
>>>>>>>>>>> >>
>>>>>>>>>>> >>      // Otherwise, insert the new element.
>>>>>>>>>>> >>      TheBucket = InsertIntoBucket(KV.first, KV.second, TheBucket);
>>>>>>>>>>> >> -    return std::make_pair(iterator(TheBucket, getBucketsEnd(), true),
>>>>>>>>>>> true);
>>>>>>>>>>> >> +    return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this,
>>>>>>>>>>> true),
>>>>>>>>>>> >> +                          true);
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>
>>>>>>>>>>> >>    // Inserts key,value pair into the map if the key isn't already in the map.
>>>>>>>>>>> >> @@ -177,14 +182,15 @@ public:
>>>>>>>>>>> >>    std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
>>>>>>>>>>> >>      BucketT *TheBucket;
>>>>>>>>>>> >>      if (LookupBucketFor(KV.first, TheBucket))
>>>>>>>>>>> >> -      return std::make_pair(iterator(TheBucket, getBucketsEnd(), true),
>>>>>>>>>>> >> +      return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this,
>>>>>>>>>>> true),
>>>>>>>>>>> >>                              false); // Already in map.
>>>>>>>>>>> >> -
>>>>>>>>>>> >> +
>>>>>>>>>>> >>      // Otherwise, insert the new element.
>>>>>>>>>>> >>      TheBucket = InsertIntoBucket(std::move(KV.first),
>>>>>>>>>>> >>                                   std::move(KV.second),
>>>>>>>>>>> >>                                   TheBucket);
>>>>>>>>>>> >> -    return std::make_pair(iterator(TheBucket, getBucketsEnd(), true),
>>>>>>>>>>> true);
>>>>>>>>>>> >> +    return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this,
>>>>>>>>>>> true),
>>>>>>>>>>> >> +                          true);
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>
>>>>>>>>>>> >>    /// insert - Range insertion of pairs.
>>>>>>>>>>> >> @@ -431,6 +437,8 @@ private:
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>
>>>>>>>>>>> >>    BucketT *InsertIntoBucketImpl(const KeyT &Key, BucketT *TheBucket) {
>>>>>>>>>>> >> +    incrementEpoch();
>>>>>>>>>>> >> +
>>>>>>>>>>> >>      // If the load of the hash table is more than 3/4, or if fewer than 1/8 of
>>>>>>>>>>> >>      // the buckets are empty (meaning that many are filled with
>>>>>>>>>>> tombstones),
>>>>>>>>>>> >>      // grow the table.
>>>>>>>>>>> >> @@ -987,9 +995,10 @@ private:
>>>>>>>>>>> >>
>>>>>>>>>>> >>  template <typename KeyT, typename ValueT, typename KeyInfoT,
>>>>>>>>>>> >> typename Bucket,
>>>>>>>>>>> >>            bool IsConst>
>>>>>>>>>>> >> -class DenseMapIterator {
>>>>>>>>>>> >> +class DenseMapIterator : DebugEpochBase::HandleBase {
>>>>>>>>>>> >>    typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>
>>>>>>>>>>> >> ConstIterator;
>>>>>>>>>>> >>    friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>;
>>>>>>>>>>> >> +  friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, false>;
>>>>>>>>>>> >>
>>>>>>>>>>> >>  public:
>>>>>>>>>>> >>    typedef ptrdiff_t difference_type;
>>>>>>>>>>> >> @@ -1003,8 +1012,10 @@ private:
>>>>>>>>>>> >>  public:
>>>>>>>>>>> >>    DenseMapIterator() : Ptr(nullptr), End(nullptr) {}
>>>>>>>>>>> >>
>>>>>>>>>>> >> -  DenseMapIterator(pointer Pos, pointer E, bool NoAdvance = false)
>>>>>>>>>>> >> -    : Ptr(Pos), End(E) {
>>>>>>>>>>> >> +  DenseMapIterator(pointer Pos, pointer E, const DebugEpochBase
>>>>>>>>>>> &Epoch,
>>>>>>>>>>> >> +                   bool NoAdvance = false)
>>>>>>>>>>> >> +      : DebugEpochBase::HandleBase(&Epoch), Ptr(Pos), End(E) {
>>>>>>>>>>> >> +    assert(isHandleInSync() && "invalid construction!");
>>>>>>>>>>> >>      if (!NoAdvance) AdvancePastEmptyBuckets();
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>
>>>>>>>>>>> >> @@ -1015,28 +1026,40 @@ public:
>>>>>>>>>>> >>              typename = typename std::enable_if<!IsConstSrc &&
>>>>>>>>>>> IsConst>::type>
>>>>>>>>>>> >>    DenseMapIterator(
>>>>>>>>>>> >>        const DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, IsConstSrc>
>>>>>>>>>>> &I)
>>>>>>>>>>> >> -      : Ptr(I.Ptr), End(I.End) {}
>>>>>>>>>>> >> +      : DebugEpochBase::HandleBase(I), Ptr(I.Ptr), End(I.End) {}
>>>>>>>>>>> >>
>>>>>>>>>>> >>    reference operator*() const {
>>>>>>>>>>> >> +    assert(isHandleInSync() && "invalid iterator access!");
>>>>>>>>>>> >>      return *Ptr;
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>    pointer operator->() const {
>>>>>>>>>>> >> +    assert(isHandleInSync() && "invalid iterator access!");
>>>>>>>>>>> >>      return Ptr;
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>
>>>>>>>>>>> >>    bool operator==(const ConstIterator &RHS) const {
>>>>>>>>>>> >> -    return Ptr == RHS.operator->();
>>>>>>>>>>> >> +    assert((!Ptr || isHandleInSync()) && "handle not in sync!");
>>>>>>>>>>> >> +    assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!");
>>>>>>>>>>> >> +    assert(getEpochAddress() == RHS.getEpochAddress() &&
>>>>>>>>>>> >> +           "comparing incomparable iterators!");
>>>>>>>>>>> >> +    return Ptr == RHS.Ptr;
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>    bool operator!=(const ConstIterator &RHS) const {
>>>>>>>>>>> >> -    return Ptr != RHS.operator->();
>>>>>>>>>>> >> +    assert((!Ptr || isHandleInSync()) && "handle not in sync!");
>>>>>>>>>>> >> +    assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!");
>>>>>>>>>>> >> +    assert(getEpochAddress() == RHS.getEpochAddress() &&
>>>>>>>>>>> >> +           "comparing incomparable iterators!");
>>>>>>>>>>> >> +    return Ptr != RHS.Ptr;
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>
>>>>>>>>>>> >>    inline DenseMapIterator& operator++() {  // Preincrement
>>>>>>>>>>> >> +    assert(isHandleInSync() && "invalid iterator access!");
>>>>>>>>>>> >>      ++Ptr;
>>>>>>>>>>> >>      AdvancePastEmptyBuckets();
>>>>>>>>>>> >>      return *this;
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>    DenseMapIterator operator++(int) {  // Postincrement
>>>>>>>>>>> >> +    assert(isHandleInSync() && "invalid iterator access!");
>>>>>>>>>>> >>      DenseMapIterator tmp = *this; ++*this; return tmp;
>>>>>>>>>>> >>    }
>>>>>>>>>>> >>
>>>>>>>>>>> >>
>>>>>>>>>>> >> Added: llvm/trunk/include/llvm/ADT/EpochTracker.h
>>>>>>>>>>> >> URL: http://llvm.org/viewvc/llvm-
>>>>>>>>>>> >>
>>>>>>>>>>> project/llvm/trunk/include/llvm/ADT/EpochTracker.h?rev=233310&view=aut
>>>>>>>>>>> >> o
>>>>>>>>>>> >>
>>>>>>>>>>> ==========================================================
>>>>>>>>>>> >> ====================
>>>>>>>>>>> >> --- llvm/trunk/include/llvm/ADT/EpochTracker.h (added)
>>>>>>>>>>> >> +++ llvm/trunk/include/llvm/ADT/EpochTracker.h Thu Mar 26 14:25:01
>>>>>>>>>>> 2015
>>>>>>>>>>> >> @@ -0,0 +1,99 @@
>>>>>>>>>>> >> +//===- llvm/ADT/EpochTracker.h - ADT epoch tracking --------------*- C++
>>>>>>>>>>> -*-
>>>>>>>>>>> >> ==//
>>>>>>>>>>> >> +//
>>>>>>>>>>> >> +//                     The LLVM Compiler Infrastructure
>>>>>>>>>>> >> +//
>>>>>>>>>>> >> +// This file is distributed under the University of Illinois Open Source
>>>>>>>>>>> >> +// License. See LICENSE.TXT for details.
>>>>>>>>>>> >> +//
>>>>>>>>>>> >> +//===----------------------------------------------------------------------===//
>>>>>>>>>>> >> +//
>>>>>>>>>>> >> +// This file defines the DebugEpochBase and
>>>>>>>>>>> DebugEpochBase::HandleBase
>>>>>>>>>>> >> classes.
>>>>>>>>>>> >> +// These can be used to write iterators that are fail-fast when LLVM is
>>>>>>>>>>> built
>>>>>>>>>>> >> +// with asserts enabled.
>>>>>>>>>>> >> +//
>>>>>>>>>>> >> +//===----------------------------------------------------------------------===//
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +#ifndef LLVM_ADT_EPOCH_TRACKER_H
>>>>>>>>>>> >> +#define LLVM_ADT_EPOCH_TRACKER_H
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +#include "llvm/Config/llvm-config.h"
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +#include <cstdint>
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +namespace llvm {
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +#ifndef LLVM_ENABLE_ABI_BREAKING_CHECKS
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +class DebugEpochBase {
>>>>>>>>>>> >> +public:
>>>>>>>>>>> >> +  void incrementEpoch() {}
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +  class HandleBase {
>>>>>>>>>>> >> +  public:
>>>>>>>>>>> >> +    HandleBase() {}
>>>>>>>>>>> >> +    explicit HandleBase(const DebugEpochBase *) {}
>>>>>>>>>>> >> +    bool isHandleInSync() const { return true; }
>>>>>>>>>>> >> +    const void *getEpochAddress() const { return nullptr; }
>>>>>>>>>>> >> +  };
>>>>>>>>>>> >> +};
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +#else
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +/// \brief A base class for data structure classes wishing to make iterators
>>>>>>>>>>> >> +/// ("handles") pointing into themselves fail-fast.  When building without
>>>>>>>>>>> >> +/// asserts, this class is empty and does nothing.
>>>>>>>>>>> >> +///
>>>>>>>>>>> >> +/// DebugEpochBase does not by itself track handles pointing into itself.
>>>>>>>>>>> >> The
>>>>>>>>>>> >> +/// expectation is that routines touching the handles will poll on
>>>>>>>>>>> >> +/// isHandleInSync at appropriate points to assert that the handle
>>>>>>>>>>> they're
>>>>>>>>>>> >> using
>>>>>>>>>>> >> +/// is still valid.
>>>>>>>>>>> >> +///
>>>>>>>>>>> >> +class DebugEpochBase {
>>>>>>>>>>> >> +  uint64_t Epoch;
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +public:
>>>>>>>>>>> >> +  DebugEpochBase() : Epoch(0) {}
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +  /// \brief Calling incrementEpoch invalidates all handles pointing into
>>>>>>>>>>> the
>>>>>>>>>>> >> +  /// calling instance.
>>>>>>>>>>> >> +  void incrementEpoch() { ++Epoch; }
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +  /// \brief The destructor calls incrementEpoch to make use-after-free
>>>>>>>>>>> bugs
>>>>>>>>>>> >> +  /// more likely to crash deterministically.
>>>>>>>>>>> >> +  ~DebugEpochBase() { incrementEpoch(); }
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +  /// \brief A base class for iterator classes ("handles") that wish to poll
>>>>>>>>>>> for
>>>>>>>>>>> >> +  /// iterator invalidating modifications in the underlying data structure.
>>>>>>>>>>> >> +  /// When LLVM is built without asserts, this class is empty and does
>>>>>>>>>>> >> nothing.
>>>>>>>>>>> >> +  ///
>>>>>>>>>>> >> +  /// HandleBase does not track the parent data structure by itself.  It
>>>>>>>>>>> >> expects
>>>>>>>>>>> >> +  /// the routines modifying the data structure to call incrementEpoch
>>>>>>>>>>> when
>>>>>>>>>>> >> they
>>>>>>>>>>> >> +  /// make an iterator-invalidating modification.
>>>>>>>>>>> >> +  ///
>>>>>>>>>>> >> +  class HandleBase {
>>>>>>>>>>> >> +    const uint64_t *EpochAddress;
>>>>>>>>>>> >> +    uint64_t EpochAtCreation;
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +  public:
>>>>>>>>>>> >> +    HandleBase() : EpochAddress(nullptr),
>>>>>>>>>>> EpochAtCreation(UINT64_MAX) {}
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +    explicit HandleBase(const DebugEpochBase *Parent)
>>>>>>>>>>> >> +        : EpochAddress(&Parent->Epoch), EpochAtCreation(Parent->Epoch)
>>>>>>>>>>> {}
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +    /// \brief Returns true if the DebugEpochBase this Handle is linked to
>>>>>>>>>>> has
>>>>>>>>>>> >> +    /// not called incrementEpoch on itself since the creation of this
>>>>>>>>>>> >> +    /// HandleBase instance.
>>>>>>>>>>> >> +    bool isHandleInSync() const { return *EpochAddress ==
>>>>>>>>>>> EpochAtCreation;
>>>>>>>>>>> >> }
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +    /// \brief Returns a pointer to the epoch word stored in the data
>>>>>>>>>>> >> structure
>>>>>>>>>>> >> +    /// this handle points into.  Can be used to check if two iterators point
>>>>>>>>>>> >> +    /// into the same data structure.
>>>>>>>>>>> >> +    const void *getEpochAddress() const { return EpochAddress; }
>>>>>>>>>>> >> +  };
>>>>>>>>>>> >> +};
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +#endif // LLVM_ENABLE_ABI_BREAKING_CHECKS
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +} // namespace llvm
>>>>>>>>>>> >> +
>>>>>>>>>>> >> +#endif
>>>>>>>>>>> >>
>>>>>>>>>>> >> Modified: llvm/trunk/include/llvm/Config/config.h.in
>>>>>>>>>>> >> URL: http://llvm.org/viewvc/llvm-
>>>>>>>>>>> >>
>>>>>>>>>>> project/llvm/trunk/include/llvm/Config/config.h.in?rev=233310&r1=233309&
>>>>>>>>>>> >> r2=233310&view=diff
>>>>>>>>>>> >>
>>>>>>>>>>> ==========================================================
>>>>>>>>>>> >> ====================
>>>>>>>>>>> >> --- llvm/trunk/include/llvm/Config/config.h.in (original)
>>>>>>>>>>> >> +++ llvm/trunk/include/llvm/Config/config.h.in Thu Mar 26 14:25:01 2015
>>>>>>>>>>> >> @@ -417,6 +417,9 @@
>>>>>>>>>>> >>  /* Installation directory for documentation */
>>>>>>>>>>> >>  #undef LLVM_DOCSDIR
>>>>>>>>>>> >>
>>>>>>>>>>> >> +/* Define to enable checks that alter the LLVM C++ ABI */
>>>>>>>>>>> >> +#undef LLVM_ENABLE_ABI_BREAKING_CHECKS
>>>>>>>>>>> >> +
>>>>>>>>>>> >>  /* Define if threads enabled */
>>>>>>>>>>> >>  #undef LLVM_ENABLE_THREADS
>>>>>>>>>>> >>
>>>>>>>>>>> >>
>>>>>>>>>>> >> Modified: llvm/trunk/include/llvm/Config/llvm-config.h.cmake
>>>>>>>>>>> >> URL: http://llvm.org/viewvc/llvm-
>>>>>>>>>>> >> project/llvm/trunk/include/llvm/Config/llvm-
>>>>>>>>>>> >> config.h.cmake?rev=233310&r1=233309&r2=233310&view=diff
>>>>>>>>>>> >>
>>>>>>>>>>> ==========================================================
>>>>>>>>>>> >> ====================
>>>>>>>>>>> >> --- llvm/trunk/include/llvm/Config/llvm-config.h.cmake (original)
>>>>>>>>>>> >> +++ llvm/trunk/include/llvm/Config/llvm-config.h.cmake Thu Mar 26
>>>>>>>>>>> 14:25:01
>>>>>>>>>>> >> 2015
>>>>>>>>>>> >> @@ -101,4 +101,8 @@
>>>>>>>>>>> >>  /* Define if we link Polly to the tools */
>>>>>>>>>>> >>  #cmakedefine LINK_POLLY_INTO_TOOLS
>>>>>>>>>>> >>
>>>>>>>>>>> >> +/* Define if LLVM is built with asserts and checks that change the layout
>>>>>>>>>>> of
>>>>>>>>>>> >> +   client-visible data structures.  */
>>>>>>>>>>> >> +#cmakedefine LLVM_ENABLE_ABI_BREAKING_CHECKS
>>>>>>>>>>> >> +
>>>>>>>>>>> >>  #endif
>>>>>>>>>>> >>
>>>>>>>>>>> >> Modified: llvm/trunk/include/llvm/Config/llvm-config.h.in
>>>>>>>>>>> >> URL: http://llvm.org/viewvc/llvm-
>>>>>>>>>>> >> project/llvm/trunk/include/llvm/Config/llvm-
>>>>>>>>>>> >> config.h.in?rev=233310&r1=233309&r2=233310&view=diff
>>>>>>>>>>> >>
>>>>>>>>>>> ==========================================================
>>>>>>>>>>> >> ====================
>>>>>>>>>>> >> --- llvm/trunk/include/llvm/Config/llvm-config.h.in (original)
>>>>>>>>>>> >> +++ llvm/trunk/include/llvm/Config/llvm-config.h.in Thu Mar 26 14:25:01
>>>>>>>>>>> >> 2015
>>>>>>>>>>> >> @@ -98,4 +98,7 @@
>>>>>>>>>>> >>  /* LLVM version string */
>>>>>>>>>>> >>  #undef LLVM_VERSION_STRING
>>>>>>>>>>> >>
>>>>>>>>>>> >> +/* Define to enable checks that alter the LLVM C++ ABI */
>>>>>>>>>>> >> +#undef LLVM_ENABLE_ABI_BREAKING_CHECKS
>>>>>>>>>>> >> +
>>>>>>>>>>> >>  #endif
>>>>>>>>>>> >>
>>>>>>>>>>> >>
>>>>>>>>>>> >> _______________________________________________
>>>>>>>>>>> >> llvm-commits mailing list
>>>>>>>>>>> >> llvm-commits at cs.uiuc.edu
>>>>>>>>>>> >> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>>>>>>>>>
>>>>>>>>>> _______________________________________________
>>>>>>>>>> llvm-commits mailing list
>>>>>>>>>> llvm-commits at cs.uiuc.edu
>>>>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list