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()16 falways_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)32 void 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)39 void 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()49 fnoinline_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)61 void 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)68 void 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