Hi Hans, I fixed the problem that caused Nico to revert this. I would like to re-land this in 3.8. This depends on libc++ commit r258217 also landing in 3.8.
@Marshall can you OK this? /Eric On Tue, Jan 19, 2016 at 4:42 PM, Eric Fiselier via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: ericwf > Date: Tue Jan 19 17:42:10 2016 > New Revision: 258249 > > URL: http://llvm.org/viewvc/llvm-project?rev=258249&view=rev > Log: > Recommit r256322: Fix PR25898 - Check for incomplete pointers types in > can_catch(...) > > This patch re-commits r256322 and r256323. They were reverted due to a OS X > test failure. The test failure has been fixed by libc++ commit r258217. > > This patch also adds some additional tests. > > Added: > libcxxabi/trunk/test/incomplete_type.sh.cpp > Modified: > libcxxabi/trunk/src/private_typeinfo.cpp > > Modified: libcxxabi/trunk/src/private_typeinfo.cpp > URL: > http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/private_typeinfo.cpp?rev=258249&r1=258248&r2=258249&view=diff > > ============================================================================== > --- libcxxabi/trunk/src/private_typeinfo.cpp (original) > +++ libcxxabi/trunk/src/private_typeinfo.cpp Tue Jan 19 17:42:10 2016 > @@ -34,9 +34,12 @@ > // > // _LIBCXX_DYNAMIC_FALLBACK is currently off by default. > > + > +#include <string.h> > + > + > #ifdef _LIBCXX_DYNAMIC_FALLBACK > #include "abort_message.h" > -#include <string.h> > #include <sys/syslog.h> > #endif > > @@ -57,31 +60,19 @@ namespace __cxxabiv1 > > #pragma GCC visibility push(hidden) > > -#ifdef _LIBCXX_DYNAMIC_FALLBACK > - > inline > bool > is_equal(const std::type_info* x, const std::type_info* y, bool > use_strcmp) > { > +#ifndef _WIN32 > if (!use_strcmp) > return x == y; > return strcmp(x->name(), y->name()) == 0; > -} > - > -#else // !_LIBCXX_DYNAMIC_FALLBACK > - > -inline > -bool > -is_equal(const std::type_info* x, const std::type_info* y, bool) > -{ > -#ifndef _WIN32 > - return x == y; > #else > return (x == y) || (strcmp(x->name(), y->name()) == 0); > -#endif > +#endif > } > > -#endif // _LIBCXX_DYNAMIC_FALLBACK > > // __shim_type_info > > @@ -351,8 +342,17 @@ bool > __pbase_type_info::can_catch(const __shim_type_info* thrown_type, > void*&) const > { > - return is_equal(this, thrown_type, false) || > - is_equal(thrown_type, &typeid(std::nullptr_t), false); > + if (is_equal(thrown_type, &typeid(std::nullptr_t), false)) return > true; > + bool use_strcmp = this->__flags & (__incomplete_class_mask | > + __incomplete_mask); > + if (!use_strcmp) { > + const __pbase_type_info* thrown_pbase = dynamic_cast<const > __pbase_type_info*>( > + thrown_type); > + if (!thrown_pbase) return false; > + use_strcmp = thrown_pbase->__flags & (__incomplete_class_mask | > + __incomplete_mask); > + } > + return is_equal(this, thrown_type, use_strcmp); > } > > #ifdef __clang__ > > Added: libcxxabi/trunk/test/incomplete_type.sh.cpp > URL: > http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/incomplete_type.sh.cpp?rev=258249&view=auto > > ============================================================================== > --- libcxxabi/trunk/test/incomplete_type.sh.cpp (added) > +++ libcxxabi/trunk/test/incomplete_type.sh.cpp Tue Jan 19 17:42:10 2016 > @@ -0,0 +1,172 @@ > +//===------------------------- incomplete_type.cpp > --------------------------===// > +// > +// The LLVM Compiler Infrastructure > +// > +// This file is dual licensed under the MIT and the University of > Illinois Open > +// Source Licenses. See LICENSE.TXT for details. > +// > > +//===----------------------------------------------------------------------===// > +// http://mentorembedded.github.io/cxx-abi/abi.html#rtti-layout > + > +// Two abi::__pbase_type_info objects can always be compared for equality > +// (i.e. of the types represented) or ordering by comparison of their name > +// NTBS addresses. In addition, unless either or both have either of the > +// incomplete flags set, equality can be tested by comparing the type_info > +// addresses. > + > +// RUN: %cxx %flags %compile_flags -c %s -o %t.one.o > +// RUN: %cxx %flags %compile_flags -c %s -o %t.two.o -DTU_ONE > +// RUN: %cxx %flags %link_flags -o %t.exe %t.one.o %t.two.o > +// RUN: %exec %t.exe > + > +#include <stdio.h> > +#include <cstring> > +#include <cassert> > +#include <typeinfo> > + > +// Check that the addresses of the typeinfo differ but still compare equal > +// via their NTBS. > +inline void > +AssertIncompleteTypeInfoEquals(std::type_info const& LHS, std::type_info > const& RHS) > +{ > + assert(&LHS != &RHS); > + assert(strcmp(LHS.name(), RHS.name()) == 0); > +} > + > +struct NeverDefined; > +void ThrowNeverDefinedMP(); > +std::type_info const& ReturnTypeInfoNeverDefinedMP(); > + > +struct IncompleteAtThrow; > +void ThrowIncompleteMP(); > +void ThrowIncompletePP(); > +void ThrowIncompletePMP(); > +std::type_info const& ReturnTypeInfoIncompleteMP(); > +std::type_info const& ReturnTypeInfoIncompletePP(); > + > +struct CompleteAtThrow; > +void ThrowCompleteMP(); > +void ThrowCompletePP(); > +void ThrowCompletePMP(); > +std::type_info const& ReturnTypeInfoCompleteMP(); > +std::type_info const& ReturnTypeInfoCompletePP(); > + > +void ThrowNullptr(); > + > +#ifndef TU_ONE > + > +void ThrowNeverDefinedMP() { throw (int NeverDefined::*)nullptr; } > +std::type_info const& ReturnTypeInfoNeverDefinedMP() { return typeid(int > NeverDefined::*); } > + > +void ThrowIncompleteMP() { throw (int IncompleteAtThrow::*)nullptr; } > +void ThrowIncompletePP() { throw (IncompleteAtThrow**)nullptr; } > +void ThrowIncompletePMP() { throw (int IncompleteAtThrow::**)nullptr; } > +std::type_info const& ReturnTypeInfoIncompleteMP() { return typeid(int > IncompleteAtThrow::*); } > +std::type_info const& ReturnTypeInfoIncompletePP() { return > typeid(IncompleteAtThrow**); } > + > +struct CompleteAtThrow {}; > +void ThrowCompleteMP() { throw (int CompleteAtThrow::*)nullptr; } > +void ThrowCompletePP() { throw (CompleteAtThrow**)nullptr; } > +void ThrowCompletePMP() { throw (int CompleteAtThrow::**)nullptr; } > +std::type_info const& ReturnTypeInfoCompleteMP() { return typeid(int > CompleteAtThrow::*); } > +std::type_info const& ReturnTypeInfoCompletePP() { return > typeid(CompleteAtThrow**); } > + > +void ThrowNullptr() { throw nullptr; } > + > +#else > + > +struct IncompleteAtThrow {}; > + > +int main() { > + AssertIncompleteTypeInfoEquals(ReturnTypeInfoNeverDefinedMP(), > typeid(int NeverDefined::*)); > + try { > + ThrowNeverDefinedMP(); > + assert(false); > + } catch (int IncompleteAtThrow::*) { > + assert(false); > + } catch (int CompleteAtThrow::*) { > + assert(false); > + } catch (int NeverDefined::*) {} > + AssertIncompleteTypeInfoEquals(ReturnTypeInfoIncompleteMP(), typeid(int > IncompleteAtThrow::*)); > + try { > + ThrowIncompleteMP(); > + assert(false); > + } catch (CompleteAtThrow**) { > + assert(false); > + } catch (int CompleteAtThrow::*) { > + assert(false); > + } catch (IncompleteAtThrow**) { > + assert(false); > + } catch (int IncompleteAtThrow::*) {} > + > + AssertIncompleteTypeInfoEquals(ReturnTypeInfoIncompletePP(), > typeid(IncompleteAtThrow**)); > + try { > + ThrowIncompletePP(); > + assert(false); > + } catch (int IncompleteAtThrow::*) { > + assert(false); > + } catch (IncompleteAtThrow**) {} > + > + try { > + ThrowIncompletePMP(); > + assert(false); > + } catch (int IncompleteAtThrow::*) { > + assert(false); > + } catch (IncompleteAtThrow**) { > + assert(false); > + } catch (int IncompleteAtThrow::**) {} > + > + AssertIncompleteTypeInfoEquals(ReturnTypeInfoCompleteMP(), typeid(int > CompleteAtThrow::*)); > + try { > + ThrowCompleteMP(); > + assert(false); > + } catch (IncompleteAtThrow**) { > + assert(false); > + } catch (int IncompleteAtThrow::*) { > + assert(false); > + } catch (CompleteAtThrow**) { > + assert(false); > + } catch (int CompleteAtThrow::*) {} > + > + AssertIncompleteTypeInfoEquals(ReturnTypeInfoCompletePP(), > typeid(CompleteAtThrow**)); > + try { > + ThrowCompletePP(); > + assert(false); > + } catch (IncompleteAtThrow**) { > + assert(false); > + } catch (int IncompleteAtThrow::*) { > + assert(false); > + } catch (int CompleteAtThrow::*) { > + assert(false); > + } catch (CompleteAtThrow**) {} > + > + try { > + ThrowCompletePMP(); > + assert(false); > + } catch (IncompleteAtThrow**) { > + assert(false); > + } catch (int IncompleteAtThrow::*) { > + assert(false); > + } catch (int CompleteAtThrow::*) { > + assert(false); > + } catch (CompleteAtThrow**) { > + assert(false); > + } catch (int CompleteAtThrow::**) {} > + > +#if __cplusplus >= 201103L > + // Catch nullptr as complete type > + try { > + ThrowNullptr(); > + } catch (int IncompleteAtThrow::*) {} > + > + // Catch nullptr as an incomplete type > + try { > + ThrowNullptr(); > + } catch (int CompleteAtThrow::*) {} > + // Catch nullptr as a type that is never complete. > + try { > + ThrowNullptr(); > + } catch (int NeverDefined::*) {} > +#endif > +} > +#endif > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits