xref: /llvm-project/clang/test/SemaCXX/attr-target-mv.cpp (revision 8282c58d9b1cd5b6df89ee3f68438fe0ee672f7f)
1 // RUN: %clang_cc1 -triple x86_64-linux-gnu  -fsyntax-only -verify -fexceptions -fcxx-exceptions %s -std=c++14
2 void __attribute__((target("default"))) invalid_features(void);
3 //expected-error@+2 {{function declaration is missing 'target' attribute in a multiversioned function}}
4 //expected-warning@+1 {{unsupported 'hello_world' in the 'target' attribute string; 'target' attribute ignored}}
5 void __attribute__((target("hello_world"))) invalid_features(void);
6 //expected-error@+1 {{function multiversioning doesn't support feature 'no-sse4.2'}}
7 void __attribute__((target("no-sse4.2"))) invalid_features(void);
8 
9 void __attribute__((target("sse4.2"))) no_default(void);
10 void __attribute__((target("arch=sandybridge")))  no_default(void);
11 
12 void use1(void){
13   // expected-error@+1 {{no matching function for call to 'no_default'}}
14   no_default();
15 }
16 constexpr int __attribute__((target("sse4.2"))) foo(void) { return 0; }
17 constexpr int __attribute__((target("arch=sandybridge"))) foo(void);
18 //expected-error@+1 {{multiversioned function declaration has a different constexpr specification}}
19 int __attribute__((target("arch=ivybridge"))) foo(void) {return 1;}
20 constexpr int __attribute__((target("default"))) foo(void) { return 2; }
21 
22 int __attribute__((target("sse4.2"))) foo2(void) { return 0; }
23 //expected-error@+1 {{multiversioned function declaration has a different constexpr specification}}
24 constexpr int __attribute__((target("arch=sandybridge"))) foo2(void);
25 int __attribute__((target("arch=ivybridge"))) foo2(void) {return 1;}
26 int __attribute__((target("default"))) foo2(void) { return 2; }
27 
28 static int __attribute__((target("sse4.2"))) bar(void) { return 0; }
29 static int __attribute__((target("arch=sandybridge"))) bar(void);
30 //expected-error@+1 {{multiversioned function declaration has a different linkage}}
31 int __attribute__((target("arch=ivybridge"))) bar(void) {return 1;}
32 static int __attribute__((target("default"))) bar(void) { return 2; }
33 
34 int __attribute__((target("sse4.2"))) bar2(void) { return 0; }
35 //expected-error@+1 {{multiversioned function declaration has a different linkage}}
36 static int __attribute__((target("arch=sandybridge"))) bar2(void);
37 int __attribute__((target("arch=ivybridge"))) bar2(void) {return 1;}
38 int __attribute__((target("default"))) bar2(void) { return 2; }
39 
40 
41 // no diagnostic, since this doesn't change the linkage.
42 int __attribute__((target("sse4.2"))) bar3(void) { return 0; }
43 extern int __attribute__((target("arch=sandybridge"))) bar2(void);
44 
45 namespace {
46 int __attribute__((target("sse4.2"))) bar4(void) { return 0; }
47 static int __attribute__((target("arch=sandybridge"))) bar4(void);
48 }
49 
50 inline int __attribute__((target("sse4.2"))) baz(void) { return 0; }
51 inline int __attribute__((target("arch=sandybridge"))) baz(void);
52 //expected-error@+1 {{multiversioned function declaration has a different inline specification}}
53 int __attribute__((target("arch=ivybridge"))) baz(void) {return 1;}
54 inline int __attribute__((target("default"))) baz(void) { return 2; }
55 
56 int __attribute__((target("sse4.2"))) baz2(void) { return 0; }
57 //expected-error@+1 {{multiversioned function declaration has a different inline specification}}
58 inline int __attribute__((target("arch=sandybridge"))) baz2(void);
59 int __attribute__((target("arch=ivybridge"))) baz2(void) {return 1;}
60 int __attribute__((target("default"))) baz2(void) { return 2; }
61 
62 float __attribute__((target("sse4.2"))) bock(void) { return 0; }
63 //expected-error@+1 {{multiversioned function declaration has a different return type}}
64 int __attribute__((target("arch=sandybridge"))) bock(void);
65 //expected-error@+1 {{multiversioned function declaration has a different return type}}
66 int __attribute__((target("arch=ivybridge"))) bock(void) {return 1;}
67 //expected-error@+1 {{multiversioned function declaration has a different return type}}
68 int __attribute__((target("default"))) bock(void) { return 2; }
69 
70 int __attribute__((target("sse4.2"))) bock2(void) { return 0; }
71 //expected-error@+1 {{multiversioned function declaration has a different return type}}
72 float __attribute__((target("arch=sandybridge"))) bock2(void);
73 int __attribute__((target("arch=ivybridge"))) bock2(void) {return 1;}
74 int __attribute__((target("default"))) bock2(void) { return 2; }
75 
76 auto __attribute__((target("sse4.2"))) bock3(void) -> int { return 0; }
77 //expected-error@+1 {{multiversioned function declaration has a different return type}}
78 auto __attribute__((target("arch=sandybridge"))) bock3(void) -> short { return (short)0;}
79 
80 int __attribute__((target("sse4.2"))) bock4(void) noexcept(false) { return 0; }
81 //expected-error@+2 {{exception specification in declaration does not match previous declaration}}
82 //expected-note@-2 {{previous declaration is here}}
83 int __attribute__((target("arch=sandybridge"))) bock4(void) noexcept(true) { return 1;}
84 
85 // FIXME: Add support for templates and virtual functions!
86 template<typename T>
87 int __attribute__((target("sse4.2"))) foo(T) { return 0; }
88 // expected-error@+2 {{multiversioned functions do not yet support function templates}}
89 template<typename T>
90 int __attribute__((target("arch=sandybridge"))) foo(T);
91 
92 // expected-error@+2 {{multiversioned functions do not yet support function templates}}
93 template<typename T>
94 int __attribute__((target("default"))) foo(T) { return 2; }
95 
96 struct S {
97   template<typename T>
98   int __attribute__((target("sse4.2"))) foo(T) { return 0; }
99   // expected-error@+2 {{multiversioned functions do not yet support function templates}}
100   template<typename T>
101   int __attribute__((target("arch=sandybridge"))) foo(T);
102 
103   // expected-error@+2 {{multiversioned functions do not yet support function templates}}
104   template<typename T>
105   int __attribute__((target("default"))) foo(T) { return 2; }
106 
107   // expected-error@+1 {{multiversioned functions do not yet support virtual functions}}
108   virtual void __attribute__((target("default"))) virt();
109 };
110 
111 extern "C" {
112 int __attribute__((target("sse4.2"))) diff_mangle(void) { return 0; }
113 }
114 //expected-error@+1 {{multiversioned function declaration has a different language linkage}}
115 int __attribute__((target("arch=sandybridge"))) diff_mangle(void) { return 0; }
116 
117 // expected-error@+1 {{multiversioned functions do not yet support deduced return types}}
118 auto __attribute__((target("default"))) deduced_return(void) { return 0; }
119 
120 auto __attribute__((target("default"))) trailing_return(void)-> int { return 0; }
121 
122 __attribute__((target("default"))) void DiffDecl();
123 namespace N {
124 using ::DiffDecl;
125 // expected-error@+3 {{declaration conflicts with target of using declaration already in scope}}
126 // expected-note@-4 {{target of using declaration}}
127 // expected-note@-3 {{using declaration}}
128 __attribute__((target("arch=sandybridge"))) void DiffDecl();
129 } // namespace N
130 
131 struct SpecialFuncs {
132   // expected-error@+1 {{multiversioned functions do not yet support constructors}}
133   __attribute__((target("default"))) SpecialFuncs();
134   // expected-error@+1 {{multiversioned functions do not yet support destructors}}
135   __attribute__((target("default"))) ~SpecialFuncs();
136 
137   // expected-error@+1 {{multiversioned functions do not yet support defaulted functions}}
138   SpecialFuncs& __attribute__((target("default"))) operator=(const SpecialFuncs&) = default;
139   // expected-error@+1 {{multiversioned functions do not yet support deleted functions}}
140   SpecialFuncs& __attribute__((target("default"))) operator=(SpecialFuncs&&) = delete;
141 };
142 
143 class Secret {
144   int i = 0;
145   __attribute__((target("default")))
146   friend int SecretAccessor(Secret &s);
147   __attribute__((target("arch=sandybridge")))
148   friend int SecretAccessor(Secret &s);
149 };
150 
151 __attribute__((target("default")))
152 int SecretAccessor(Secret &s) {
153   return s.i;
154 }
155 
156 __attribute__((target("arch=sandybridge")))
157 int SecretAccessor(Secret &s) {
158   return s.i + 2;
159 }
160 
161 __attribute__((target("arch=ivybridge")))
162 int SecretAccessor(Secret &s) {
163   //expected-error@+2{{'i' is a private member of 'Secret'}}
164   //expected-note@-20{{implicitly declared private here}}
165   return s.i + 3;
166 }
167 
168 constexpr int __attribute__((target("sse4.2"))) constexpr_foo(void) {
169   return 0;
170 }
171 constexpr int __attribute__((target("arch=sandybridge"))) constexpr_foo(void);
172 constexpr int __attribute__((target("arch=ivybridge"))) constexpr_foo(void) {
173   return 1;
174 }
175 constexpr int __attribute__((target("default"))) constexpr_foo(void) {
176   return 2;
177 }
178 
179 void constexpr_test() {
180   static_assert(foo() == 2, "Should call 'default' in a constexpr context");
181 }
182 
183 struct BadOutOfLine { // #defined-here
184   int __attribute__((target("sse4.2"))) foo(int);
185   int __attribute__((target("default"))) foo(int);
186 };
187 
188 int __attribute__((target("sse4.2"))) BadOutOfLine::foo(int) { return 0; }
189 int __attribute__((target("default"))) BadOutOfLine::foo(int) { return 1; }
190 // expected-error@+4 {{out-of-line definition of 'foo' does not match any declaration in 'BadOutOfLine'}}
191 // expected-note@#defined-here {{defined here}}
192 // expected-note@-4 {{member declaration nearly matches}}
193 // expected-note@-4 {{member declaration nearly matches}}
194 int __attribute__((target("arch=atom"))) BadOutOfLine::foo(int) { return 1; }
195