erichkeane created this revision.
erichkeane added a reviewer: aaron.ballman.
erichkeane requested review of this revision.

Allow multiversioning declarations to match when the actual formal
linkage matches, not just when the storage class is identical.
Additionally, change the ambiguous 'linkage' mismatch to be more
specific and say 'language linkage'.


https://reviews.llvm.org/D110255

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDecl.cpp
  clang/test/SemaCXX/attr-cpuspecific.cpp
  clang/test/SemaCXX/attr-target-mv.cpp

Index: clang/test/SemaCXX/attr-target-mv.cpp
===================================================================
--- clang/test/SemaCXX/attr-target-mv.cpp
+++ clang/test/SemaCXX/attr-target-mv.cpp
@@ -27,17 +27,26 @@
 
 static int __attribute__((target("sse4.2"))) bar(void) { return 0; }
 static int __attribute__((target("arch=sandybridge"))) bar(void);
-//expected-error@+1 {{multiversioned function declaration has a different storage class}}
+//expected-error@+1 {{multiversioned function declaration has a different linkage}}
 int __attribute__((target("arch=ivybridge"))) bar(void) {return 1;}
 static int __attribute__((target("default"))) bar(void) { return 2; }
 
 int __attribute__((target("sse4.2"))) bar2(void) { return 0; }
-//expected-error@+1 {{multiversioned function declaration has a different storage class}}
+//expected-error@+1 {{multiversioned function declaration has a different linkage}}
 static int __attribute__((target("arch=sandybridge"))) bar2(void);
 int __attribute__((target("arch=ivybridge"))) bar2(void) {return 1;}
 int __attribute__((target("default"))) bar2(void) { return 2; }
 
 
+// no diagnostic, since this doesn't change the linkage.
+int __attribute__((target("sse4.2"))) bar3(void) { return 0; }
+extern int __attribute__((target("arch=sandybridge"))) bar2(void);
+
+namespace {
+int __attribute__((target("sse4.2"))) bar4(void) { return 0; }
+static int __attribute__((target("arch=sandybridge"))) bar4(void);
+}
+
 inline int __attribute__((target("sse4.2"))) baz(void) { return 0; }
 inline int __attribute__((target("arch=sandybridge"))) baz(void);
 //expected-error@+1 {{multiversioned function declaration has a different inline specification}}
@@ -102,7 +111,7 @@
 extern "C" {
 int __attribute__((target("sse4.2"))) diff_mangle(void) { return 0; }
 }
-//expected-error@+1 {{multiversioned function declaration has a different linkage}}
+//expected-error@+1 {{multiversioned function declaration has a different language linkage}}
 int __attribute__((target("arch=sandybridge"))) diff_mangle(void) { return 0; }
 
 // expected-error@+1 {{multiversioned functions do not yet support deduced return types}}
Index: clang/test/SemaCXX/attr-cpuspecific.cpp
===================================================================
--- clang/test/SemaCXX/attr-cpuspecific.cpp
+++ clang/test/SemaCXX/attr-cpuspecific.cpp
@@ -34,9 +34,19 @@
 constexpr int __attribute__((cpu_specific(ivybridge))) foo2(void);
 
 static int __attribute__((cpu_specific(sandybridge))) bar(void);
-//expected-error@+1 {{multiversioned function declaration has a different storage class}}
+//expected-error@+1 {{multiversioned function declaration has a different linkage}}
 int __attribute__((cpu_dispatch(ivybridge))) bar(void) {}
 
+// OK
+extern int __attribute__((cpu_specific(sandybridge))) bar2(void);
+int __attribute__((cpu_dispatch(ivybridge))) bar2(void) {}
+
+namespace {
+int __attribute__((cpu_specific(sandybridge))) bar3(void);
+static int __attribute__((cpu_dispatch(ivybridge))) bar3(void) {}
+}
+
+
 inline int __attribute__((cpu_specific(sandybridge))) baz(void);
 //expected-error@+1 {{multiversioned function declaration has a different inline specification}}
 int __attribute__((cpu_specific(ivybridge))) baz(void) {return 1;}
@@ -74,7 +84,7 @@
 extern "C" {
 int __attribute__((cpu_specific(atom))) diff_mangle(void) { return 0; }
 }
-//expected-error@+1 {{multiversioned function declaration has a different linkage}}
+//expected-error@+1 {{multiversioned function declaration has a different language linkage}}
 int __attribute__((cpu_specific(sandybridge))) diff_mangle(void) { return 0; }
 
 __attribute__((cpu_specific(atom))) void DiffDecl();
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -10320,8 +10320,8 @@
     ReturnType = 1,
     ConstexprSpec = 2,
     InlineSpec = 3,
-    StorageClass = 4,
-    Linkage = 5,
+    Linkage = 4,
+    LanguageLinkage = 5,
   };
 
   if (NoProtoDiagID.getDiagID() != 0 && OldFD &&
@@ -10395,11 +10395,11 @@
     if (OldFD->isInlineSpecified() != NewFD->isInlineSpecified())
       return Diag(DiffDiagIDAt.first, DiffDiagIDAt.second) << InlineSpec;
 
-    if (OldFD->getStorageClass() != NewFD->getStorageClass())
-      return Diag(DiffDiagIDAt.first, DiffDiagIDAt.second) << StorageClass;
+    if (OldFD->getFormalLinkage() != NewFD->getFormalLinkage())
+      return Diag(DiffDiagIDAt.first, DiffDiagIDAt.second) << Linkage;
 
     if (!CLinkageMayDiffer && OldFD->isExternC() != NewFD->isExternC())
-      return Diag(DiffDiagIDAt.first, DiffDiagIDAt.second) << Linkage;
+      return Diag(DiffDiagIDAt.first, DiffDiagIDAt.second) << LanguageLinkage;
 
     if (CheckEquivalentExceptionSpec(
             OldFD->getType()->getAs<FunctionProtoType>(), OldFD->getLocation(),
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -11208,8 +11208,8 @@
             "%0 %select{is missing|has different arguments}1">;
 def err_multiversion_diff : Error<
   "multiversioned function declaration has a different %select{calling convention"
-  "|return type|constexpr specification|inline specification|storage class|"
-  "linkage}0">;
+  "|return type|constexpr specification|inline specification|linkage|"
+  "language linkage}0">;
 def err_multiversion_doesnt_support : Error<
   "attribute '%select{target|cpu_specific|cpu_dispatch}0' multiversioned functions do not "
   "yet support %select{function templates|virtual functions|"
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D110255: Change erro... Erich Keane via Phabricator via cfe-commits

Reply via email to