brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.8 KiB · 1bd4277 Raw
188 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9//  This test case checks specifically the cases under bullet 3.3:10//11//  C++ ABI 15.3:12//  A handler is a match for an exception object of type E if13//     *  The handler is of type cv T or cv T& and E and T are the same type14//        (ignoring the top-level cv-qualifiers), or15//     *  the handler is of type cv T or cv T& and T is an unambiguous base16//        class of E, or17//  >  *  the handler is of type cv1 T* cv2 and E is a pointer type that can   <18//  >     be converted to the type of the handler by either or both of         <19//  >       o  a standard pointer conversion (4.10 [conv.ptr]) not involving   <20//  >          conversions to private or protected or ambiguous classes        <21//  >       o  a qualification conversion                                      <22//     *  the handler is a pointer or pointer to member type and E is23//        std::nullptr_t24//25//===----------------------------------------------------------------------===//26 27// UNSUPPORTED: no-exceptions28 29// This test requires the fix to https://github.com/llvm/llvm-project/issues/64953,30// which landed in d5f84e6 and is in the libc++abi built library.31// XFAIL: using-built-library-before-llvm-1832 33#include <exception>34#include <stdlib.h>35#include <assert.h>36#include <stdio.h>37 38struct Base {39  int b;40};41struct Base2 {42  int b;43};44struct Derived1 : Base {45  int b;46};47struct Derived2 : Base {48  int b;49};50struct Derived3 : Base2 {51  int b;52};53struct Private : private Base {54  int b;55};56struct Protected : protected Base {57  int b;58};59struct Virtual1 : virtual Base {60  int b;61};62struct Virtual2 : virtual Base {63  int b;64};65 66struct Ambiguous1 : Derived1, Derived2 {67  int b;68};69struct Ambiguous2 : Derived1, Private {70  int b;71};72struct Ambiguous3 : Derived1, Protected {73  int b;74};75 76struct NoPublic1 : Private, Base2 {77  int b;78};79struct NoPublic2 : Protected, Base2 {80  int b;81};82 83struct Catchable1 : Derived3, Derived1 {84  int b;85};86struct Catchable2 : Virtual1, Virtual2 {87  int b;88};89struct Catchable3 : virtual Base, Virtual2 {90  int b;91};92 93// Check that, when we have a null pointer-to-object that we catch a nullptr.94template <typename T // Handler type95          ,96          typename E // Thrown exception type97          >98void assert_catches() {99  try {100    throw static_cast<E>(0);101    printf("%s\n", __PRETTY_FUNCTION__);102    assert(false && "Statements after throw must be unreachable");103  } catch (T t) {104    assert(t == nullptr);105    return;106  } catch (...) {107    printf("%s\n", __PRETTY_FUNCTION__);108    assert(false && "Should not have entered catch-all");109  }110 111  printf("%s\n", __PRETTY_FUNCTION__);112  assert(false && "The catch should have returned");113}114 115template <typename T // Handler type116          ,117          typename E // Thrown exception type118          >119void assert_cannot_catch() {120  try {121    throw static_cast<E>(0);122    printf("%s\n", __PRETTY_FUNCTION__);123    assert(false && "Statements after throw must be unreachable");124  } catch (T t) {125    printf("%s\n", __PRETTY_FUNCTION__);126    assert(false && "Should not have entered the catch");127  } catch (...) {128    assert(true);129    return;130  }131 132  printf("%s\n", __PRETTY_FUNCTION__);133  assert(false && "The catch-all should have returned");134}135 136// Check that when we have a pointer-to-actual-object we, in fact, get the137// adjusted pointer to the base class.138template <typename T // Handler type139          ,140          typename O // Object type141          >142void assert_catches_bp() {143  O* o = new (O);144  try {145    throw o;146    printf("%s\n", __PRETTY_FUNCTION__);147    assert(false && "Statements after throw must be unreachable");148  } catch (T t) {149    assert(t == static_cast<T>(o));150    //__builtin_printf("o = %p t = %p\n", o, t);151    delete o;152    return;153  } catch (...) {154    printf("%s\n", __PRETTY_FUNCTION__);155    assert(false && "Should not have entered catch-all");156  }157 158  printf("%s\n", __PRETTY_FUNCTION__);159  assert(false && "The catch should have returned");160}161 162void f1() {163  assert_catches<Base*, Catchable1*>();164  assert_catches<Base*, Catchable2*>();165  assert_catches<Base*, Catchable3*>();166}167 168void f2() {169  assert_cannot_catch<Base*, Ambiguous1*>();170  assert_cannot_catch<Base*, Ambiguous2*>();171  assert_cannot_catch<Base*, Ambiguous3*>();172  assert_cannot_catch<Base*, NoPublic1*>();173  assert_cannot_catch<Base*, NoPublic2*>();174}175 176void f3() {177  assert_catches_bp<Base*, Catchable1>();178  assert_catches_bp<Base*, Catchable2>();179  assert_catches_bp<Base*, Catchable3>();180}181 182int main(int, char**) {183  f1();184  f2();185  f3();186  return 0;187}188