tahonermann updated this revision to Diff 416665.
tahonermann added a comment.

Corrected a clang-format issue.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D121959/new/

https://reviews.llvm.org/D121959

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/test/Sema/attr-cpuspecific.c
  clang/test/Sema/attr-target-clones.c
  clang/test/Sema/attr-target-mv.c

Index: clang/test/Sema/attr-target-mv.c
===================================================================
--- clang/test/Sema/attr-target-mv.c
+++ clang/test/Sema/attr-target-mv.c
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -triple x86_64-linux-gnu -Wno-strict-prototypes -fsyntax-only -verify %s
-// XFAIL: asserts
 
 void __attribute__((target("sse4.2"))) no_default(void);
 void __attribute__((target("arch=sandybridge")))  no_default(void);
@@ -109,13 +108,9 @@
 void __attribute__((target("sse4.2"))) addtl_attrs6(int*);
 void __attribute__((target("arch=sandybridge"), nothrow, used, nonnull)) addtl_attrs6(int*);
 
-// FIXME: Declaration of a non-overloadable function when more than one
-// FIXME: multiversion function declarations are present results in an
-// FIXME: assertion failure.
 int __attribute__((target("sse4.2"))) bad_overload1(void);
 int __attribute__((target("arch=sandybridge"))) bad_overload1(void);
-// expected-error@+2 {{at most one overload for a given name may lack the 'overloadable' attribute}}
-// expected-note@-2 {{previous unmarked overload of function is here}}
+// expected-error@+1 {{function declaration is missing 'target' attribute in a multiversioned function}}
 int bad_overload1(int);
 
 int bad_overload2(int);
Index: clang/test/Sema/attr-target-clones.c
===================================================================
--- clang/test/Sema/attr-target-clones.c
+++ clang/test/Sema/attr-target-clones.c
@@ -90,9 +90,13 @@
 void bad_overload1(int p) {}
 
 void bad_overload2(int p) {}
+// expected-error@+2 {{conflicting types for 'bad_overload2'}}
+// expected-note@-2 {{previous definition is here}}
 void bad_overload2(void) __attribute__((target_clones("mmx", "sse4.2", "default")));
 
 void bad_overload3(void) __attribute__((target_clones("mmx", "sse4.2", "default")));
+// expected-error@+2 {{conflicting types for 'bad_overload3'}}
+// expected-note@-2 {{previous declaration is here}}
 void bad_overload3(int) __attribute__((target_clones("mmx", "sse4.2", "default")));
 
 void good_overload1(void) __attribute__((target_clones("mmx", "sse4.2", "default")));
Index: clang/test/Sema/attr-cpuspecific.c
===================================================================
--- clang/test/Sema/attr-cpuspecific.c
+++ clang/test/Sema/attr-cpuspecific.c
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -triple x86_64-linux-gnu -Wno-strict-prototypes -fsyntax-only -verify %s -Wnonnull
-// XFAIL: asserts
 
 void __attribute__((cpu_specific(ivybridge))) no_default(void);
 void __attribute__((cpu_specific(sandybridge)))  no_default(void);
@@ -120,13 +119,9 @@
 
 void __attribute__((cpu_specific(atom), nothrow, nonnull(1))) addtl_attrs(int*);
 
-// FIXME: Declaration of a non-overloadable function when more than one
-// FIXME: multiversion function declarations are present results in an
-// FIXME: assertion failure.
 int __attribute__((cpu_specific(atom))) bad_overload1(void);
 int __attribute__((cpu_specific(ivybridge))) bad_overload1(void);
-// expected-error@+2 {{at most one overload for a given name may lack the 'overloadable' attribute}}
-// expected-note@-2 {{previous unmarked overload of function is here}}
+// expected-error@+1 {{function declaration is missing 'cpu_specific' or 'cpu_dispatch' attribute in a multiversioned function}}
 int bad_overload1(int);
 
 int bad_overload2(int);
@@ -135,13 +130,9 @@
 int __attribute__((cpu_specific(atom))) bad_overload2(void);
 int __attribute__((cpu_specific(ivybridge))) bad_overload2(void);
 
-// FIXME: Declaration of a non-overloadable function when more than one
-// FIXME: multiversion function declarations are present results in an
-// FIXME: assertion failure.
 int __attribute__((cpu_dispatch(generic))) bad_overload3(void);
 int __attribute__((cpu_specific(ivybridge))) bad_overload3(void);
-// expected-error@+2 {{at most one overload for a given name may lack the 'overloadable' attribute}}
-// expected-note@-2 {{previous unmarked overload of function is here}}
+// expected-error@+1 {{function declaration is missing 'cpu_specific' or 'cpu_dispatch' attribute in a multiversioned function}}
 int bad_overload3(int);
 
 int bad_overload4(int);
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -1460,27 +1460,38 @@
   assert(CurContext && "Popped translation unit!");
 }
 
-/// Determine whether we allow overloading of the function
-/// PrevDecl with another declaration.
+/// Determine whether overloading is allowed for a new function
+/// declaration considering prior declarations of the same name.
 ///
 /// This routine determines whether overloading is possible, not
-/// whether some new function is actually an overload. It will return
-/// true in C++ (where we can always provide overloads) or, as an
-/// extension, in C when the previous function is already an
-/// overloaded function declaration or has the "overloadable"
-/// attribute.
-static bool AllowOverloadingOfFunction(LookupResult &Previous,
+/// whether a new declaration actually overloads a previous one.
+/// It will return true in C++ (where overloads are alway permitted)
+/// or, as a C extension, when either the new declaration or a
+/// previous one is declared with the 'overloadable' attribute.
+static bool AllowOverloadingOfFunction(const LookupResult &Previous,
                                        ASTContext &Context,
                                        const FunctionDecl *New) {
-  if (Context.getLangOpts().CPlusPlus)
+  if (Context.getLangOpts().CPlusPlus || New->hasAttr<OverloadableAttr>())
     return true;
 
-  if (Previous.getResultKind() == LookupResult::FoundOverloaded)
-    return true;
+  // Multiversion function declarations are not overloads in the
+  // usual sense of that term, but lookup will report that an
+  // overload set was found if more than one multiversion function
+  // declaration is present for the same name. It is therefore
+  // inadequate to assume that some prior declaration(s) had
+  // the overloadable attribute; checking is required. Since one
+  // declaration is permitted to omit the attribute, it is necessary
+  // to check at least two; hence the 'any_of' check below. Note that
+  // the overloadable attribute is implicitly added to declarations
+  // that were required to have it but did not.
+  if (Previous.getResultKind() == LookupResult::FoundOverloaded) {
+    return llvm::any_of(Previous, [](const NamedDecl *ND) {
+      return ND->hasAttr<OverloadableAttr>();
+    });
+  } else if (Previous.getResultKind() == LookupResult::Found)
+    return Previous.getFoundDecl()->hasAttr<OverloadableAttr>();
 
-  return Previous.getResultKind() == LookupResult::Found &&
-         (Previous.getFoundDecl()->hasAttr<OverloadableAttr>() ||
-          New->hasAttr<OverloadableAttr>());
+  return false;
 }
 
 /// Add this decl to the scope shadowed decl chains.
@@ -10706,13 +10717,17 @@
   bool UseMemberUsingDeclRules =
       S.CurContext->isRecord() && !NewFD->getFriendObjectKind();
 
+  bool MayNeedOverloadableChecks =
+      AllowOverloadingOfFunction(Previous, S.Context, NewFD);
+
   // Next, check ALL non-overloads to see if this is a redeclaration of a
   // previous member of the MultiVersion set.
   for (NamedDecl *ND : Previous) {
     FunctionDecl *CurFD = ND->getAsFunction();
     if (!CurFD)
       continue;
-    if (S.IsOverload(NewFD, CurFD, UseMemberUsingDeclRules))
+    if (MayNeedOverloadableChecks &&
+        S.IsOverload(NewFD, CurFD, UseMemberUsingDeclRules))
       continue;
 
     switch (NewMVType) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to