summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErich Keane <erich.keane@intel.com>2019-08-28 20:59:25 +0000
committerErich Keane <erich.keane@intel.com>2019-08-28 20:59:25 +0000
commitfb0b88ae111d441128ad35e287fed3b56d704e21 (patch)
tree417254b84ffabf1d012dbc31299f53ef5f9702d4
parent4c11f17103c599c2af4fffcd5d670e495119cc0c (diff)
downloadclang-fb0b88ae111d441128ad35e287fed3b56d704e21.tar.gz
Fix always_inline 'target' compatibility check code for Lambdas
The previous version of this used CurFuncDecl in CodeGenFunction, however this doesn't include lambdas. However, CurCodeDecl DOES. Switch the check to use CurCodeDecl so that the actual function being emitted gets checked, preventing an error in ISEL. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@370261 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp2
-rw-r--r--test/CodeGenCXX/target-features-error.cpp46
2 files changed, 46 insertions, 2 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 4b7986f716..e3fb205232 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -2203,7 +2203,7 @@ void CodeGenFunction::checkTargetFeatures(SourceLocation Loc,
// Get the current enclosing function if it exists. If it doesn't
// we can't check the target features anyhow.
- const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl);
+ const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl);
if (!FD)
return;
diff --git a/test/CodeGenCXX/target-features-error.cpp b/test/CodeGenCXX/target-features-error.cpp
index 44179deaf3..28fe4d0e72 100644
--- a/test/CodeGenCXX/target-features-error.cpp
+++ b/test/CodeGenCXX/target-features-error.cpp
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -S -verify -o -
+// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -S -verify -o - -DTEST1
+// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -S -verify -o - -DTEST2
+// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -S -verify -o - -DTEST3
struct S {
__attribute__((always_inline, target("avx512f")))
@@ -9,9 +11,51 @@ struct S {
void operator()(){ }
};
+__attribute__((always_inline, target("avx512f")))
+void free_func(){}
+
+#ifdef TEST1
void usage(S & s) {
s.foo(); // expected-error {{'foo' requires target feature 'avx512f'}}
(void)(int)s; // expected-error {{'operator int' requires target feature 'avx512f'}}
s(); // expected-error {{'operator()' requires target feature 'avx512f'}}
+ free_func(); // expected-error{{'free_func' requires target feature 'avx512f'}}
+
+}
+#endif
+
+#ifdef TEST2
+__attribute__((target("avx512f")))
+void usage(S & s) {
+ s.foo();
+ (void)(int)s;
+ s();
+
+ [&s] {
+ s.foo(); // expected-error {{'foo' requires target feature 'avx512f'}}
+ (void)(int) s; // expected-error {{'operator int' requires target feature 'avx512f'}}
+ s(); // expected-error {{'operator()' requires target feature 'avx512f'}}
+ free_func(); // expected-error{{'free_func' requires target feature 'avx512f'}}
+ }();
+}
+#endif
+
+#ifdef TEST3
+void usage(S & s) {
+
+ [&s] () __attribute__((target("avx512f"))) {
+ s.foo();
+ (void)(int) s;
+ s();
+ free_func();
+ }();
+
+ [&s] {
+ s.foo(); // expected-error {{'foo' requires target feature 'avx512f'}}
+ (void)(int) s; // expected-error {{'operator int' requires target feature 'avx512f'}}
+ s(); // expected-error {{'operator()' requires target feature 'avx512f'}}
+ free_func(); // expected-error{{'free_func' requires target feature 'avx512f'}}
+ }();
}
+#endif