summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Sema/Sema.h2
-rw-r--r--clang/lib/Sema/SemaDecl.cpp7
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp3
-rw-r--r--clang/test/OpenMP/declare_variant_ast_print.cpp19
-rw-r--r--clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp12
-rw-r--r--clang/test/OpenMP/declare_variant_messages.cpp12
6 files changed, 38 insertions, 17 deletions
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index a77cbc09e40..28180ed6d11 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -9128,7 +9128,7 @@ public:
const PartialDiagnosticAt &NoteCausedDiagIDAt,
const PartialDiagnosticAt &NoSupportDiagIDAt,
const PartialDiagnosticAt &DiffDiagIDAt, bool TemplatesSupported,
- bool ConstexprSupported);
+ bool ConstexprSupported, bool CLinkageMayDiffer);
/// Function tries to capture lambda's captured variables in the OpenMP region
/// before the original lambda is captured.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index db89e54c517..4a027d86819 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9685,7 +9685,7 @@ bool Sema::areMultiversionVariantFunctionsCompatible(
const PartialDiagnosticAt &NoteCausedDiagIDAt,
const PartialDiagnosticAt &NoSupportDiagIDAt,
const PartialDiagnosticAt &DiffDiagIDAt, bool TemplatesSupported,
- bool ConstexprSupported) {
+ bool ConstexprSupported, bool CLinkageMayDiffer) {
enum DoesntSupport {
FuncTemplates = 0,
VirtFuncs = 1,
@@ -9778,7 +9778,7 @@ bool Sema::areMultiversionVariantFunctionsCompatible(
if (OldFD->getStorageClass() != NewFD->getStorageClass())
return Diag(DiffDiagIDAt.first, DiffDiagIDAt.second) << StorageClass;
- if (OldFD->isExternC() != NewFD->isExternC())
+ if (!CLinkageMayDiffer && OldFD->isExternC() != NewFD->isExternC())
return Diag(DiffDiagIDAt.first, DiffDiagIDAt.second) << Linkage;
if (CheckEquivalentExceptionSpec(
@@ -9831,7 +9831,8 @@ static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD,
PartialDiagnosticAt(NewFD->getLocation(),
S.PDiag(diag::err_multiversion_diff)),
/*TemplatesSupported=*/false,
- /*ConstexprSupported=*/!IsCPUSpecificCPUDispatchMVType);
+ /*ConstexprSupported=*/!IsCPUSpecificCPUDispatchMVType,
+ /*CLinkageMayDiffer=*/false);
}
/// Check the validity of a multiversion function declaration that is the
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index b0fd6aa5fd5..ff7e1c004c5 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -5109,7 +5109,8 @@ Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
PartialDiagnosticAt(VariantRef->getExprLoc(),
PDiag(diag::err_omp_declare_variant_diff)
<< FD->getLocation()),
- /*TemplatesSupported=*/true, /*ConstexprSupported=*/false))
+ /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
+ /*CLinkageMayDiffer=*/true))
return None;
return std::make_pair(FD, cast<Expr>(DRE));
}
diff --git a/clang/test/OpenMP/declare_variant_ast_print.cpp b/clang/test/OpenMP/declare_variant_ast_print.cpp
index c79b6b8da10..984aafac762 100644
--- a/clang/test/OpenMP/declare_variant_ast_print.cpp
+++ b/clang/test/OpenMP/declare_variant_ast_print.cpp
@@ -201,3 +201,22 @@ void bazzzz() {
s.foo1();
static_f();
}
+
+// CHECK: int fn_linkage_variant();
+// CHECK: extern "C" {
+// CHECK: #pragma omp declare variant(fn_linkage_variant) match(implementation={vendor(xxx)})
+// CHECK: int fn_linkage();
+// CHECK: }
+int fn_linkage_variant();
+extern "C" {
+#pragma omp declare variant(fn_linkage_variant) match(implementation = {vendor(xxx)})
+int fn_linkage();
+}
+
+// CHECK: extern "C" int fn_linkage_variant1()
+// CHECK: #pragma omp declare variant(fn_linkage_variant1) match(implementation={vendor(xxx)})
+// CHECK: int fn_linkage1();
+extern "C" int fn_linkage_variant1();
+#pragma omp declare variant(fn_linkage_variant1) match(implementation = {vendor(xxx)})
+int fn_linkage1();
+
diff --git a/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp b/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp
index b0940751b76..1c200cca909 100644
--- a/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp
+++ b/clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp
@@ -22,6 +22,8 @@
// CHECK-DAG: ret i32 7
// CHECK-DAG: ret i32 82
// CHECK-DAG: ret i32 83
+// CHECK-DAG: ret i32 85
+// CHECK-DAG: ret i32 86
// CHECK-NOT: ret i32 {{1|4|81|84}}
#ifndef HEADER
@@ -110,4 +112,14 @@ static int prio1_() { return 1; }
int int_fn() { return prio1_(); }
+int fn_linkage_variant() { return 85; }
+extern "C" {
+#pragma omp declare variant(fn_linkage_variant) match(implementation = {vendor(llvm)})
+int fn_linkage() { return 1; }
+}
+
+extern "C" int fn_linkage_variant1() { return 86; }
+#pragma omp declare variant(fn_linkage_variant1) match(implementation = {vendor(llvm)})
+int fn_linkage1() { return 1; }
+
#endif // HEADER
diff --git a/clang/test/OpenMP/declare_variant_messages.cpp b/clang/test/OpenMP/declare_variant_messages.cpp
index aee5544bf29..f80c93c312d 100644
--- a/clang/test/OpenMP/declare_variant_messages.cpp
+++ b/clang/test/OpenMP/declare_variant_messages.cpp
@@ -165,18 +165,6 @@ inline int fn_inline_variant1();
#pragma omp declare variant(fn_inline_variant1) match(xxx = {})
int fn_inline1();
-int fn_linkage_variant();
-extern "C" {
-// expected-error@+1 {{function with '#pragma omp declare variant' has a different linkage}}
-#pragma omp declare variant(fn_linkage_variant) match(xxx = {})
-int fn_linkage();
-}
-
-extern "C" int fn_linkage_variant1();
-// expected-error@+1 {{function with '#pragma omp declare variant' has a different linkage}}
-#pragma omp declare variant(fn_linkage_variant1) match(xxx = {})
-int fn_linkage1();
-
auto fn_deduced_variant() { return 0; }
#pragma omp declare variant(fn_deduced_variant) match(xxx = {})
int fn_deduced();
OpenPOWER on IntegriCloud