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

Daniel Sanders Daniel.Sanders at imgtec.com
Wed May 13 02:35:23 PDT 2015


Hi,

My main concern was that it looked like LLVM_ABI_BREAKING_CHECKS was intended to pass information to the users of llvm-config.h and LLVMConfig.cmake and the original approach only passed it through llvm-config.h. Projects like clang could potentially obtain a different value to the one used to configure LLVM. I've no strong objection to doing both approaches together.

> -----Original Message-----
> From: Eric Fiselier [mailto:eric at efcs.ca]
> Sent: 12 May 2015 23:55
> To: Sanjoy Das
> Cc: Daniel Sanders; llvm-commits at cs.uiuc.edu
> Subject: Re: [llvm] r233310 - [ADT][CMake][AutoConf] Fail-fast iterators for
> DenseMap
> 
> 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