mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-09-25 16:37:56 +03:00
Class members are destroyed in the reverse order of their declaration (like C++). The previous code destroyed members in declaration order, which caused a use-after-free in Rance 9's T_Map class. Added a test to verify the reverse destruction order.
94 lines
1.7 KiB
C
Executable File
94 lines
1.7 KiB
C
Executable File
// -*-mode: C; coding: sjis; -*-
|
|
|
|
struct inner_struct {
|
|
int a;
|
|
};
|
|
|
|
struct my_struct {
|
|
int a;
|
|
int b;
|
|
string s;
|
|
inner_struct inner;
|
|
};
|
|
|
|
struct my_class_inner {
|
|
int a;
|
|
my_class_inner() {
|
|
a = 99;
|
|
}
|
|
};
|
|
|
|
struct my_class {
|
|
int a;
|
|
int b;
|
|
my_class_inner inner;
|
|
|
|
my_class() {
|
|
a = 42;
|
|
b = inner.a + 1;
|
|
}
|
|
|
|
void set_a(int a_);
|
|
};
|
|
|
|
void my_class::set_a(int a_) {
|
|
a = a_;
|
|
}
|
|
|
|
string dtor_order;
|
|
|
|
struct dtor_a {
|
|
~dtor_a() { dtor_order += "a"; }
|
|
};
|
|
|
|
struct dtor_b {
|
|
~dtor_b() { dtor_order += "b"; }
|
|
};
|
|
|
|
struct dtor_c {
|
|
~dtor_c() { dtor_order += "c"; }
|
|
};
|
|
|
|
struct dtor_parent {
|
|
dtor_a a;
|
|
dtor_b b;
|
|
dtor_c c;
|
|
};
|
|
|
|
void create_and_destroy_dtor_parent(void)
|
|
{
|
|
dtor_parent p;
|
|
}
|
|
|
|
void test_structs(void)
|
|
{
|
|
my_struct s;
|
|
my_class c;
|
|
test_equal("s.a (uninitialized)", s.a, 0);
|
|
test_string("s.s (uninitialized)", s.s, "");
|
|
test_equal("s.inner.a (uninitialized)", s.inner.a, 0);
|
|
test_equal("s.a = 12", (s.a = 12, s.a), 12);
|
|
test_equal("s.b = 13", (s.b = 13, s.b), 13);
|
|
test_bool("s.s = \"test\"", (s.s = "test", s.s == "test"), true);
|
|
test_equal("s.inner.a = 14", (s.inner.a = 14, s.inner.a), 14);
|
|
test_equal("constructor", c.a, 42);
|
|
test_equal("nested constructor", c.inner.a, 99);
|
|
test_equal("nested constructor precedence", c.b, 100);
|
|
test_equal("c.set_a(22)", (c.set_a(22), c.a), 22);
|
|
|
|
my_struct a;
|
|
my_struct b;
|
|
a.a = 42;
|
|
b = a;
|
|
test_equal("struct assign", b.a, 42);
|
|
|
|
ref my_struct r;
|
|
r <- new my_struct;
|
|
test_equal("r.a (uninitialized)", r.a, 0);
|
|
test_equal("r.a = 12", (r.a = 12, r.a), 12);
|
|
|
|
dtor_order = "";
|
|
create_and_destroy_dtor_parent();
|
|
test_string("member destruct order", dtor_order, "cba");
|
|
}
|