199 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/*10 This test checks that adjustedPtr is correct as there exist offsets in this11 object for the various subobjects, all of which have a unique id_ to12 check against.13*/14 15// UNSUPPORTED: no-exceptions16 17// Compilers emit warnings about exceptions of type 'Child' being caught by18// an earlier handler of type 'Base'. Congrats, you've just diagnosed the19// behavior under test.20// ADDITIONAL_COMPILE_FLAGS: -Wno-exceptions21 22#include <exception>23#include <stdlib.h>24#include <assert.h>25 26struct B27{28 static int count;29 int id_;30 explicit B(int id) : id_(id) {count++;}31 B(const B& a) : id_(a.id_) {count++;}32 ~B() {count--;}33};34 35int B::count = 0;36 37struct C138 : B39{40 static int count;41 int id_;42 explicit C1(int id) : B(id-2), id_(id) {count++;}43 C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;}44 ~C1() {count--;}45};46 47int C1::count = 0;48 49struct C250 : B51{52 static int count;53 int id_;54 explicit C2(int id) : B(id-2), id_(id) {count++;}55 C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;}56 ~C2() {count--;}57};58 59int C2::count = 0;60 61struct A62 : C1, C263{64 static int count;65 int id_;66 explicit A(int id) : C1(id-1), C2(id-2), id_(id) {count++;}67 A(const A& a) : C1(a.id_-1), C2(a.id_-2), id_(a.id_) {count++;}68 ~A() {count--;}69};70 71int A::count = 0;72 73void f1()74{75 assert(A::count == 0);76 assert(C1::count == 0);77 assert(C2::count == 0);78 assert(B::count == 0);79 A a(5);80 assert(A::count == 1);81 assert(C1::count == 1);82 assert(C2::count == 1);83 assert(B::count == 2);84 85 assert(a.id_ == 5);86 assert(static_cast<C1&>(a).id_ == 4);87 assert(static_cast<C2&>(a).id_ == 3);88 assert(static_cast<B&>(static_cast<C1&>(a)).id_ == 2);89 assert(static_cast<B&>(static_cast<C2&>(a)).id_ == 1);90 throw a;91 assert(false);92}93 94void f2()95{96 try97 {98 assert(A::count == 0);99 assert(C1::count == 0);100 assert(C2::count == 0);101 assert(B::count == 0);102 f1();103 assert(false);104 }105 catch (const A& a) // can catch A106 {107 assert(a.id_ == 5);108 assert(static_cast<const C1&>(a).id_ == 4);109 assert(static_cast<const C2&>(a).id_ == 3);110 assert(static_cast<const B&>(static_cast<const C1&>(a)).id_ == 2);111 assert(static_cast<const B&>(static_cast<const C2&>(a)).id_ == 1);112 throw;113 }114 catch (const C1&)115 {116 assert(false);117 }118 catch (const C2&)119 {120 assert(false);121 }122 catch (const B&)123 {124 assert(false);125 }126}127 128void f3()129{130 try131 {132 assert(A::count == 0);133 assert(C1::count == 0);134 assert(C2::count == 0);135 assert(B::count == 0);136 f2();137 assert(false);138 }139 catch (const B& a) // can not catch B (ambiguous base)140 {141 assert(false);142 }143 catch (const C1& c1) // can catch C1144 {145 assert(c1.id_ == 4);146 assert(static_cast<const B&>(c1).id_ == 2);147 throw;148 }149 catch (const C2&)150 {151 assert(false);152 }153}154 155void f4()156{157 try158 {159 assert(A::count == 0);160 assert(C1::count == 0);161 assert(C2::count == 0);162 assert(B::count == 0);163 f3();164 assert(false);165 }166 catch (const B& a) // can not catch B (ambiguous base)167 {168 assert(false);169 }170 catch (const C2& c2) // can catch C2171 {172 assert(c2.id_ == 3);173 assert(static_cast<const B&>(c2).id_ == 1);174 throw;175 }176 catch (const C1&)177 {178 assert(false);179 }180}181 182int main(int, char**)183{184 try185 {186 f4();187 assert(false);188 }189 catch (...)190 {191 }192 assert(A::count == 0);193 assert(C1::count == 0);194 assert(C2::count == 0);195 assert(B::count == 0);196 197 return 0;198}199