diff options
-rw-r--r-- | clang/include/clang/Sema/Sema.h | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 3 | ||||
-rw-r--r-- | clang/test/OpenMP/declare_variant_ast_print.cpp | 19 | ||||
-rw-r--r-- | clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp | 12 | ||||
-rw-r--r-- | clang/test/OpenMP/declare_variant_messages.cpp | 12 |
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(); |