diff --git a/src/func_def.c b/src/func_def.c index c28d7e0519..0e954ae248 100644 --- a/src/func_def.c +++ b/src/func_def.c @@ -371,6 +371,16 @@ indicated routine has just been processed. a_boolean needed = FALSE; a_type_ptr class_type = parent_class_of(routine); +#if IA64_ABI && ABI_COMPATIBILITY_VERSION >= 410 + if (is_unspecialized_template_class(class_type) && + class_type->variant.class_struct_union.do_not_instantiate && + !class_type->variant.class_struct_union.explicitly_instantiated && + class_type->source_corresp.name_linkage == nlk_cplusplus_external && + !class_type_supp(class_type)->named_in_inline_template_directive) { + /* Lowering suppresses this specialization's virtual function table. */ + } else +#endif /* IA64_ABI && ABI_COMPATIBILITY_VERSION >= 410 */ + /* Do not insert code here. */ if (class_type->variant.class_struct_union. any_virtual_functions_including_in_base_classes) { if (routine->special_kind == (a_special_function_kind)sfk_constructor || diff --git a/src/pending_changes/gh-431.txt b/src/pending_changes/gh-431.txt new file mode 100644 index 0000000000..3c82314d3a --- /dev/null +++ b/src/pending_changes/gh-431.txt @@ -0,0 +1,18 @@ +[GH #431] +Virtual function instantiation for suppressed class template specializations + +Previously, in IA-64 ABI configurations with ABI_COMPATIBILITY_VERSION >= 410, +defining an inline member function of a class template specialization whose +instantiation was suppressed could unnecessarily instantiate the class's +virtual functions. This no longer occurs when the specialization has external +linkage and its virtual function table is suppressed. A GNU "inline template" +directive still requires the virtual functions. For example, with +--c++11 -tused: + + template struct C { + virtual void f() { + static_assert(N != 1, ""); // Previously a spurious error, now okay. + } + }; + extern template class C<1>; + C<1> c; diff --git a/tests/tests/regressions/.gh-431-diag.rto/default.1.1.txt b/tests/tests/regressions/.gh-431-diag.rto/default.1.1.txt new file mode 100644 index 0000000000..d984e4570b --- /dev/null +++ b/tests/tests/regressions/.gh-431-diag.rto/default.1.1.txt @@ -0,0 +1,127 @@ +fe_only -DTEST_NUMBER=1 -tused --c++11 Test_name.c +"Test_name.c", line 11: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 11: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_call::C::f() [with T=int]" at line 20 + +"Test_name.c", line 33: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 33: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_call_inline_out_of_class::C::f() [with T=int]" at line 40 + +"Test_name.c", line 50: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 50: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void explicit_instantiation::C::f() [with T=int]" at line 56 + +"Test_name.c", line 84: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 84: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void explicit_instantiation_inline_out_of_class::C::f() [with T=int]" at line 88 + +"Test_name.c", line 223: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 223: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_virtual_call::C::f() [with T=int]" at line 232 + +"Test_name.c", line 245: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 245: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_virtual_call_inline_out_of_class::C::f() [with T=int]" at line 252 + +"Test_name.c", line 68: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 68: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void explicit_instantiation_out_of_class::C::f() [with T=int]" at line 72 + +"Test_name.c", line 97: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 97: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void derived_vtable::C::f() [with T=int]" + +"Test_name.c", line 121: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 121: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void derived_vtable_inline_out_of_class::C::f() [with T=int]" + +"Test_name.c", line 145: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 145: note: the final comparison was 1 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void internal_linkage::C::f() [with T=internal_linkage::::Local]" + +"Test_name.c", line 168: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 168: note: the final comparison was 1 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void internal_linkage_inline_out_of_class::C::f() [with T=internal_linkage_inline_out_of_class::::Local]" + +"Test_name.c", line 183: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 183: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void internal_linkage_template::::C::f() [with T=int]" + +"Test_name.c", line 207: error: static assertion failed with "" + static_assert(P == nullptr, ""); + ^ + detected during instantiation of "void internal_linkage_nontype_argument::C

::f() [with P=&internal_linkage_nontype_argument::value]" + +"Test_name.c", line 262: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 262: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void specialized_nested_class::Base::f() [with T=int]" + +"Test_name.c", line 287: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 287: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void nontemplate_nested_class::Base::f() [with T=int]" + +"Test_name.c", line 314: error: static assertion failed with "" + static_assert(N != 2, ""); + ^ +"Test_name.c", line 314: note: the final comparison was 2 != 2 + static_assert(N != 2, ""); + ^ + detected during instantiation of "void unsuppressed_specialization::C::f() [with N=2]" + +16 errors detected in the compilation of "Test_name.c". diff --git a/tests/tests/regressions/.gh-431-diag.rto/default.2.1.txt b/tests/tests/regressions/.gh-431-diag.rto/default.2.1.txt new file mode 100644 index 0000000000..e6575e340e --- /dev/null +++ b/tests/tests/regressions/.gh-431-diag.rto/default.2.1.txt @@ -0,0 +1,143 @@ +fe_only -DTEST_NUMBER=2 -tused --gnu_version 150200 Test_name.c +"Test_name.c", line 11: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 11: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_call::C::f() [with T=int]" at line 20 + +"Test_name.c", line 33: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 33: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_call_inline_out_of_class::C::f() [with T=int]" at line 40 + +"Test_name.c", line 50: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 50: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void explicit_instantiation::C::f() [with T=int]" at line 56 + +"Test_name.c", line 68: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 68: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void explicit_instantiation_out_of_class::C::f() [with T=int]" at line 72 + +"Test_name.c", line 84: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 84: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void explicit_instantiation_inline_out_of_class::C::f() [with T=int]" at line 88 + +"Test_name.c", line 97: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 97: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void derived_vtable::C::f() [with T=int]" + +"Test_name.c", line 121: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 121: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void derived_vtable_inline_out_of_class::C::f() [with T=int]" + +"Test_name.c", line 145: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 145: note: the final comparison was 1 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void internal_linkage::C::f() [with T=internal_linkage::::Local]" + +"Test_name.c", line 168: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 168: note: the final comparison was 1 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void internal_linkage_inline_out_of_class::C::f() [with T=internal_linkage_inline_out_of_class::::Local]" + +"Test_name.c", line 183: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 183: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void internal_linkage_template::::C::f() [with T=int]" + +"Test_name.c", line 207: error: static assertion failed with "" + static_assert(P == nullptr, ""); + ^ + detected during instantiation of "void internal_linkage_nontype_argument::C

::f() [with P=&internal_linkage_nontype_argument::value]" + +"Test_name.c", line 223: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 223: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_virtual_call::C::f() [with T=int]" at line 232 + +"Test_name.c", line 245: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 245: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_virtual_call_inline_out_of_class::C::f() [with T=int]" at line 252 + +"Test_name.c", line 262: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 262: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void specialized_nested_class::Base::f() [with T=int]" + +"Test_name.c", line 287: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 287: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void nontemplate_nested_class::Base::f() [with T=int]" + +"Test_name.c", line 314: error: static assertion failed with "" + static_assert(N != 2, ""); + ^ +"Test_name.c", line 314: note: the final comparison was 2 != 2 + static_assert(N != 2, ""); + ^ + detected during instantiation of "void unsuppressed_specialization::C::f() [with N=2]" + +"Test_name.c", line 331: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 331: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void inline_template::C::f() [with T=int]" + +"Test_name.c", line 349: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 349: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void inline_template_inline_out_of_class::C::f() [with T=int]" + +18 errors detected in the compilation of "Test_name.c". diff --git a/tests/tests/regressions/.gh-431-diag.rto/default.3.1.txt b/tests/tests/regressions/.gh-431-diag.rto/default.3.1.txt new file mode 100644 index 0000000000..02707b6168 --- /dev/null +++ b/tests/tests/regressions/.gh-431-diag.rto/default.3.1.txt @@ -0,0 +1,127 @@ +fe_only -DTEST_NUMBER=3 -tused --clang_version 220100 Test_name.c +"Test_name.c", line 11: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 11: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_call::C::f() [with T=int]" at line 20 + +"Test_name.c", line 33: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 33: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_call_inline_out_of_class::C::f() [with T=int]" at line 40 + +"Test_name.c", line 50: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 50: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void explicit_instantiation::C::f() [with T=int]" at line 56 + +"Test_name.c", line 68: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 68: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void explicit_instantiation_out_of_class::C::f() [with T=int]" at line 72 + +"Test_name.c", line 84: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 84: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void explicit_instantiation_inline_out_of_class::C::f() [with T=int]" at line 88 + +"Test_name.c", line 97: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 97: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void derived_vtable::C::f() [with T=int]" + +"Test_name.c", line 121: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 121: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void derived_vtable_inline_out_of_class::C::f() [with T=int]" + +"Test_name.c", line 145: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 145: note: the final comparison was 1 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void internal_linkage::C::f() [with T=internal_linkage::::Local]" + +"Test_name.c", line 168: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 168: note: the final comparison was 1 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void internal_linkage_inline_out_of_class::C::f() [with T=internal_linkage_inline_out_of_class::::Local]" + +"Test_name.c", line 183: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 183: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void internal_linkage_template::::C::f() [with T=int]" + +"Test_name.c", line 207: error: static assertion failed with "" + static_assert(P == nullptr, ""); + ^ + detected during instantiation of "void internal_linkage_nontype_argument::C

::f() [with P=&internal_linkage_nontype_argument::value]" + +"Test_name.c", line 223: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 223: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_virtual_call::C::f() [with T=int]" at line 232 + +"Test_name.c", line 245: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 245: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_virtual_call_inline_out_of_class::C::f() [with T=int]" at line 252 + +"Test_name.c", line 262: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 262: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void specialized_nested_class::Base::f() [with T=int]" + +"Test_name.c", line 287: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 287: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void nontemplate_nested_class::Base::f() [with T=int]" + +"Test_name.c", line 314: error: static assertion failed with "" + static_assert(N != 2, ""); + ^ +"Test_name.c", line 314: note: the final comparison was 2 != 2 + static_assert(N != 2, ""); + ^ + detected during instantiation of "void unsuppressed_specialization::C::f() [with N=2]" + +16 errors detected in the compilation of "Test_name.c". diff --git a/tests/tests/regressions/.gh-431-diag.rto/default.4.1.txt b/tests/tests/regressions/.gh-431-diag.rto/default.4.1.txt new file mode 100644 index 0000000000..f346ee5710 --- /dev/null +++ b/tests/tests/regressions/.gh-431-diag.rto/default.4.1.txt @@ -0,0 +1,103 @@ +fe_only -DTEST_NUMBER=4 -tused --ms_c++20 --microsoft_version 1950 Test_name.c +"Test_name.c", line 11: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 11: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_call::C::f() [with T=int]" at line 20 + +"Test_name.c", line 33: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 33: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_call_inline_out_of_class::C::f() [with T=int]" at line 40 + +"Test_name.c", line 50: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 50: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void explicit_instantiation::C::f() [with T=int]" at line 56 + +"Test_name.c", line 68: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 68: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void explicit_instantiation_out_of_class::C::f() [with T=int]" at line 72 + +"Test_name.c", line 84: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 84: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void explicit_instantiation_inline_out_of_class::C::f() [with T=int]" at line 88 + +"Test_name.c", line 97: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 97: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void derived_vtable::C::f() [with T=int]" + +"Test_name.c", line 121: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 121: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void derived_vtable_inline_out_of_class::C::f() [with T=int]" + +"Test_name.c", line 207: error: static assertion failed with "" + static_assert(P == nullptr, ""); + ^ + detected during instantiation of "void internal_linkage_nontype_argument::C

::f() [with P=&internal_linkage_nontype_argument::value]" + +"Test_name.c", line 223: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 223: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_virtual_call::C::f() [with T=int]" at line 232 + +"Test_name.c", line 245: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 245: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void direct_virtual_call_inline_out_of_class::C::f() [with T=int]" at line 252 + +"Test_name.c", line 262: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 262: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void specialized_nested_class::Base::f() [with T=int]" + +"Test_name.c", line 287: error: static assertion failed with "" + static_assert(sizeof(T) == 0, ""); + ^ +"Test_name.c", line 287: note: the final comparison was 4 == 0 + static_assert(sizeof(T) == 0, ""); + ^ + detected during instantiation of "void nontemplate_nested_class::Base::f() [with T=int]" + +"Test_name.c", line 314: error: static assertion failed with "" + static_assert(N != 2, ""); + ^ +"Test_name.c", line 314: note: the final comparison was 2 != 2 + static_assert(N != 2, ""); + ^ + detected during instantiation of "void unsuppressed_specialization::C::f() [with N=2]" + +13 errors detected in the compilation of "Test_name.c". diff --git a/tests/tests/regressions/.gh-431-ia64.rto/default.1.1.txt b/tests/tests/regressions/.gh-431-ia64.rto/default.1.1.txt new file mode 100644 index 0000000000..fcf5b546e4 --- /dev/null +++ b/tests/tests/regressions/.gh-431-ia64.rto/default.1.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=1 -tused --c++11 Test_name.c diff --git a/tests/tests/regressions/.gh-431-ia64.rto/default.2.1.txt b/tests/tests/regressions/.gh-431-ia64.rto/default.2.1.txt new file mode 100644 index 0000000000..7a2ce534cb --- /dev/null +++ b/tests/tests/regressions/.gh-431-ia64.rto/default.2.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=2 -tused --gnu_version 150200 Test_name.c diff --git a/tests/tests/regressions/.gh-431-ia64.rto/default.3.1.txt b/tests/tests/regressions/.gh-431-ia64.rto/default.3.1.txt new file mode 100644 index 0000000000..6d6dc6d606 --- /dev/null +++ b/tests/tests/regressions/.gh-431-ia64.rto/default.3.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=3 -tused --clang_version 220100 Test_name.c diff --git a/tests/tests/regressions/.gh-431-ia64.rto/default.4.1.txt b/tests/tests/regressions/.gh-431-ia64.rto/default.4.1.txt new file mode 100644 index 0000000000..6c55ae241d --- /dev/null +++ b/tests/tests/regressions/.gh-431-ia64.rto/default.4.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=4 -tused --ms_c++20 --microsoft_version 1950 Test_name.c diff --git a/tests/tests/regressions/.gh-431.rto/default.1.1.txt b/tests/tests/regressions/.gh-431.rto/default.1.1.txt new file mode 100644 index 0000000000..fcf5b546e4 --- /dev/null +++ b/tests/tests/regressions/.gh-431.rto/default.1.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=1 -tused --c++11 Test_name.c diff --git a/tests/tests/regressions/.gh-431.rto/default.2.1.txt b/tests/tests/regressions/.gh-431.rto/default.2.1.txt new file mode 100644 index 0000000000..7a2ce534cb --- /dev/null +++ b/tests/tests/regressions/.gh-431.rto/default.2.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=2 -tused --gnu_version 150200 Test_name.c diff --git a/tests/tests/regressions/.gh-431.rto/default.3.1.txt b/tests/tests/regressions/.gh-431.rto/default.3.1.txt new file mode 100644 index 0000000000..6d6dc6d606 --- /dev/null +++ b/tests/tests/regressions/.gh-431.rto/default.3.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=3 -tused --clang_version 220100 Test_name.c diff --git a/tests/tests/regressions/.gh-431.rto/default.4.1.txt b/tests/tests/regressions/.gh-431.rto/default.4.1.txt new file mode 100644 index 0000000000..6c55ae241d --- /dev/null +++ b/tests/tests/regressions/.gh-431.rto/default.4.1.txt @@ -0,0 +1 @@ +fe_only -DTEST_NUMBER=4 -tused --ms_c++20 --microsoft_version 1950 Test_name.c diff --git a/tests/tests/regressions/gh-431-diag.sft.cpp b/tests/tests/regressions/gh-431-diag.sft.cpp new file mode 100644 index 0000000000..72784bedee --- /dev/null +++ b/tests/tests/regressions/gh-431-diag.sft.cpp @@ -0,0 +1,355 @@ +//type:fn +//options_all:-tused +//options:--c++11:--gnu_version 150200:--clang_version 220100:--ms_c++20 --microsoft_version 1950 + +namespace direct_call +{ + template struct C + { + void f() + { + static_assert(sizeof(T) == 0, ""); + } + }; + + extern template struct C; + + /* An extern template declaration must not suppress inline body checking. */ + void g(C& c) + { + c.f(); + } +} + +namespace direct_call_inline_out_of_class +{ + template struct C + { + void f(); + }; + + template inline void C::f() + { + static_assert(sizeof(T) == 0, ""); + } + + extern template struct C; + + void g(C& c) + { + c.f(); + } +} + +namespace explicit_instantiation +{ + template struct C + { + virtual void f() + { + static_assert(sizeof(T) == 0, ""); + } + }; + + extern template struct C; + /* A subsequent explicit instantiation must instantiate the virtual member. */ + template struct C; +} + +namespace explicit_instantiation_out_of_class +{ + template struct C + { + virtual void f(); + }; + + template void C::f() + { + static_assert(sizeof(T) == 0, ""); + } + + extern template struct C; + template struct C; +} + +namespace explicit_instantiation_inline_out_of_class +{ + template struct C + { + virtual void f(); + }; + + template inline void C::f() + { + static_assert(sizeof(T) == 0, ""); + } + + extern template struct C; + template struct C; +} + +namespace derived_vtable +{ + template struct C + { + virtual void f() + { + static_assert(sizeof(T) == 0, ""); + } + }; + + extern template struct C; + struct D : C + {}; + + /* The derived vtable still needs the inherited virtual member. */ + D *g() + { + return new D(); + } +} + +namespace derived_vtable_inline_out_of_class +{ + template struct C + { + virtual void f(); + }; + + template inline void C::f() + { + static_assert(sizeof(T) == 0, ""); + } + + extern template struct C; + struct D : C + {}; + + D *g() + { + return new D(); + } +} + +namespace internal_linkage +{ + namespace + { + struct Local {}; + } + + template struct C + { + virtual void f() + { + static_assert(sizeof(T) == 0, ""); + } + }; + + extern template struct C; + /* A specialization with internal linkage still gets a local vtable. */ + C c; +} + +namespace internal_linkage_inline_out_of_class +{ + namespace + { + struct Local {}; + } + + template struct C + { + virtual void f(); + }; + + template inline void C::f() + { + static_assert(sizeof(T) == 0, ""); + } + + extern template struct C; + C c; +} + +namespace internal_linkage_template +{ + namespace + { + template struct C + { + virtual void f() + { + static_assert(sizeof(T) == 0, ""); + } + }; + + extern template struct C; + + /* The template itself has internal linkage, even with an external arg. */ + C c; + } + + void *g() + { + return &c; + } +} + +namespace internal_linkage_nontype_argument +{ + static int value; + + template struct C + { + virtual void f() + { + static_assert(P == nullptr, ""); + } + }; + + extern template struct C<&value>; + + /* A pointer to an internal-linkage object makes the instance local too. */ + C<&value> c; +} + +namespace direct_virtual_call +{ + template struct C + { + virtual void f() + { + static_assert(sizeof(T) == 0, ""); + } + }; + + extern template struct C; + + /* Suppressing the vtable must not suppress a qualified inline call. */ + void g(C& c) + { + c.C::f(); + } +} + +namespace direct_virtual_call_inline_out_of_class +{ + template struct C + { + virtual void f(); + }; + + template inline void C::f() + { + static_assert(sizeof(T) == 0, ""); + } + + extern template struct C; + + void g(C& c) + { + c.C::f(); + } +} + +namespace specialized_nested_class +{ + template struct Base + { + virtual void f() + { + static_assert(sizeof(T) == 0, ""); + } + }; + + extern template struct Base; + + template struct C + { + struct D; + }; + + template<> struct C::D : Base {}; + + /* Propagation of suppression must not suppress a specialized class's + vtable or its inherited virtual functions. */ + extern template struct C; + C::D d; +} + +namespace nontemplate_nested_class +{ + template struct Base + { + virtual void f() + { + static_assert(sizeof(T) == 0, ""); + } + }; + + extern template struct Base; + + template struct C + { + struct D; + }; + + template<> struct C::D + { + struct E : Base {}; + }; + + /* Suppression also propagates to E, which is not a template instance. */ + extern template struct C; + C::D::E e; +} + +namespace unsuppressed_specialization +{ + template struct C + { + virtual void f() + { + static_assert(N != 2, ""); + } + }; + + extern template struct C<1>; + + /* Suppression applies only to the named specialization. */ + C<2> c; +} + +#if defined(__GNUC__) && !defined(__clang__) +namespace inline_template +{ + template struct C + { + virtual void f() + { + static_assert(sizeof(T) == 0, ""); + } + }; + + extern template struct C; + /* GNU inline template explicitly requests a local vtable. */ + inline template struct C; +} + +namespace inline_template_inline_out_of_class +{ + template struct C + { + virtual void f(); + }; + + template inline void C::f() + { + static_assert(sizeof(T) == 0, ""); + } + + extern template struct C; + inline template struct C; +} +#endif diff --git a/tests/tests/regressions/gh-431-ia64.sft.cpp b/tests/tests/regressions/gh-431-ia64.sft.cpp new file mode 100644 index 0000000000..fafeccaebd --- /dev/null +++ b/tests/tests/regressions/gh-431-ia64.sft.cpp @@ -0,0 +1,105 @@ +//type:fp +//options:--c++11:--gnu_version 150200:--clang_version 220100:--ms_c++20 --microsoft_version 1950 +//options_all:-tused +//requires:IA64_ABI=1 + +namespace in_class +{ + template + struct C + { + virtual void f() + { + static_assert(N != 1, ""); + } + }; + + extern template class C<1>; + + C<1> c; +} + +namespace external_linkage +{ + struct External {}; + + template struct C + { + C() {} + ~C() {} + + virtual void f() + { + static_assert(sizeof(T) == 0, ""); + } + }; + + extern template struct C; + + /* Both user-defined bodies are checked, but the vtable is suppressed. */ + void g() + { + C c; + } +} + +namespace partial_specialization +{ + template struct C; + + template struct C + { + C() {} + virtual ~C() {} + + virtual void f() + { + static_assert(sizeof(T) == 0, ""); + } + }; + + extern template struct C; + + /* A partial specialization is still subject to extern template. */ + void g() + { + C c; + } +} + +#if defined(__GNUC__) || defined(__clang__) +namespace hidden_external_linkage +{ + template struct __attribute__((visibility("hidden"))) C + { + virtual void f() + { + static_assert(sizeof(T) == 0, ""); + } + }; + + extern template struct C; + + /* Hidden visibility is not internal linkage: suppress this vtable too. */ + C c; +} +#endif + +namespace inline_out_of_class +{ + template + struct C + { + virtual void f(); + }; + + template + inline void C::f() + { + static_assert(N != 1, ""); + } + + extern template class C<1>; + + C<1> c; +} diff --git a/tests/tests/regressions/gh-431-link/.t1.rto/default.1.1.txt b/tests/tests/regressions/gh-431-link/.t1.rto/default.1.1.txt new file mode 100644 index 0000000000..64d6aa5453 --- /dev/null +++ b/tests/tests/regressions/gh-431-link/.t1.rto/default.1.1.txt @@ -0,0 +1,3 @@ +eccp -DTEST_NUMBER=1 --c++11 -tused t2.cpp Test_name.c +t2.cpp: +Test_name.c: diff --git a/tests/tests/regressions/gh-431-link/.t1.rto/default.1.2.txt b/tests/tests/regressions/gh-431-link/.t1.rto/default.1.2.txt new file mode 100644 index 0000000000..ff2642c6d5 --- /dev/null +++ b/tests/tests/regressions/gh-431-link/.t1.rto/default.1.2.txt @@ -0,0 +1 @@ +./a.out diff --git a/tests/tests/regressions/gh-431-link/t1.mft.cpp b/tests/tests/regressions/gh-431-link/t1.mft.cpp new file mode 100644 index 0000000000..28cdb3ce45 --- /dev/null +++ b/tests/tests/regressions/gh-431-link/t1.mft.cpp @@ -0,0 +1,18 @@ +//type:rp +//options:--c++11 -tused t2.cpp +//source_files:t2.cpp + +template +struct C { + virtual int f() { return N; } +}; + +extern template struct C<1>; + +C<1> c; +C<1> *p = &c; + +int main() +{ + return p->f() != 1; +} diff --git a/tests/tests/regressions/gh-431-link/t2.cpp b/tests/tests/regressions/gh-431-link/t2.cpp new file mode 100644 index 0000000000..27d556805f --- /dev/null +++ b/tests/tests/regressions/gh-431-link/t2.cpp @@ -0,0 +1,6 @@ +template +struct C { + virtual int f() { return N; } +}; + +template struct C<1>; diff --git a/tests/tests/regressions/gh-431.sft.cpp b/tests/tests/regressions/gh-431.sft.cpp new file mode 100644 index 0000000000..7e29b3c582 --- /dev/null +++ b/tests/tests/regressions/gh-431.sft.cpp @@ -0,0 +1,44 @@ +//type:fp +//options:--c++11:--gnu_version 150200:--clang_version 220100:--ms_c++20 --microsoft_version 1950 +//options_all:-tused + +namespace out_of_class +{ + template + struct C + { + virtual void f(); + }; + + template + void C::f() + { + static_assert(N != 1, ""); + } + + extern template class C<1>; + + C<1> c; +} + +namespace constant_evaluation +{ + template + struct C + { + static constexpr int f() + { + return 42; + } + + constexpr int g() const + { + return 43; + } + }; + + extern template struct C; + + static_assert(C::f() == 42, ""); + static_assert(C{}.g() == 43, ""); +}