Reid Kleckner | 2eab2bd | 2014-02-27 00:22:40 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -triple i686-linux-gnu %s -emit-llvm -o - | FileCheck %s |
Reid Kleckner | c497f1d | 2014-02-27 00:03:39 +0000 | [diff] [blame] | 2 | |
| 3 | class A { |
| 4 | // append has to have the same prototype as fn1 to tickle the bug. |
| 5 | void (*append)(A *); |
| 6 | }; |
| 7 | |
| 8 | class B {}; |
| 9 | class D; |
| 10 | |
| 11 | // C has to be non-C++98 POD with available tail padding, making the LLVM base |
| 12 | // type differ from the complete LLVM type. |
| 13 | class C { |
| 14 | // This member creates a circular LLVM type reference to %class.D. |
| 15 | D *m_group; |
| 16 | B changeListeners; |
| 17 | }; |
| 18 | class D : C {}; |
| 19 | |
| 20 | void fn1(A *p1) { |
| 21 | } |
| 22 | |
| 23 | void |
| 24 | fn2(C *) { |
| 25 | } |
| 26 | |
| 27 | // We end up using an opaque type for 'append' to avoid circular references. |
| 28 | // CHECK: %class.A = type { {}* } |
David Majnemer | bb51300 | 2014-09-28 06:39:30 +0000 | [diff] [blame] | 29 | // CHECK: %class.C = type <{ %class.D*, %class.B, [3 x i8] }> |
Reid Kleckner | c497f1d | 2014-02-27 00:03:39 +0000 | [diff] [blame] | 30 | // CHECK: %class.D = type { %class.C.base, [3 x i8] } |
| 31 | // CHECK: %class.C.base = type <{ %class.D*, %class.B }> |
| 32 | // CHECK: %class.B = type { i8 } |