// Bug c++/83871 - wrong code due to attributes on distinct template // specializations // Test to verify that an explicit template specifialization does not // "inherit" attributes always_inline or noinline from a primary template // declared with either. The test disables optimization to verify that // always_inline forces inlining. // { dg-do compile } // { dg-options "-O0 -Wall -fdump-tree-optimized" } enum Special { }; template inline void __attribute__ ((always_inline)) falways_inline_none () { // Primary template should always be inlined, even without optimization. asm (""); // induce a no-op "side-effect" } template <> inline void falways_inline_none() { // The specialization should not be inlined without optimization, even // though it's declared inline. asm (""); } // Verify that a call to the primary is inlined but one to // the explicit specialization is not. void test_elim_primary_1 (void) { // Should be inlined. falways_inline_none(); // { dg-final { scan-tree-dump-not "falways_inline_none *\\(\\)" "optimized" } } } void test_keep_special_1 (void) { // Should not be inlined. falways_inline_none(); // { dg-final { scan-tree-dump-times "falways_inline_none *\\(\\);" 1 "optimized" } } } template inline void __attribute__ ((always_inline)) falways_inline_noinline () { asm (""); // induce a no-op "side-effect" } template <> void __attribute__ ((noinline)) falways_inline_noinline() { asm (""); } // Verify that a call to the primary is inlined but one to // the explicit specialization is not. void test_elim_primary_2 (void) { falways_inline_noinline(); // { dg-final { scan-tree-dump-not "falways_inline_noinline *\\(\\)" "optimized" } } } void test_keep_special_2 (void) { falways_inline_noinline(); // { dg-final { scan-tree-dump-times "falways_inline_noinline *\\(\\);" 1 "optimized" } } } template inline void fnone_always_inline () { asm (""); // induce a no-op "side-effect" } template <> inline void __attribute__ ((always_inline)) fnone_always_inline() { asm (""); } // Verify that a call to the primary is not inlined but one to // the explicit specialization is. void test_keep_primary_3 (void) { fnone_always_inline(); // { dg-final { scan-tree-dump-times "fnone_always_inline *\\(\\);" 1 "optimized" } } } void test_elim_special_3 (void) { fnone_always_inline(); // { dg-final { scan-tree-dump-not "fnone_always_inline *\\(\\);" "optimized" } } } template void __attribute__ ((noinline)) fnoinline_always_inline () { asm (""); // induce a no-op "side-effect" } template <> inline void __attribute__ ((always_inline)) fnoinline_always_inline() // { dg-bogus "follows declaration" } { asm (""); } // Verify that a call to the primary is not inlined but one to // the explicit specialization is. void test_keep_primary_4 (void) { fnoinline_always_inline(); // { dg-final { scan-tree-dump-times "fnoinline_always_inline *\\(\\);" 1 "optimized" } } } void test_elim_special_4 (void) { fnoinline_always_inline(); // { dg-final { scan-tree-dump-not "fnoinline_always_inline *\\(\\);" "optimized" } } }