Skip to content

Commit 26199f0

Browse files
committed
[CIR][Tests] Add 10 minimal crash test cases from LLVM/Clang builds
Added crash reproducers from building LLVM/Clang with ClangIR, reduced using creduce. Tests covering various C++ features and CIR implementation gaps: Control flow and destructors: - conditional-return-destructors.cpp: Multiple destructors with conditional return - static-local-destructor.cpp: Static local with non-trivial destructor Template metaprogramming: - constexpr-complex-template-metaprog.cpp: Complex template metaprogramming with __builtin_is_constant_evaluated - dyncast-assertion.cpp: Aggregate member initialization with template parameters Static locals and globals: - static-local-used-attribute.cpp: Static local with __used__ attribute - static-init-recursion.cpp: Static local with recursive initialization - virtual-method-global-dtor.cpp: Global with virtual method and destructor Inheritance: - virtual-base-constructor.cpp: Virtual base class constructor calls Function types: - function-ref-pointer-params.cpp: Function reference with multi-level pointer indirection Creduce artifacts: - template-syntax-error.cpp: Malformed creduce artifact documenting reduction process limitations All tests use XFAIL except template-syntax-error.cpp which uses FileCheck. These are minimal reproductions from creduce processing of crash reproducers collected during LLVM/Clang toolchain builds with ClangIR enabled.
1 parent c75b032 commit 26199f0

10 files changed

+226
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
//
3+
// XFAIL: *
4+
//
5+
// Issue: Conditional return with multiple destructors in different scopes
6+
//
7+
// When a function has:
8+
// - Multiple local variables with destructors in different scopes
9+
// - A conditional return statement
10+
// - Return value containing a member with a destructor
11+
// CIR fails to properly manage the cleanup scope stack for all destructors
12+
// that need to run on each exit path.
13+
14+
class a {
15+
public:
16+
~a();
17+
};
18+
struct b {
19+
a c;
20+
};
21+
b fn1(bool e) {
22+
a d;
23+
b f;
24+
if (e) {
25+
a d;
26+
return f;
27+
}
28+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
//
3+
// XFAIL: *
4+
//
5+
// Issue: Complex template metaprogramming with __builtin_is_constant_evaluated
6+
//
7+
// When using advanced template metaprogramming involving:
8+
// - Template aliases with variadic templates
9+
// - decltype expressions in template parameters
10+
// - __builtin_is_constant_evaluated() in constexpr context
11+
// - Complex member function template instantiation chains
12+
// CIR fails during constant expression evaluation or template instantiation.
13+
14+
template <typename a> struct b {
15+
typedef a c;
16+
};
17+
template <typename a> class d {
18+
public:
19+
typedef a c;
20+
};
21+
template <typename a> using ad = d<a>::c;
22+
template <typename...> struct g;
23+
struct i {
24+
template <typename, typename e> using f = decltype(e());
25+
template <typename a, typename e> static b<ad<f<a, e>>> k(int);
26+
};
27+
template <typename h> struct l : i {
28+
using c = decltype(k<int, h>(0));
29+
};
30+
template <typename j, typename h> struct g<j, h> : l<h>::c {};
31+
template <typename... a> using ah = g<a...>::c;
32+
class m;
33+
class n {
34+
void o(m &) const;
35+
};
36+
template <typename = void> struct al;
37+
template <typename a> struct al<a *> {
38+
void operator()(a *, a *) {
39+
if (__builtin_is_constant_evaluated())
40+
;
41+
}
42+
};
43+
template <> struct al<> {
44+
template <typename a, typename e> void operator()(a p, e *p2) {
45+
al<ah<a, e *>>{}(p, p2);
46+
}
47+
};
48+
class q {
49+
void *aq;
50+
void *ar;
51+
template <class au> void r(au, int, long) {
52+
al a;
53+
a(aq, ar);
54+
}
55+
};
56+
template <typename> class s : q {
57+
int az;
58+
long ba;
59+
60+
public:
61+
void t() { r(this, az, ba); }
62+
};
63+
class m {
64+
s<int> bd;
65+
66+
public:
67+
void m_fn5() { bd.t(); }
68+
};
69+
void n::o(m &p) const { p.m_fn5(); }
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
//
3+
// XFAIL: *
4+
//
5+
// Crash from LLVM build with ClangIR. Creduced from llvm::formLCSSAForInstructions
6+
//
7+
// Issue: dyn_cast assertion failure
8+
// Location: Casting.h:644
9+
// Error: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"`
10+
//
11+
// When initializing aggregate members in a constructor with template parameters,
12+
// CIR attempts an invalid cast operation.
13+
14+
struct a {
15+
template <typename b, typename c> a(b, c);
16+
};
17+
class d {
18+
a e;
19+
20+
public:
21+
d(int) : e(0, 0) {}
22+
};
23+
void f() { static d g(0); }
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
//
3+
// XFAIL: *
4+
//
5+
// Issue: Function reference parameter with multiple pointer indirections
6+
//
7+
// When passing a reference to a function type as a parameter, where the function
8+
// signature contains multiple levels of pointer indirection in its parameters,
9+
// CIR fails during type lowering or function call code generation.
10+
11+
const char *a;
12+
unsigned b;
13+
unsigned char c;
14+
void d(int (&e)(unsigned char *, unsigned *, char, const char **)) {
15+
e(&c, &b, 0, &a);
16+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
//
3+
// XFAIL: *
4+
//
5+
// Issue: Static local variable with recursive initialization
6+
//
7+
// When a static local variable is initialized by calling the function that
8+
// contains it, CIR fails during initialization code generation. This pattern
9+
// requires special guard variable handling to prevent infinite recursion at
10+
// runtime and detect the recursion during initialization.
11+
12+
int a() { static int b = a(); }
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
//
3+
// XFAIL: *
4+
//
5+
// Crash from LLVM build with ClangIR
6+
//
7+
// Issue: Static local variable with destructor
8+
// Location: CIRGenDecl.cpp:616
9+
// Error: UNREACHABLE: NYI
10+
//
11+
// When a static local variable has a non-trivial destructor, CIR must
12+
// register the destructor to run at program exit. This is not yet implemented.
13+
14+
class a {
15+
public:
16+
~a();
17+
};
18+
void b() { static a c; }
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
//
3+
// XFAIL: *
4+
//
5+
// Issue: Static local variable with __used__ attribute
6+
//
7+
// When a function contains a static local variable with the __used__ attribute,
8+
// CIR fails to properly handle the attribute during code generation.
9+
// The __used__ attribute prevents the variable from being optimized away even
10+
// if it appears unused.
11+
12+
void a() { __attribute__((__used__)) static void *b; }
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: not %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir 2>&1 | FileCheck %s
2+
//
3+
// This test captures malformed C++ that creduce generated.
4+
// It documents that our crash reproducer reduction process needs improvement.
5+
//
6+
// CHECK: error: expected
7+
//
8+
// Issue: Creduce produced syntactically invalid C++ during reduction
9+
//
10+
// This is a creduce artifact showing incomplete template syntax.
11+
// The original crash involved template metaprogramming, but creduce
12+
// reduced it too aggressively, producing invalid syntax.
13+
14+
template <a> b() struct c {
15+
c::b::
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
//
3+
// XFAIL: *
4+
//
5+
// Issue: Virtual base class constructor call
6+
//
7+
// When a derived class constructor explicitly calls a virtual base class constructor,
8+
// CIR fails during code generation. Virtual base class constructors require special
9+
// handling as they are initialized by the most derived class, not intermediate classes.
10+
11+
class a {};
12+
class b : virtual a {};
13+
class c : b {
14+
public:
15+
c() : b() {}
16+
};
17+
void d() { c e; }
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
2+
//
3+
// XFAIL: *
4+
//
5+
// Issue: Global variable with virtual method and destructor
6+
//
7+
// When a global variable has both:
8+
// - A non-trivial destructor requiring registration for cleanup at program exit
9+
// - A virtual method requiring vtable generation
10+
// CIR fails to properly coordinate the vtable setup with destructor registration.
11+
12+
class a {
13+
public:
14+
~a();
15+
virtual char b();
16+
} c;

0 commit comments

Comments
 (0)