Skip to content

Commit 39832b7

Browse files
committed
Add semantic restrictions for value- and default-initialization
1 parent 0be4e00 commit 39832b7

File tree

3 files changed

+106
-6
lines changed

3 files changed

+106
-6
lines changed

cpp23/common.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@
55
#define ILL_FORMED_NODE(id) { id [label="The program is ill-formed.", shape=box, style=filled, color=red, fontcolor=white]; }
66
#define RECURSE_SUBOBJECT_NODE(id) { id [label="Partially recurse.", shape=box, style=filled, color=lightblue, fontcolor=black]}
77
#define RECURSE_NODE(id) { id [label="Recurse.", shape=box, style=filled, color=blue, fontcolor=white]}
8+
#define YES_NODE(id, text) { id [label=text, shape=box, color=green, fontcolor=black]; }
9+
#define NO_NODE(id, text) { id [label=text, shape=box, color=red, fontcolor=black]; }
810

911
#define NEW_DONE() { DONE_NODE(TOKEN_CAT(__local_done_, __COUNTER__)); }
1012
#define NEW_ILL_FORMED() { ILL_FORMED_NODE(TOKEN_CAT(__local_ill_formed_, __COUNTER__)); }
1113
#define NEW_RECURSE() { RECURSE_NODE(TOKEN_CAT(__local_recurse, __COUNTER__)); }
1214
#define NEW_RECURSE_SUBOBJECT() { RECURSE_SUBOBJECT_NODE(TOKEN_CAT(__local_recurse_subobject, __COUNTER__)); }
15+
#define NEW_YES(label) { YES_NODE(TOKEN_CAT(__local_yes_, __COUNTER__), label); }
16+
#define NEW_NO(label) { NO_NODE(TOKEN_CAT(__local_no_, __COUNTER__), label); }
1317

1418
#define INTERNALLY_RECURSES_SUBOBJECT(id) { id -> { RECURSE_SUBOBJECT_NODE(TOKEN_CAT(id, __recurse)); } [style="dotted"]; }
1519

cpp23/default_init.dot.cpp

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,44 @@
88
#define DEFAULT_INIT_BACKREF(source) { { source; } -> NODE_DEFAULT_INIT_HEAD [style="dotted"] }
99
#define INTERNALLY_DEFAULT_INITS(id) { id -> NODE_DEFAULT_INIT_HEAD [style="dotted"]; }
1010

11+
#define NEW_IS_CDC() NEW_YES("T is const-default-constructible.")
12+
#define NEW_NOT_CDC() NEW_NO("T is not const-default-constructible.")
13+
14+
#define REFERENCES_CDC(node) { node -> cdc_head [style="dotted"]; }
15+
16+
// Forward declare to avoid cdc_head being in cluster_default_initialization.
17+
subgraph cluster_is_const_default_constructible {
18+
cdc_head
19+
}
20+
1121
// [dcl.init.general]/7
1222
subgraph cluster_default_initialization {
1323
INSTRUCTION_NODE(NODE_DEFAULT_INIT_HEAD, "Default-initialization", "[dcl.init.general]/7")
14-
-> INSTRUCTION_NODE(default_defn_t, "Let the type of the object be T.", "[dcl.init.general]/7")
15-
-> default_is_class
24+
-> default_is_reference
25+
26+
// 10
27+
{
28+
YN_QUESTION_NODE(default_is_reference, "Is the destination a reference?", "[dcl.init.general]/10", NEW_ILL_FORMED(), default_defn_t)
29+
}
30+
31+
INSTRUCTION_NODE(default_defn_t, "Let the type of the object be T.", "[dcl.init.general]/7")
32+
-> default_is_const
1633

17-
// 7,1
34+
// 8
35+
{
36+
YN_QUESTION_NODE(default_is_const, "Is T const-qualified?", "[dcl.init.general]/8", default_const_is_class, default_is_class)
37+
38+
YN_QUESTION_NODE(default_const_is_class, "Is T a class type?", "[dcl.init.general]/8", default_const_class_is_cdc, default_const_is_class)
39+
YN_QUESTION_NODE(default_const_class_is_cdc, "Is T const-default-constructible", "[dcl.init.general]/8", default_is_class, NEW_ILL_FORMED())
40+
REFERENCES_CDC(default_const_class_is_cdc)
41+
42+
YN_QUESTION_NODE(default_const_is_class, "Is T an array type?", "[dcl.init.general]/8", default_const_array_element_is_class, NEW_ILL_FORMED())
43+
YN_QUESTION_NODE(default_const_array_element_is_class, "Is T's element type a class type?", "[dcl.init.general]/8", default_const_array_element_class_is_cdc, NEW_ILL_FORMED())
44+
YN_QUESTION_NODE(default_const_array_element_class_is_cdc, "Is that class type const-default-constructible?", "[dcl.init.general]/8", default_is_class, NEW_ILL_FORMED())
45+
REFERENCES_CDC(default_const_array_element_class_is_cdc)
46+
}
47+
48+
// 7.1
1849
{
1950
YN_QUESTION_NODE(default_is_class, "Is T a (possibly cv-qualified class type)?", "[dcl.init.general]/7.1", default_class_enumerate, default_is_array)
2051

@@ -41,4 +72,62 @@ subgraph cluster_default_initialization {
4172
}
4273
}
4374

75+
// [dcl.init.general]/8
76+
subgraph cluster_is_const_default_constructible {
77+
INSTRUCTION_NODE(cdc_head, "To determine if class type T is const-default-constructible:", "[dcl.init.general/8]")
78+
-> cdc_would_invoke_user_provided
79+
80+
YN_QUESTION_NODE(cdc_would_invoke_user_provided, "Would default-initialization of T invoke a user-provided constructor of T (not inherited from a base class)?", "[dcl.init.general/8]", NEW_IS_CDC(), cdc_base_is_cdc)
81+
82+
// 8.4
83+
YN_QUESTION_NODE(cdc_base_is_cdc, "Is each potentially constructed base class of T const-default-constructible?", "[dcl.init.general]/8.4", cdc_member_each, NEW_NOT_CDC())
84+
85+
// 8.1
86+
{
87+
INSTRUCTION_NODE(cdc_member_each, "For each direct non-variant non-static data member M of T:", "[dcl.init.general]/8.1")
88+
-> cdc_member_has_default
89+
90+
YN_QUESTION_NODE_NO_CITE(cdc_member_has_default, "Does M have a default member initializer?", cdc_member_repeat, cdc_member_is_class)
91+
92+
YN_QUESTION_NODE_NO_CITE(cdc_member_is_class, "Does M have class type?", cdc_member_class_defn_x, cdc_member_is_array_of_class)
93+
YN_QUESTION_NODE_NO_CITE(cdc_member_is_array_of_class, "Does M have array of class type?", cdc_member_array_defn_x, NEW_NOT_CDC())
94+
95+
INSTRUCTION_NODE(cdc_member_class_defn_x, "Let X be that class type.")
96+
-> cdc_member_x_is_cdc
97+
98+
INSTRUCTION_NODE(cdc_member_array_defn_x, "Let X be the element (class) type.")
99+
-> cdc_member_x_is_cdc
100+
101+
YN_QUESTION_NODE_NO_CITE(cdc_member_x_is_cdc, "Is X const-default-constructible?", cdc_member_repeat, NEW_NOT_CDC())
102+
REFERENCES_CDC(cdc_member_x_is_cdc)
103+
104+
INSTRUCTION_NODE(cdc_member_repeat, "Repeat with the next non-static data member.")
105+
-> cdc_is_union [label="Once done with all non-static data members"]
106+
107+
LOOP_BACKEDGE(cdc_member_repeat, cdc_member_each)
108+
}
109+
110+
YN_QUESTION_NODE(cdc_is_union, "Is T a union?", "[dcl.init.general]/8.2-3", cdc_union_has_nsdm, cdc_nonunion_anon_union_each)
111+
112+
// 8.2
113+
{
114+
YN_QUESTION_NODE(cdc_union_has_nsdm, "Does T have at least one non-static data member?", "[dcl.init.general]/8.2", cdc_union_has_one_init_nsdm, NEW_IS_CDC())
115+
YN_QUESTION_NODE(cdc_union_has_one_init_nsdm, "Does exactly one variant member of T have a default member initializer?", "[dcl.init.general]/8.2", NEW_IS_CDC(), NEW_NOT_CDC())
116+
}
117+
118+
// 8.3
119+
{
120+
INSTRUCTION_NODE(cdc_nonunion_anon_union_each, "For each anonymous union member of T:", "[dcl.init.general]/8.3")
121+
-> cdc_nonunion_anon_union_has_nsdm
122+
123+
YN_QUESTION_NODE_NO_CITE(cdc_nonunion_anon_union_has_nsdm, "Does that anonymous union member have at least one non-static data member?", cdc_nonunion_anon_union_one_init_nsdm, cdc_nonunion_anon_union_repeat)
124+
YN_QUESTION_NODE_NO_CITE(cdc_nonunion_anon_union_one_init_nsdm, "Does exactly one non-static data member of that anonymous union member have a default member initializer?", cdc_nonunion_anon_union_repeat, NEW_NOT_CDC())
125+
126+
INSTRUCTION_NODE(cdc_nonunion_anon_union_repeat, "Repeat with the next anonymous data member.")
127+
-> NEW_IS_CDC() [label="Once done with all anonymous union members"]
128+
129+
LOOP_BACKEDGE(cdc_nonunion_anon_union_repeat, cdc_nonunion_anon_union_each)
130+
}
131+
}
132+
44133
#endif

cpp23/value_init.dot.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,23 @@
1313
// [dcl.init.general]/9
1414
subgraph cluster_value_initialization {
1515
INSTRUCTION_NODE(NODE_VALUE_INIT_HEAD, "Value-initialization", "[dcl.init.general]/9")
16-
-> INSTRUCTION_NODE(value_defn_t, "Let T be the type of the object.", "[dcl.init.general]/9")
16+
-> value_is_reference
17+
18+
// 10
19+
{
20+
YN_QUESTION_NODE(value_is_reference, "Is the destination a reference?", "[dcl.init.general]/10", NEW_ILL_FORMED(), value_defn_t)
21+
}
22+
23+
INSTRUCTION_NODE(value_defn_t, "Let T be the type of the object.", "[dcl.init.general]/9")
1724
-> value_is_class
1825

1926
// 9.1
2027
{
2128
YN_QUESTION_NODE(value_is_class, "Is the type a (possibly cv-qualified) class type?", "[dcl.init.general]/9.1", value_class_has_default, value_is_array)
2229

2330
YN_QUESTION_NODE(value_class_has_default, "Does T have a default constructor?", "[dcl.init.general]/9.1", value_class_default_is_deleted, value_class_direct_default_init)
24-
YN_QUESTION_NODE(value_class_default_is_deleted, "Is that default constructor deleted?", "[dcl.init.general]/9.1", value_class_direct_default_init, value_class_default_is_user_provided)
25-
YN_QUESTION_NODE(value_class_default_is_user_provided, "Is that default constructor user-provided?", "[dcl.init.general]/9.1", value_class_direct_default_init, value_class_dflt_ctor_check_zero)
31+
YN_QUESTION_NODE(value_class_default_is_deleted, "Does T have a default constructor that is deleted?", "[dcl.init.general]/9.1", value_class_direct_default_init, value_class_default_is_user_provided)
32+
YN_QUESTION_NODE(value_class_default_is_user_provided, "Does T have a default constructor that is user-provided?", "[dcl.init.general]/9.1", value_class_direct_default_init, value_class_dflt_ctor_check_zero)
2633

2734
INSTRUCTION_NODE(value_class_direct_default_init, "Default-initialize the object.", "[dcl.init.general]/9.1")
2835
-> NODE_DEFAULT_INIT_HEAD

0 commit comments

Comments
 (0)