diff options
author | Eric Fiselier <eric@efcs.ca> | 2015-12-23 06:35:25 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2015-12-23 06:35:25 +0000 |
commit | 1a034d70c8a7409787341234f2f9ae6e18399c1d (patch) | |
tree | b0e167c5f1596527611a25ae998b8a30141f1e51 /test/incomplete_type.sh.cpp | |
parent | f67395cccae6049982ad67530f406624cc0445ac (diff) |
Fix PR25898 - Check for incomplete pointers types in can_catch(...)
git-svn-id: https://llvm.org/svn/llvm-project/libcxxabi/trunk@256322 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/incomplete_type.sh.cpp')
-rw-r--r-- | test/incomplete_type.sh.cpp | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/test/incomplete_type.sh.cpp b/test/incomplete_type.sh.cpp new file mode 100644 index 0000000..111d133 --- /dev/null +++ b/test/incomplete_type.sh.cpp @@ -0,0 +1,83 @@ +//===------------------------- 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 %compile_flags -c %s -o %t.one.o +// RUN: %cxx %compile_flags -c %s -o %t.two.o -DTU_ONE +// RUN: %cxx %link_flags -o %t.exe %t.one.o %t.two.o +// RUN: %t.exe + +#include <stdio.h> +#include <cassert> +#include <typeinfo> + +struct NeverDefined; +void ThrowNeverDefined(); + +struct IncompleteAtThrow; +void ThrowIncomplete(); +std::type_info const& ReturnTypeInfoIncomplete(); + +struct CompleteAtThrow; +void ThrowComplete(); +std::type_info const& ReturnTypeInfoComplete(); + +void ThrowNullptr(); + +#ifndef TU_ONE + +void ThrowNeverDefined() { throw (int NeverDefined::*)nullptr; } + +void ThrowIncomplete() { throw (int IncompleteAtThrow::*)nullptr; } +std::type_info const& ReturnTypeInfoIncomplete() { return typeid(int IncompleteAtThrow::*); } + +struct CompleteAtThrow {}; +void ThrowComplete() { throw (int CompleteAtThrow::*)nullptr; } +std::type_info const& ReturnTypeInfoComplete() { return typeid(int CompleteAtThrow::*); } + +void ThrowNullptr() { throw nullptr; } + +#else + +struct IncompleteAtThrow {}; + +int main() { + assert(ReturnTypeInfoIncomplete() != typeid(int IncompleteAtThrow::*)); + try { + ThrowIncomplete(); + } catch (int IncompleteAtThrow::*) {} + + assert(ReturnTypeInfoComplete() != typeid(int CompleteAtThrow::*)); + try { + ThrowComplete(); + } 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 { + ThrowNeverDefined(); + } catch (int NeverDefined::*) {} +#endif +} +#endif |