131
|
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))
|
|
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
|
|
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
|
|
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))
|
|
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
|
|
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
|
|
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 }
|