Author: Erich Keane Date: 2021-09-22T10:51:05-07:00 New Revision: 97b2f20a446e54f4354d8f950dfab62c37e6ddf4
URL: https://github.com/llvm/llvm-project/commit/97b2f20a446e54f4354d8f950dfab62c37e6ddf4 DIFF: https://github.com/llvm/llvm-project/commit/97b2f20a446e54f4354d8f950dfab62c37e6ddf4.diff LOG: Change error for storage-class to mean linkage, fix lang-linkage diag 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'. Added: Modified: clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaDecl.cpp clang/test/SemaCXX/attr-cpuspecific.cpp clang/test/SemaCXX/attr-target-mv.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 3cadd986b8ae..0e803ee028ce 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -11208,8 +11208,8 @@ def err_multiversion_mismatched_attrs "%0 %select{is missing|has diff erent arguments}1">; def err_multiversion_ diff : Error< "multiversioned function declaration has a diff erent %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|" diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 13389ebdd72f..79080098026c 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -10322,8 +10322,8 @@ bool Sema::areMultiversionVariantFunctionsCompatible( ReturnType = 1, ConstexprSpec = 2, InlineSpec = 3, - StorageClass = 4, - Linkage = 5, + Linkage = 4, + LanguageLinkage = 5, }; if (NoProtoDiagID.getDiagID() != 0 && OldFD && @@ -10397,11 +10397,11 @@ bool Sema::areMultiversionVariantFunctionsCompatible( 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(), diff --git a/clang/test/SemaCXX/attr-cpuspecific.cpp b/clang/test/SemaCXX/attr-cpuspecific.cpp index 861711b46383..fe4635816654 100644 --- a/clang/test/SemaCXX/attr-cpuspecific.cpp +++ b/clang/test/SemaCXX/attr-cpuspecific.cpp @@ -34,9 +34,19 @@ int __attribute__((cpu_specific(sandybridge))) foo2(void); constexpr int __attribute__((cpu_specific(ivybridge))) foo2(void); static int __attribute__((cpu_specific(sandybridge))) bar(void); -//expected-error@+1 {{multiversioned function declaration has a diff erent storage class}} +//expected-error@+1 {{multiversioned function declaration has a diff erent 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 diff erent inline specification}} int __attribute__((cpu_specific(ivybridge))) baz(void) {return 1;} @@ -74,7 +84,7 @@ struct S { extern "C" { int __attribute__((cpu_specific(atom))) diff _mangle(void) { return 0; } } -//expected-error@+1 {{multiversioned function declaration has a diff erent linkage}} +//expected-error@+1 {{multiversioned function declaration has a diff erent language linkage}} int __attribute__((cpu_specific(sandybridge))) diff _mangle(void) { return 0; } __attribute__((cpu_specific(atom))) void DiffDecl(); diff --git a/clang/test/SemaCXX/attr-target-mv.cpp b/clang/test/SemaCXX/attr-target-mv.cpp index 5ef1d398d2d8..5b2f0fc825f3 100644 --- a/clang/test/SemaCXX/attr-target-mv.cpp +++ b/clang/test/SemaCXX/attr-target-mv.cpp @@ -27,17 +27,26 @@ int __attribute__((target("default"))) foo2(void) { return 2; } 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 diff erent storage class}} +//expected-error@+1 {{multiversioned function declaration has a diff erent 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 diff erent storage class}} +//expected-error@+1 {{multiversioned function declaration has a diff erent 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 diff erent inline specification}} @@ -102,7 +111,7 @@ struct S { extern "C" { int __attribute__((target("sse4.2"))) diff _mangle(void) { return 0; } } -//expected-error@+1 {{multiversioned function declaration has a diff erent linkage}} +//expected-error@+1 {{multiversioned function declaration has a diff erent language linkage}} int __attribute__((target("arch=sandybridge"))) diff _mangle(void) { return 0; } // expected-error@+1 {{multiversioned functions do not yet support deduced return types}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits