1830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant//===---------------------- catch_class_04.cpp ----------------------------===// 2830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant// 3830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant// The LLVM Compiler Infrastructure 4830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant// 5830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open 6830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant// Source Licenses. See LICENSE.TXT for details. 7830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant// 8830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant//===----------------------------------------------------------------------===// 9830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 10830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant/* 11830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant This test checks that adjustedPtr is correct as there exist offsets in this 12830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant object for the various subobjects, all of which have a unique id_ to 13830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant check against. It also checks that virtual bases work properly 14830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant*/ 15830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 16830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#include <exception> 17830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#include <stdlib.h> 18830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant#include <assert.h> 19830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 20830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantstruct B 21830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{ 22830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant static int count; 23830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant int id_; 24830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant explicit B(int id) : id_(id) {count++;} 25830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant B(const B& a) : id_(a.id_) {count++;} 26830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant ~B() {count--;} 27830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant}; 28830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 29830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantint B::count = 0; 30830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 31830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantstruct C1 32830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant : virtual B 33830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{ 34830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant static int count; 35830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant int id_; 36830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant explicit C1(int id) : B(id-2), id_(id) {count++;} 37830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant C1(const C1& a) : B(a.id_-2), id_(a.id_) {count++;} 38830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant ~C1() {count--;} 39830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant}; 40830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 41830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantint C1::count = 0; 42830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 43830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantstruct C2 44830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant : virtual private B 45830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{ 46830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant static int count; 47830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant int id_; 48830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant explicit C2(int id) : B(id-2), id_(id) {count++;} 49830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant C2(const C2& a) : B(a.id_-2), id_(a.id_) {count++;} 50830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant ~C2() {count--;} 51830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant}; 52830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 53830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantint C2::count = 0; 54830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 55830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantstruct A 56830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant : C1, C2 57830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{ 58830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant static int count; 59830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant int id_; 60830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant explicit A(int id) : C1(id-1), C2(id-2), B(id+3), id_(id) {count++;} 61830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant A(const A& a) : C1(a.id_-1), C2(a.id_-2), B(a.id_+3), id_(a.id_) {count++;} 62830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant ~A() {count--;} 63830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant}; 64830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 65830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantint A::count = 0; 66830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 67830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantvoid f1() 68830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{ 69830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(A::count == 0); 70830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(C1::count == 0); 71830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(C2::count == 0); 72830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(B::count == 0); 73830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant A a(5); 74830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(A::count == 1); 75830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(C1::count == 1); 76830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(C2::count == 1); 77830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(B::count == 1); 78830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 79830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(a.id_ == 5); 80830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(static_cast<C1&>(a).id_ == 4); 81830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(static_cast<C2&>(a).id_ == 3); 82830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(static_cast<B&>(a).id_ == 8); 83830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant throw a; 84830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(false); 85830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant} 86830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 87830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantvoid f2() 88830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{ 89830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant try 90830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 91830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(A::count == 0); 92830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(C1::count == 0); 93830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(C2::count == 0); 94830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(B::count == 0); 95830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant f1(); 96830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(false); 97830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 98830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant catch (const A& a) // can catch A 99830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 100830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(a.id_ == 5); 101830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(static_cast<const C1&>(a).id_ == 4); 102830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(static_cast<const C2&>(a).id_ == 3); 103830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(static_cast<const B&>(a).id_ == 8); 104830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant throw; 105830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 106830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant catch (const C1&) 107830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 108830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(false); 109830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 110830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant catch (const C2&) 111830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 112830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(false); 113830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 114830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant catch (const B&) 115830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 116830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(false); 117830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 118830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant} 119830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 120830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantvoid f3() 121830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{ 122830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant try 123830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 124830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(A::count == 0); 125830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(C1::count == 0); 126830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(C2::count == 0); 127830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(B::count == 0); 128830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant f2(); 129830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(false); 130830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 131830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant catch (const B& a) // can catch B 132830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 133830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(static_cast<const B&>(a).id_ == 8); 134830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant throw; 135830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 136830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant catch (const C1& c1) 137830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 138830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(false); 139830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 140830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant catch (const C2&) 141830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 142830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(false); 143830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 144830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant} 145830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 146830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantvoid f4() 147830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{ 148830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant try 149830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 150830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(A::count == 0); 151830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(C1::count == 0); 152830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(C2::count == 0); 153830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(B::count == 0); 154830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant f3(); 155830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(false); 156830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 157830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant catch (const C2& c2) // can catch C2 158830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 159830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(c2.id_ == 3); 160830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant throw; 161830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 162830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant catch (const B& a) // can not catch B (ambiguous base) 163830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 164830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(false); 165830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 166830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant catch (const C1&) 167830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 168830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(false); 169830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 170830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant} 171830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 172830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantvoid f5() 173830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{ 174830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant try 175830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 176830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(A::count == 0); 177830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(C1::count == 0); 178830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(C2::count == 0); 179830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(B::count == 0); 180830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant f4(); 181830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(false); 182830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 183830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant catch (const C1& c1) // can catch C1 184830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 185830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(c1.id_ == 4); 186830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(static_cast<const B&>(c1).id_ == 8); 187830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant throw; 188830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 189830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant catch (const B& a) 190830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 191830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(false); 192830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 193830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant catch (const C2&) 194830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 195830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(false); 196830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 197830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant} 198830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant 199830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnantint main() 200830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant{ 201830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant try 202830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 203830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant f5(); 204830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(false); 205830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 206830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant catch (...) 207830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant { 208830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant } 209830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(A::count == 0); 210830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(C1::count == 0); 211830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(C2::count == 0); 212830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant assert(B::count == 0); 213830713c63ecaf0a5d7690db92f83f2741754de15Howard Hinnant} 214