1 //===------------------------- incomplete_type.cpp --------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // http://mentorembedded.github.io/cxx-abi/abi.html#rtti-layout 10 11 // Two abi::__pbase_type_info objects can always be compared for equality 12 // (i.e. of the types represented) or ordering by comparison of their name 13 // NTBS addresses. In addition, unless either or both have either of the 14 // incomplete flags set, equality can be tested by comparing the type_info 15 // addresses. 16 17 // RUN: %cxx %flags %compile_flags -c %s -o %t.one.o 18 // RUN: %cxx %flags %compile_flags -c %s -o %t.two.o -DTU_ONE 19 // RUN: %cxx %flags %link_flags -o %t.exe %t.one.o %t.two.o 20 // RUN: %t.exe 21 22 #include <stdio.h> 23 #include <cassert> 24 #include <typeinfo> 25 26 struct NeverDefined; 27 void ThrowNeverDefinedMP(); 28 29 struct IncompleteAtThrow; 30 void ThrowIncompleteMP(); 31 void ThrowIncompletePP(); 32 void ThrowIncompletePMP(); 33 std::type_info const& ReturnTypeInfoIncompleteMP(); 34 std::type_info const& ReturnTypeInfoIncompletePP(); 35 36 struct CompleteAtThrow; 37 void ThrowCompleteMP(); 38 void ThrowCompletePP(); 39 void ThrowCompletePMP(); 40 std::type_info const& ReturnTypeInfoCompleteMP(); 41 std::type_info const& ReturnTypeInfoCompletePP(); 42 43 void ThrowNullptr(); 44 45 #ifndef TU_ONE 46 47 void ThrowNeverDefinedMP() { throw (int NeverDefined::*)nullptr; } 48 49 void ThrowIncompleteMP() { throw (int IncompleteAtThrow::*)nullptr; } 50 void ThrowIncompletePP() { throw (IncompleteAtThrow**)nullptr; } 51 void ThrowIncompletePMP() { throw (int IncompleteAtThrow::**)nullptr; } 52 53 std::type_info const& ReturnTypeInfoIncompleteMP() { return typeid(int IncompleteAtThrow::*); } 54 std::type_info const& ReturnTypeInfoIncompletePP() { return typeid(IncompleteAtThrow**); } 55 56 struct CompleteAtThrow {}; 57 void ThrowCompleteMP() { throw (int CompleteAtThrow::*)nullptr; } 58 void ThrowCompletePP() { throw (CompleteAtThrow**)nullptr; } 59 void ThrowCompletePMP() { throw (int CompleteAtThrow::**)nullptr; } 60 61 std::type_info const& ReturnTypeInfoCompleteMP() { return typeid(int CompleteAtThrow::*); } 62 std::type_info const& ReturnTypeInfoCompletePP() { return typeid(CompleteAtThrow**); } 63 64 void ThrowNullptr() { throw nullptr; } 65 66 #else 67 68 struct IncompleteAtThrow {}; 69 70 int main() { 71 try { 72 ThrowNeverDefinedMP(); 73 assert(false); 74 } catch (int IncompleteAtThrow::*) { 75 assert(false); 76 } catch (int CompleteAtThrow::*) { 77 assert(false); 78 } catch (int NeverDefined::*) {} 79 80 assert(ReturnTypeInfoIncompleteMP() != typeid(int IncompleteAtThrow::*)); 81 try { 82 ThrowIncompleteMP(); 83 assert(false); 84 } catch (CompleteAtThrow**) { 85 assert(false); 86 } catch (int CompleteAtThrow::*) { 87 assert(false); 88 } catch (IncompleteAtThrow**) { 89 assert(false); 90 } catch (int IncompleteAtThrow::*) {} 91 92 assert(ReturnTypeInfoIncompletePP() != typeid(IncompleteAtThrow**)); 93 try { 94 ThrowIncompletePP(); 95 assert(false); 96 } catch (int IncompleteAtThrow::*) { 97 assert(false); 98 } catch (IncompleteAtThrow**) {} 99 100 try { 101 ThrowIncompletePMP(); 102 assert(false); 103 } catch (int IncompleteAtThrow::*) { 104 assert(false); 105 } catch (IncompleteAtThrow**) { 106 assert(false); 107 } catch (int IncompleteAtThrow::**) {} 108 109 assert(ReturnTypeInfoCompleteMP() != typeid(int CompleteAtThrow::*)); 110 try { 111 ThrowCompleteMP(); 112 assert(false); 113 } catch (IncompleteAtThrow**) { 114 assert(false); 115 } catch (int IncompleteAtThrow::*) { 116 assert(false); 117 } catch (CompleteAtThrow**) { 118 assert(false); 119 } catch (int CompleteAtThrow::*) {} 120 121 assert(ReturnTypeInfoCompletePP() != typeid(CompleteAtThrow**)); 122 try { 123 ThrowCompletePP(); 124 assert(false); 125 } catch (IncompleteAtThrow**) { 126 assert(false); 127 } catch (int IncompleteAtThrow::*) { 128 assert(false); 129 } catch (int CompleteAtThrow::*) { 130 assert(false); 131 } catch (CompleteAtThrow**) {} 132 133 try { 134 ThrowCompletePMP(); 135 assert(false); 136 } catch (IncompleteAtThrow**) { 137 assert(false); 138 } catch (int IncompleteAtThrow::*) { 139 assert(false); 140 } catch (int CompleteAtThrow::*) { 141 assert(false); 142 } catch (CompleteAtThrow**) { 143 assert(false); 144 } catch (int CompleteAtThrow::**) {} 145 146 #if __cplusplus >= 201103L 147 // Catch nullptr as complete type 148 try { 149 ThrowNullptr(); 150 } catch (int IncompleteAtThrow::*) {} 151 152 // Catch nullptr as an incomplete type 153 try { 154 ThrowNullptr(); 155 } catch (int CompleteAtThrow::*) {} 156 // Catch nullptr as a type that is never complete. 157 try { 158 ThrowNullptr(); 159 } catch (int NeverDefined::*) {} 160 #endif 161 } 162 #endif 163