Home | History | Annotate | Download | only in test
      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 // UNSUPPORTED: libcxxabi-no-exceptions
     18 
     19 // NOTE: Pass -lc++abi explicitly and before -lc++ so that -lc++ doesn't drag
     20 // in the system libc++abi installation on OS X. (DYLD_LIBRARY_PATH is ignored
     21 // for shell tests because of Apple security features).
     22 
     23 // RUN: %cxx %flags %compile_flags -c %s -o %t.one.o
     24 // RUN: %cxx %flags %compile_flags -c %s -o %t.two.o -DTU_ONE
     25 // RUN: %cxx %flags %t.one.o %t.two.o -lc++abi %link_flags -o %t.exe
     26 // RUN: %t.exe
     27 
     28 #include <stdio.h>
     29 #include <cstring>
     30 #include <cassert>
     31 #include <typeinfo>
     32 
     33 // Check that the addresses of the typeinfo differ but still compare equal
     34 // via their NTBS.
     35 inline void
     36 AssertIncompleteTypeInfoEquals(std::type_info const& LHS, std::type_info const& RHS)
     37 {
     38   assert(&LHS != &RHS);
     39   assert(strcmp(LHS.name(), RHS.name()) == 0);
     40 }
     41 
     42 struct NeverDefined;
     43 void ThrowNeverDefinedMP();
     44 std::type_info const& ReturnTypeInfoNeverDefinedMP();
     45 
     46 struct IncompleteAtThrow;
     47 void ThrowIncompleteMP();
     48 void ThrowIncompletePP();
     49 void ThrowIncompletePMP();
     50 std::type_info const& ReturnTypeInfoIncompleteMP();
     51 std::type_info const& ReturnTypeInfoIncompletePP();
     52 
     53 struct CompleteAtThrow;
     54 void ThrowCompleteMP();
     55 void ThrowCompletePP();
     56 void ThrowCompletePMP();
     57 std::type_info const& ReturnTypeInfoCompleteMP();
     58 std::type_info const& ReturnTypeInfoCompletePP();
     59 
     60 void ThrowNullptr();
     61 
     62 #ifndef TU_ONE
     63 
     64 void ThrowNeverDefinedMP() { throw (int NeverDefined::*)nullptr; }
     65 std::type_info const& ReturnTypeInfoNeverDefinedMP() { return typeid(int NeverDefined::*); }
     66 
     67 void ThrowIncompleteMP() { throw (int IncompleteAtThrow::*)nullptr; }
     68 void ThrowIncompletePP() { throw (IncompleteAtThrow**)nullptr; }
     69 void ThrowIncompletePMP() { throw (int IncompleteAtThrow::**)nullptr; }
     70 std::type_info const& ReturnTypeInfoIncompleteMP() { return typeid(int IncompleteAtThrow::*); }
     71 std::type_info const& ReturnTypeInfoIncompletePP() { return typeid(IncompleteAtThrow**); }
     72 
     73 struct CompleteAtThrow {};
     74 void ThrowCompleteMP() { throw (int CompleteAtThrow::*)nullptr; }
     75 void ThrowCompletePP() { throw (CompleteAtThrow**)nullptr; }
     76 void ThrowCompletePMP() { throw (int CompleteAtThrow::**)nullptr; }
     77 std::type_info const& ReturnTypeInfoCompleteMP() { return typeid(int CompleteAtThrow::*); }
     78 std::type_info const& ReturnTypeInfoCompletePP() { return typeid(CompleteAtThrow**); }
     79 
     80 void ThrowNullptr() { throw nullptr; }
     81 
     82 #else
     83 
     84 struct IncompleteAtThrow {};
     85 
     86 int main() {
     87   AssertIncompleteTypeInfoEquals(ReturnTypeInfoNeverDefinedMP(), typeid(int NeverDefined::*));
     88   try {
     89     ThrowNeverDefinedMP();
     90     assert(false);
     91   } catch (int IncompleteAtThrow::*) {
     92     assert(false);
     93   } catch (int CompleteAtThrow::*) {
     94     assert(false);
     95   } catch (int NeverDefined::*p) {
     96     assert(!p);
     97   }
     98   catch(...) { assert(!"FAIL: Didn't catch NeverDefined::*" ); }
     99 
    100   AssertIncompleteTypeInfoEquals(ReturnTypeInfoIncompleteMP(), typeid(int IncompleteAtThrow::*));
    101   try {
    102     ThrowIncompleteMP();
    103     assert(false);
    104   } catch (CompleteAtThrow**) {
    105     assert(false);
    106   } catch (int CompleteAtThrow::*) {
    107     assert(false);
    108   } catch (IncompleteAtThrow**) {
    109     assert(false);
    110   } catch (int IncompleteAtThrow::*p) {
    111     assert(!p);
    112   }
    113   catch(...) { assert(!"FAIL: Didn't catch IncompleteAtThrow::*" ); }
    114 
    115   AssertIncompleteTypeInfoEquals(ReturnTypeInfoIncompletePP(), typeid(IncompleteAtThrow**));
    116   try {
    117     ThrowIncompletePP();
    118     assert(false);
    119   } catch (int IncompleteAtThrow::*) {
    120     assert(false);
    121   } catch (IncompleteAtThrow** p) {
    122     assert(!p);
    123   }
    124   catch(...) { assert(!"FAIL: Didn't catch IncompleteAtThrow**" ); }
    125 
    126   try {
    127     ThrowIncompletePMP();
    128     assert(false);
    129   } catch (int IncompleteAtThrow::*) {
    130     assert(false);
    131   } catch (IncompleteAtThrow**) {
    132     assert(false);
    133   } catch (int IncompleteAtThrow::**p) {
    134     assert(!p);
    135   }
    136   catch(...) { assert(!"FAIL: Didn't catch IncompleteAtThrow::**" ); }
    137 
    138   AssertIncompleteTypeInfoEquals(ReturnTypeInfoCompleteMP(), typeid(int CompleteAtThrow::*));
    139   try {
    140     ThrowCompleteMP();
    141     assert(false);
    142   } catch (IncompleteAtThrow**) {
    143     assert(false);
    144   } catch (int IncompleteAtThrow::*) {
    145     assert(false);
    146   } catch (CompleteAtThrow**) {
    147     assert(false);
    148   } catch (int CompleteAtThrow::*p) {
    149     assert(!p);
    150   }
    151   catch(...) { assert(!"FAIL: Didn't catch CompleteAtThrow::" ); }
    152 
    153   AssertIncompleteTypeInfoEquals(ReturnTypeInfoCompletePP(), typeid(CompleteAtThrow**));
    154   try {
    155     ThrowCompletePP();
    156     assert(false);
    157   } catch (IncompleteAtThrow**) {
    158     assert(false);
    159   } catch (int IncompleteAtThrow::*) {
    160     assert(false);
    161   } catch (int CompleteAtThrow::*) {
    162     assert(false);
    163   } catch (CompleteAtThrow**p) {
    164     assert(!p);
    165   }
    166   catch(...) { assert(!"FAIL: Didn't catch CompleteAtThrow**" ); }
    167 
    168   try {
    169     ThrowCompletePMP();
    170     assert(false);
    171   } catch (IncompleteAtThrow**) {
    172     assert(false);
    173   } catch (int IncompleteAtThrow::*) {
    174     assert(false);
    175   } catch (int CompleteAtThrow::*) {
    176     assert(false);
    177   } catch (CompleteAtThrow**) {
    178     assert(false);
    179   } catch (int CompleteAtThrow::**p) {
    180     assert(!p);
    181   }
    182   catch(...) { assert(!"FAIL: Didn't catch CompleteAtThrow::**" ); }
    183 
    184 #if __cplusplus >= 201103L
    185   // Catch nullptr as complete type
    186   try {
    187     ThrowNullptr();
    188   } catch (int IncompleteAtThrow::*p) {
    189     assert(!p);
    190   }
    191   catch(...) { assert(!"FAIL: Didn't catch nullptr as IncompleteAtThrow::*" ); }
    192 
    193   // Catch nullptr as an incomplete type
    194   try {
    195     ThrowNullptr();
    196   } catch (int CompleteAtThrow::*p) {
    197     assert(!p);
    198   }
    199   catch(...) { assert(!"FAIL: Didn't catch nullptr as CompleteAtThrow::*" ); }
    200 
    201   // Catch nullptr as a type that is never complete.
    202   try {
    203     ThrowNullptr();
    204   } catch (int NeverDefined::*p) {
    205     assert(!p);
    206   }
    207   catch(...) { assert(!"FAIL: Didn't catch nullptr as NeverDefined::*" ); }
    208 
    209 #endif
    210 }
    211 #endif
    212