Skip to content

Commit 07d255a

Browse files
committed
Virtual function instantiation for suppressed class template specializations [GH #431]
1 parent 6c38e1f commit 07d255a

12 files changed

Lines changed: 518 additions & 1 deletion

File tree

‎src/func_def.c‎

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

374-
if (class_type->variant.class_struct_union.
374+
if (class_type->variant.class_struct_union.do_not_instantiate &&
375+
!class_type_supp(class_type)->named_in_inline_template_directive) {
376+
/* Suppressing instantiation also suppresses vtable emission here, unless
377+
a GNU "inline template" directive explicitly requests it. Defining
378+
this member therefore does not require the virtual functions. */
379+
} else if (class_type->variant.class_struct_union.
375380
any_virtual_functions_including_in_base_classes) {
376381
if (routine->special_kind == (a_special_function_kind)sfk_constructor ||
377382
routine->special_kind == (a_special_function_kind)sfk_destructor) {

‎src/pending_changes/gh-431.txt‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[GH #431]
2+
Virtual function instantiation for suppressed class template specializations
3+
4+
Previously, defining an inline member function of a class template
5+
specialization whose instantiation was suppressed could unnecessarily
6+
instantiate the class's virtual functions. This no longer occurs unless the
7+
specialization is named in a GNU "inline template" directive. For example,
8+
with --c++11 -tused:
9+
10+
template<int N> struct C {
11+
virtual void f() {
12+
static_assert(N != 1, ""); // Previously a spurious error, now okay.
13+
}
14+
};
15+
extern template class C<1>;
16+
C<1> c;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
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 68: error: static assertion failed with ""
35+
static_assert(sizeof(T) == 0, "");
36+
^
37+
"Test_name.c", line 68: note: the final comparison was 4 == 0
38+
static_assert(sizeof(T) == 0, "");
39+
^
40+
detected during instantiation of "void explicit_instantiation_out_of_class::C<T>::f() [with T=int]" at line 72
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+
7 errors detected in the compilation of "Test_name.c".
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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 141: error: static assertion failed with ""
59+
static_assert(sizeof(T) == 0, "");
60+
^
61+
"Test_name.c", line 141: note: the final comparison was 4 == 0
62+
static_assert(sizeof(T) == 0, "");
63+
^
64+
detected during instantiation of "void inline_template::C<T>::f() [with T=int]"
65+
66+
"Test_name.c", line 159: error: static assertion failed with ""
67+
static_assert(sizeof(T) == 0, "");
68+
^
69+
"Test_name.c", line 159: note: the final comparison was 4 == 0
70+
static_assert(sizeof(T) == 0, "");
71+
^
72+
detected during instantiation of "void inline_template_inline_out_of_class::C<T>::f() [with T=int]"
73+
74+
9 errors detected in the compilation of "Test_name.c".
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
fe_only -DTEST_NUMBER=3 -tused --clang_version 220100 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+
7 errors detected in the compilation of "Test_name.c".
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
fe_only -DTEST_NUMBER=4 -tused --ms_c++20 --microsoft_version 1950 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+
7 errors detected in the compilation of "Test_name.c".
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fe_only -DTEST_NUMBER=1 -tused --c++11 Test_name.c
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fe_only -DTEST_NUMBER=2 -tused --gnu_version 150200 Test_name.c
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fe_only -DTEST_NUMBER=3 -tused --clang_version 220100 Test_name.c
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fe_only -DTEST_NUMBER=4 -tused --ms_c++20 --microsoft_version 1950 Test_name.c

0 commit comments

Comments
 (0)