[OPENMP50]Allow functions in declare variant directive to have different
authorAlexey Bataev <a.bataev@hotmail.com>
Tue, 8 Oct 2019 14:56:20 +0000 (14:56 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Tue, 8 Oct 2019 14:56:20 +0000 (14:56 +0000)
C linkage.

After some discussion with OpenMP developers, it was decided that the
functions with the different C linkage can be used in declare variant
directive.

llvm-svn: 374057

clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaOpenMP.cpp
clang/test/OpenMP/declare_variant_ast_print.cpp
clang/test/OpenMP/declare_variant_implementation_vendor_codegen.cpp
clang/test/OpenMP/declare_variant_messages.cpp

index a77cbc0..28180ed 100644 (file)
@@ -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.
index db89e54..4a027d8 100644 (file)
@@ -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
index b0fd6aa..ff7e1c0 100644 (file)
@@ -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));
 }
index c79b6b8..984aafa 100644 (file)
@@ -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();
+
index b094075..1c200cc 100644 (file)
@@ -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
index aee5544..f80c93c 100644 (file)
@@ -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();