Skip to content

Commit 0866b8e

Browse files
committed
The change only applies to the IA-64 ABI [GH #431]
1 parent 07d255a commit 0866b8e

6 files changed

Lines changed: 113 additions & 17 deletions

File tree

‎src/func_def.c‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -371,12 +371,17 @@ 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.do_not_instantiate &&
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 &&
375379
!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.
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. */
384+
if (class_type->variant.class_struct_union.
380385
any_virtual_functions_including_in_base_classes) {
381386
if (routine->special_kind == (a_special_function_kind)sfk_constructor ||
382387
routine->special_kind == (a_special_function_kind)sfk_destructor) {

‎src/pending_changes/gh-431.txt‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
[GH #431]
22
Virtual function instantiation for suppressed class template specializations
33

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:
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:
911

1012
template<int N> struct C {
1113
virtual void f() {

‎tests/tests/regressions/.gh-431-diag.rto/default.1.1.txt‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,20 @@ fe_only -DTEST_NUMBER=1 -tused --c++11 Test_name.c
5555
^
5656
detected during instantiation of "void derived_vtable_inline_out_of_class::C<T>::f() [with T=int]"
5757

58-
7 errors detected in the compilation of "Test_name.c".
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+
9 errors detected in the compilation of "Test_name.c".

‎tests/tests/regressions/.gh-431-diag.rto/default.2.1.txt‎

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,20 +55,36 @@ fe_only -DTEST_NUMBER=2 -tused --gnu_version 150200 Test_name.c
5555
^
5656
detected during instantiation of "void derived_vtable_inline_out_of_class::C<T>::f() [with T=int]"
5757

58-
"Test_name.c", line 141: error: static assertion failed with ""
58+
"Test_name.c", line 145: error: static assertion failed with ""
5959
static_assert(sizeof(T) == 0, "");
6060
^
61-
"Test_name.c", line 141: note: the final comparison was 4 == 0
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 182: error: static assertion failed with ""
75+
static_assert(sizeof(T) == 0, "");
76+
^
77+
"Test_name.c", line 182: note: the final comparison was 4 == 0
6278
static_assert(sizeof(T) == 0, "");
6379
^
6480
detected during instantiation of "void inline_template::C<T>::f() [with T=int]"
6581

66-
"Test_name.c", line 159: error: static assertion failed with ""
82+
"Test_name.c", line 200: error: static assertion failed with ""
6783
static_assert(sizeof(T) == 0, "");
6884
^
69-
"Test_name.c", line 159: note: the final comparison was 4 == 0
85+
"Test_name.c", line 200: note: the final comparison was 4 == 0
7086
static_assert(sizeof(T) == 0, "");
7187
^
7288
detected during instantiation of "void inline_template_inline_out_of_class::C<T>::f() [with T=int]"
7389

74-
9 errors detected in the compilation of "Test_name.c".
90+
11 errors detected in the compilation of "Test_name.c".

‎tests/tests/regressions/.gh-431-diag.rto/default.3.1.txt‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,20 @@ fe_only -DTEST_NUMBER=3 -tused --clang_version 220100 Test_name.c
5555
^
5656
detected during instantiation of "void derived_vtable_inline_out_of_class::C<T>::f() [with T=int]"
5757

58-
7 errors detected in the compilation of "Test_name.c".
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+
9 errors detected in the compilation of "Test_name.c".

‎tests/tests/regressions/gh-431-diag.sft.cpp‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,47 @@ namespace derived_vtable_inline_out_of_class
131131
}
132132
}
133133

134+
namespace internal_linkage
135+
{
136+
namespace
137+
{
138+
struct Local {};
139+
}
140+
141+
template<class T> struct C
142+
{
143+
virtual void f()
144+
{
145+
static_assert(sizeof(T) == 0, "");
146+
}
147+
};
148+
149+
extern template struct C<Local>;
150+
/* A specialization with internal linkage still gets a local vtable. */
151+
C<Local> c;
152+
}
153+
154+
namespace internal_linkage_inline_out_of_class
155+
{
156+
namespace
157+
{
158+
struct Local {};
159+
}
160+
161+
template<class T> struct C
162+
{
163+
virtual void f();
164+
};
165+
166+
template<class T> inline void C<T>::f()
167+
{
168+
static_assert(sizeof(T) == 0, "");
169+
}
170+
171+
extern template struct C<Local>;
172+
C<Local> c;
173+
}
174+
134175
#if defined(__GNUC__) && !defined(__clang__)
135176
namespace inline_template
136177
{

0 commit comments

Comments
 (0)