aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/g++.dg/ext/attr-noinline.C
blob: 54f69d580ea362b43fe1414ad4e833e82bf79b5c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// 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 <class T>
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<Special>()
{
  // 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<void>();
// { dg-final { scan-tree-dump-not "falways_inline_none<void> *\\(\\)" "optimized" } }
}

void test_keep_special_1 (void)
{
  // Should not be inlined.
  falways_inline_none<Special>();
// { dg-final { scan-tree-dump-times "falways_inline_none<Special> *\\(\\);" 1 "optimized" } }
}


template <class T>
inline void __attribute__ ((always_inline))
falways_inline_noinline ()
{
  asm ("");   // induce a no-op "side-effect"
}

template <>
void __attribute__ ((noinline))
falways_inline_noinline<Special>() { 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<void>();
// { dg-final { scan-tree-dump-not "falways_inline_noinline<void> *\\(\\)" "optimized" } }
}

void test_keep_special_2 (void)
{
  falways_inline_noinline<Special>();
// { dg-final { scan-tree-dump-times "falways_inline_noinline<Special> *\\(\\);" 1 "optimized" } }
}


template <class T>
inline void
fnone_always_inline ()
{
  asm ("");   // induce a no-op "side-effect"
}

template <>
inline void __attribute__ ((always_inline))
fnone_always_inline<Special>() { 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<void>();
// { dg-final { scan-tree-dump-times "fnone_always_inline<void> *\\(\\);" 1 "optimized" } }
}

void test_elim_special_3 (void)
{
  fnone_always_inline<Special>();
// { dg-final { scan-tree-dump-not "fnone_always_inline<Special> *\\(\\);" "optimized" } }
}


template <class T>
void __attribute__ ((noinline))
fnoinline_always_inline ()
{
  asm ("");   // induce a no-op "side-effect"
}

template <>
inline void __attribute__ ((always_inline))
fnoinline_always_inline<Special>()    // { 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<void>();
// { dg-final { scan-tree-dump-times "fnoinline_always_inline<void> *\\(\\);" 1 "optimized" } }
}

void test_elim_special_4 (void)
{
  fnoinline_always_inline<Special>();
// { dg-final { scan-tree-dump-not "fnoinline_always_inline<Special> *\\(\\);" "optimized" } }
}