1 // Bug c++/83871 - wrong code due to attributes on distinct template 2 // specializations 3 // Test to verify that an explicit template specifialization does not 4 // "inherit" attributes always_inline or noinline from a primary template 5 // declared with either. Unlike attr-noinline.C, this test enables 6 // optimization to verify that noinline prevents inlining. 7 // { dg-do compile } 8 // { dg-options "-O2 -Wall -fdump-tree-optimized" } 9 10 enum Special { }; 11 12 int global; 13 14 template <class T> 15 inline void __attribute__ ((always_inline)) falways_inline_noinline()16falways_inline_noinline () 17 { 18 // Create a side-effect that's unique to this function. 19 global = __LINE__; 20 } 21 22 template <> 23 void __attribute__ ((noinline)) 24 falways_inline_noinline<Special>() 25 { 26 global = __LINE__; 27 } 28 29 // Verify that a call to the primary is inlined but one to 30 // the explicit specialization is not. 31 test_elim_primary_1(void)32void test_elim_primary_1 (void) 33 { 34 // Should be inlined. 35 falways_inline_noinline<void>(); 36 // { dg-final { scan-tree-dump-not "falways_inline_noinline<void> *\\(\\)" "optimized" } } 37 } 38 test_keep_special_1(void)39void test_keep_special_1 (void) 40 { 41 // Should not be inlined. 42 falways_inline_noinline<Special>(); 43 // { dg-final { scan-tree-dump-times "falways_inline_noinline<Special> *\\(\\);" 1 "optimized" } } 44 } 45 46 47 template <class T> 48 void __attribute__ ((noinline)) fnoinline_always_inline()49fnoinline_always_inline () 50 { 51 global = __LINE__; 52 } 53 54 template <> 55 inline void __attribute__ ((always_inline)) 56 fnoinline_always_inline<Special>() // { dg-bogus "follows declaration" } 57 { 58 global = __LINE__; 59 } 60 test_keep_primary_2(void)61void test_keep_primary_2 (void) 62 { 63 // Should not be inlined. 64 fnoinline_always_inline<void>(); 65 // { dg-final { scan-tree-dump-times "fnoinline_always_inline<void> *\\(\\);" 1 "optimized" } } 66 } 67 test_elim_special_2(void)68void test_elim_special_2 (void) 69 { 70 // Should be inlined. 71 fnoinline_always_inline<Special>(); 72 // { dg-final { scan-tree-dump-not "fnoinline_always_inline<Special> *\\(\\);" "optimized" } } 73 } 74