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

Eric Fiselier eric at efcs.ca
Tue May 12 13:56:01 PDT 2015


> 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.

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