Skip to content

Commit fd3fc54

Browse files
committed
Virtual function instantiation for suppressed class template specializations [GH #431]
1 parent 92d9444 commit fd3fc54

21 files changed

Lines changed: 1068 additions & 0 deletions

‎src/func_def.c‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,16 @@ indicated routine has just been processed.
371371
a_boolean needed = FALSE;
372372
a_type_ptr class_type = parent_class_of(routine);
373373

374+
#if IA64_ABI && ABI_COMPATIBILITY_VERSION >= 410
375+
if (is_unspecialized_template_class(class_type) &&
376+
class_type->variant.class_struct_union.do_not_instantiate &&
377+
!class_type->variant.class_struct_union.explicitly_instantiated &&
378+
class_type->source_corresp.name_linkage == nlk_cplusplus_external &&
379+
!class_type_supp(class_type)->named_in_inline_template_directive) {
380+
/* Lowering suppresses this specialization's virtual function table. */
381+
} else
382+
#endif /* IA64_ABI && ABI_COMPATIBILITY_VERSION >= 410 */
383+
/* Do not insert code here. */
374384
if (class_type->variant.class_struct_union.
375385
any_virtual_functions_including_in_base_classes) {
376386
if (routine->special_kind == (a_special_function_kind)sfk_constructor ||

‎src/pending_changes/gh-431.txt‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[GH #431]
2+
Virtual function instantiation for suppressed class template specializations
3+
4+
Previously, in IA-64 ABI configurations with ABI_COMPATIBILITY_VERSION >= 410,
5+
defining an inline member function of a class template specialization whose
6+
instantiation was suppressed could unnecessarily instantiate the class's
7+
virtual functions. This no longer occurs when the specialization has external
8+
linkage and its virtual function table is suppressed. A GNU "inline template"
9+
directive still requires the virtual functions. For example, with
10+
--c++11 -tused:
11+
12+
template<int N> struct C {
13+
virtual void f() {
14+
static_assert(N != 1, ""); // Previously a spurious error, now okay.
15+
}
16+
};
17+
extern template class C<1>;
18+
C<1> c;
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
fe_only -DTEST_NUMBER=1 -tused --c++11 Test_name.c
2+
"Test_name.c", line 11: error: static assertion failed with ""
3+
static_assert(sizeof(T) == 0, "");
4+
^
5+
"Test_name.c", line 11: note: the final comparison was 4 == 0
6+
static_assert(sizeof(T) == 0, "");
7+
^
8+
detected during instantiation of "void direct_call::C<T>::f() [with T=int]" at line 20
9+
10+
"Test_name.c", line 33: error: static assertion failed with ""
11+
static_assert(sizeof(T) == 0, "");
12+
^
13+
"Test_name.c", line 33: note: the final comparison was 4 == 0
14+
static_assert(sizeof(T) == 0, "");
15+
^
16+
detected during instantiation of "void direct_call_inline_out_of_class::C<T>::f() [with T=int]" at line 40
17+
18+
"Test_name.c", line 50: error: static assertion failed with ""
19+
static_assert(sizeof(T) == 0, "");
20+
^
21+
"Test_name.c", line 50: note: the final comparison was 4 == 0
22+
static_assert(sizeof(T) == 0, "");
23+
^
24+
detected during instantiation of "void explicit_instantiation::C<T>::f() [with T=int]" at line 56
25+
26+
"Test_name.c", line 84: error: static assertion failed with ""
27+
static_assert(sizeof(T) == 0, "");
28+
^
29+
"Test_name.c", line 84: note: the final comparison was 4 == 0
30+
static_assert(sizeof(T) == 0, "");
31+
^
32+
detected during instantiation of "void explicit_instantiation_inline_out_of_class::C<T>::f() [with T=int]" at line 88
33+
34+
"Test_name.c", line 223: error: static assertion failed with ""
35+
static_assert(sizeof(T) == 0, "");
36+
^
37+
"Test_name.c", line 223: note: the final comparison was 4 == 0
38+
static_assert(sizeof(T) == 0, "");
39+
^
40+
detected during instantiation of "void direct_virtual_call::C<T>::f() [with T=int]" at line 232
41+
42+
"Test_name.c", line 245: error: static assertion failed with ""
43+
static_assert(sizeof(T) == 0, "");
44+
^
45+
"Test_name.c", line 245: note: the final comparison was 4 == 0
46+
static_assert(sizeof(T) == 0, "");
47+
^
48+
detected during instantiation of "void direct_virtual_call_inline_out_of_class::C<T>::f() [with T=int]" at line 252
49+
50+
"Test_name.c", line 68: error: static assertion failed with ""
51+
static_assert(sizeof(T) == 0, "");
52+
^
53+
"Test_name.c", line 68: note: the final comparison was 4 == 0
54+
static_assert(sizeof(T) == 0, "");
55+
^
56+
detected during instantiation of "void explicit_instantiation_out_of_class::C<T>::f() [with T=int]" at line 72
57+
58+
"Test_name.c", line 97: error: static assertion failed with ""
59+
static_assert(sizeof(T) == 0, "");
60+
^
61+
"Test_name.c", line 97: note: the final comparison was 4 == 0
62+
static_assert(sizeof(T) == 0, "");
63+
^
64+
detected during instantiation of "void derived_vtable::C<T>::f() [with T=int]"
65+
66+
"Test_name.c", line 121: error: static assertion failed with ""
67+
static_assert(sizeof(T) == 0, "");
68+
^
69+
"Test_name.c", line 121: note: the final comparison was 4 == 0
70+
static_assert(sizeof(T) == 0, "");
71+
^
72+
detected during instantiation of "void derived_vtable_inline_out_of_class::C<T>::f() [with T=int]"
73+
74+
"Test_name.c", line 145: error: static assertion failed with ""
75+
static_assert(sizeof(T) == 0, "");
76+
^
77+
"Test_name.c", line 145: note: the final comparison was 1 == 0
78+
static_assert(sizeof(T) == 0, "");
79+
^
80+
detected during instantiation of "void internal_linkage::C<T>::f() [with T=internal_linkage::<unnamed>::Local]"
81+
82+
"Test_name.c", line 168: error: static assertion failed with ""
83+
static_assert(sizeof(T) == 0, "");
84+
^
85+
"Test_name.c", line 168: note: the final comparison was 1 == 0
86+
static_assert(sizeof(T) == 0, "");
87+
^
88+
detected during instantiation of "void internal_linkage_inline_out_of_class::C<T>::f() [with T=internal_linkage_inline_out_of_class::<unnamed>::Local]"
89+
90+
"Test_name.c", line 183: error: static assertion failed with ""
91+
static_assert(sizeof(T) == 0, "");
92+
^
93+
"Test_name.c", line 183: note: the final comparison was 4 == 0
94+
static_assert(sizeof(T) == 0, "");
95+
^
96+
detected during instantiation of "void internal_linkage_template::<unnamed>::C<T>::f() [with T=int]"
97+
98+
"Test_name.c", line 207: error: static assertion failed with ""
99+
static_assert(P == nullptr, "");
100+
^
101+
detected during instantiation of "void internal_linkage_nontype_argument::C<P>::f() [with P=&internal_linkage_nontype_argument::value]"
102+
103+
"Test_name.c", line 262: error: static assertion failed with ""
104+
static_assert(sizeof(T) == 0, "");
105+
^
106+
"Test_name.c", line 262: note: the final comparison was 4 == 0
107+
static_assert(sizeof(T) == 0, "");
108+
^
109+
detected during instantiation of "void specialized_nested_class::Base<T>::f() [with T=int]"
110+
111+
"Test_name.c", line 287: error: static assertion failed with ""
112+
static_assert(sizeof(T) == 0, "");
113+
^
114+
"Test_name.c", line 287: note: the final comparison was 4 == 0
115+
static_assert(sizeof(T) == 0, "");
116+
^
117+
detected during instantiation of "void nontemplate_nested_class::Base<T>::f() [with T=int]"
118+
119+
"Test_name.c", line 314: error: static assertion failed with ""
120+
static_assert(N != 2, "");
121+
^
122+
"Test_name.c", line 314: note: the final comparison was 2 != 2
123+
static_assert(N != 2, "");
124+
^
125+
detected during instantiation of "void unsuppressed_specialization::C<N>::f() [with N=2]"
126+
127+
16 errors detected in the compilation of "Test_name.c".
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
fe_only -DTEST_NUMBER=2 -tused --gnu_version 150200 Test_name.c
2+
"Test_name.c", line 11: error: static assertion failed with ""
3+
static_assert(sizeof(T) == 0, "");
4+
^
5+
"Test_name.c", line 11: note: the final comparison was 4 == 0
6+
static_assert(sizeof(T) == 0, "");
7+
^
8+
detected during instantiation of "void direct_call::C<T>::f() [with T=int]" at line 20
9+
10+
"Test_name.c", line 33: error: static assertion failed with ""
11+
static_assert(sizeof(T) == 0, "");
12+
^
13+
"Test_name.c", line 33: note: the final comparison was 4 == 0
14+
static_assert(sizeof(T) == 0, "");
15+
^
16+
detected during instantiation of "void direct_call_inline_out_of_class::C<T>::f() [with T=int]" at line 40
17+
18+
"Test_name.c", line 50: error: static assertion failed with ""
19+
static_assert(sizeof(T) == 0, "");
20+
^
21+
"Test_name.c", line 50: note: the final comparison was 4 == 0
22+
static_assert(sizeof(T) == 0, "");
23+
^
24+
detected during instantiation of "void explicit_instantiation::C<T>::f() [with T=int]" at line 56
25+
26+
"Test_name.c", line 68: error: static assertion failed with ""
27+
static_assert(sizeof(T) == 0, "");
28+
^
29+
"Test_name.c", line 68: note: the final comparison was 4 == 0
30+
static_assert(sizeof(T) == 0, "");
31+
^
32+
detected during instantiation of "void explicit_instantiation_out_of_class::C<T>::f() [with T=int]" at line 72
33+
34+
"Test_name.c", line 84: error: static assertion failed with ""
35+
static_assert(sizeof(T) == 0, "");
36+
^
37+
"Test_name.c", line 84: note: the final comparison was 4 == 0
38+
static_assert(sizeof(T) == 0, "");
39+
^
40+
detected during instantiation of "void explicit_instantiation_inline_out_of_class::C<T>::f() [with T=int]" at line 88
41+
42+
"Test_name.c", line 97: error: static assertion failed with ""
43+
static_assert(sizeof(T) == 0, "");
44+
^
45+
"Test_name.c", line 97: note: the final comparison was 4 == 0
46+
static_assert(sizeof(T) == 0, "");
47+
^
48+
detected during instantiation of "void derived_vtable::C<T>::f() [with T=int]"
49+
50+
"Test_name.c", line 121: error: static assertion failed with ""
51+
static_assert(sizeof(T) == 0, "");
52+
^
53+
"Test_name.c", line 121: note: the final comparison was 4 == 0
54+
static_assert(sizeof(T) == 0, "");
55+
^
56+
detected during instantiation of "void derived_vtable_inline_out_of_class::C<T>::f() [with T=int]"
57+
58+
"Test_name.c", line 145: error: static assertion failed with ""
59+
static_assert(sizeof(T) == 0, "");
60+
^
61+
"Test_name.c", line 145: note: the final comparison was 1 == 0
62+
static_assert(sizeof(T) == 0, "");
63+
^
64+
detected during instantiation of "void internal_linkage::C<T>::f() [with T=internal_linkage::<unnamed>::Local]"
65+
66+
"Test_name.c", line 168: error: static assertion failed with ""
67+
static_assert(sizeof(T) == 0, "");
68+
^
69+
"Test_name.c", line 168: note: the final comparison was 1 == 0
70+
static_assert(sizeof(T) == 0, "");
71+
^
72+
detected during instantiation of "void internal_linkage_inline_out_of_class::C<T>::f() [with T=internal_linkage_inline_out_of_class::<unnamed>::Local]"
73+
74+
"Test_name.c", line 183: error: static assertion failed with ""
75+
static_assert(sizeof(T) == 0, "");
76+
^
77+
"Test_name.c", line 183: note: the final comparison was 4 == 0
78+
static_assert(sizeof(T) == 0, "");
79+
^
80+
detected during instantiation of "void internal_linkage_template::<unnamed>::C<T>::f() [with T=int]"
81+
82+
"Test_name.c", line 207: error: static assertion failed with ""
83+
static_assert(P == nullptr, "");
84+
^
85+
detected during instantiation of "void internal_linkage_nontype_argument::C<P>::f() [with P=&internal_linkage_nontype_argument::value]"
86+
87+
"Test_name.c", line 223: error: static assertion failed with ""
88+
static_assert(sizeof(T) == 0, "");
89+
^
90+
"Test_name.c", line 223: note: the final comparison was 4 == 0
91+
static_assert(sizeof(T) == 0, "");
92+
^
93+
detected during instantiation of "void direct_virtual_call::C<T>::f() [with T=int]" at line 232
94+
95+
"Test_name.c", line 245: error: static assertion failed with ""
96+
static_assert(sizeof(T) == 0, "");
97+
^
98+
"Test_name.c", line 245: note: the final comparison was 4 == 0
99+
static_assert(sizeof(T) == 0, "");
100+
^
101+
detected during instantiation of "void direct_virtual_call_inline_out_of_class::C<T>::f() [with T=int]" at line 252
102+
103+
"Test_name.c", line 262: error: static assertion failed with ""
104+
static_assert(sizeof(T) == 0, "");
105+
^
106+
"Test_name.c", line 262: note: the final comparison was 4 == 0
107+
static_assert(sizeof(T) == 0, "");
108+
^
109+
detected during instantiation of "void specialized_nested_class::Base<T>::f() [with T=int]"
110+
111+
"Test_name.c", line 287: error: static assertion failed with ""
112+
static_assert(sizeof(T) == 0, "");
113+
^
114+
"Test_name.c", line 287: note: the final comparison was 4 == 0
115+
static_assert(sizeof(T) == 0, "");
116+
^
117+
detected during instantiation of "void nontemplate_nested_class::Base<T>::f() [with T=int]"
118+
119+
"Test_name.c", line 314: error: static assertion failed with ""
120+
static_assert(N != 2, "");
121+
^
122+
"Test_name.c", line 314: note: the final comparison was 2 != 2
123+
static_assert(N != 2, "");
124+
^
125+
detected during instantiation of "void unsuppressed_specialization::C<N>::f() [with N=2]"
126+
127+
"Test_name.c", line 331: error: static assertion failed with ""
128+
static_assert(sizeof(T) == 0, "");
129+
^
130+
"Test_name.c", line 331: note: the final comparison was 4 == 0
131+
static_assert(sizeof(T) == 0, "");
132+
^
133+
detected during instantiation of "void inline_template::C<T>::f() [with T=int]"
134+
135+
"Test_name.c", line 349: error: static assertion failed with ""
136+
static_assert(sizeof(T) == 0, "");
137+
^
138+
"Test_name.c", line 349: note: the final comparison was 4 == 0
139+
static_assert(sizeof(T) == 0, "");
140+
^
141+
detected during instantiation of "void inline_template_inline_out_of_class::C<T>::f() [with T=int]"
142+
143+
18 errors detected in the compilation of "Test_name.c".

0 commit comments

Comments
 (0)