Author: Erich Keane
Date: 2020-11-17T05:49:31-08:00
New Revision: 6976fef05b7e5301815baa6cc4af27284e8aceb4

URL: 
https://github.com/llvm/llvm-project/commit/6976fef05b7e5301815baa6cc4af27284e8aceb4
DIFF: 
https://github.com/llvm/llvm-project/commit/6976fef05b7e5301815baa6cc4af27284e8aceb4.diff

LOG: Update 'note-candiate' functions to skip lambda-conversion-op-overloads

In the wake of https://reviews.llvm.org/D89559, we discovered that a
couple of tests (the ones modified below to have additional triple
versions) would fail on Win32, for 1 of two reasons.  We seem to not
have a win32 buildbot anymore, so the triple is to make sure this
doesn't get broken in the future.

First, two of the three 'note-candidate' functions weren't appropriately
skipping the remaining conversion functions.

Second, in 1 situation (note surrogate candidates) we actually print the
type of the conversion operator.  The two tests that ran into that
needed updating to make sure it printed the proper one in the win32
case.

Added: 
    

Modified: 
    clang/lib/Sema/SemaOverload.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.lambda/p6.cpp
    clang/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
    clang/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp
    clang/test/SemaCXX/cxx1y-generic-lambdas.cpp
    clang/test/SemaOpenCLCXX/address-space-lambda.cl

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 847f0dd977b73..11fa0a634492a 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -10217,6 +10217,27 @@ bool Sema::checkAddressOfFunctionIsAvailable(const 
FunctionDecl *Function,
                                              Loc);
 }
 
+// Don't print candidates other than the one that matches the calling
+// convention of the call operator, since that is guaranteed to exist.
+static bool shouldSkipNotingLambdaConversionDecl(FunctionDecl *Fn) {
+  const auto *ConvD = dyn_cast<CXXConversionDecl>(Fn);
+
+  if (!ConvD)
+    return false;
+  const auto *RD = cast<CXXRecordDecl>(Fn->getParent());
+  if (!RD->isLambda())
+    return false;
+
+  CXXMethodDecl *CallOp = RD->getLambdaCallOperator();
+  CallingConv CallOpCC =
+      CallOp->getType()->getAs<FunctionType>()->getCallConv();
+  QualType ConvRTy = ConvD->getType()->getAs<FunctionType>()->getReturnType();
+  CallingConv ConvToCC =
+      ConvRTy->getPointeeType()->getAs<FunctionType>()->getCallConv();
+
+  return ConvToCC != CallOpCC;
+}
+
 // Notes the location of an overload candidate.
 void Sema::NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn,
                                  OverloadCandidateRewriteKind RewriteKind,
@@ -10226,22 +10247,8 @@ void Sema::NoteOverloadCandidate(NamedDecl *Found, 
FunctionDecl *Fn,
   if (Fn->isMultiVersion() && Fn->hasAttr<TargetAttr>() &&
       !Fn->getAttr<TargetAttr>()->isDefaultVersion())
     return;
-  if (isa<CXXConversionDecl>(Fn) &&
-      cast<CXXRecordDecl>(Fn->getParent())->isLambda()) {
-    // Don't print candidates other than the one that matches the calling
-    // convention of the call operator, since that is guaranteed to exist.
-    const auto *RD = cast<CXXRecordDecl>(Fn->getParent());
-    CXXMethodDecl *CallOp = RD->getLambdaCallOperator();
-    CallingConv CallOpCC =
-        CallOp->getType()->getAs<FunctionType>()->getCallConv();
-    CXXConversionDecl *ConvD = cast<CXXConversionDecl>(Fn);
-    QualType ConvRTy = 
ConvD->getType()->getAs<FunctionType>()->getReturnType();
-    CallingConv ConvToCC =
-        ConvRTy->getPointeeType()->getAs<FunctionType>()->getCallConv();
-
-    if (ConvToCC != CallOpCC)
-      return;
-  }
+  if (shouldSkipNotingLambdaConversionDecl(Fn))
+    return;
 
   std::string FnDesc;
   std::pair<OverloadCandidateKind, OverloadCandidateSelect> KSPair =
@@ -11101,6 +11108,8 @@ static void NoteFunctionCandidate(Sema &S, 
OverloadCandidate *Cand,
                                   bool TakingCandidateAddress,
                                   LangAS CtorDestAS = LangAS::Default) {
   FunctionDecl *Fn = Cand->Function;
+  if (shouldSkipNotingLambdaConversionDecl(Fn))
+    return;
 
   // Note deleted candidates, but only if they're viable.
   if (Cand->Viable) {
@@ -11217,6 +11226,9 @@ static void NoteFunctionCandidate(Sema &S, 
OverloadCandidate *Cand,
 }
 
 static void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) {
+  if (shouldSkipNotingLambdaConversionDecl(Cand->Surrogate))
+    return;
+
   // Desugar the type of the surrogate down to a function type,
   // retaining as many typedefs as possible while still showing
   // the function type (and, therefore, its parameter types).

diff  --git 
a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp 
b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp
index 9b0a9ad8c2573..5d3c63f92c287 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify=expected,nowin32
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify=expected,win32 -triple 
i386-windows
 
 void defargs() {
   auto l1 = [](int i, int j = 17, int k = 18) { return i + j + k; };
@@ -9,8 +10,8 @@ void defargs() {
 
 
 void defargs_errors() {
-  auto l1 = [](int i, 
-               int j = 17, 
+  auto l1 = [](int i,
+               int j = 17,
                int k) { }; // expected-error{{missing default argument on 
parameter 'k'}}
 
   auto l2 = [](int i, int j = i) {}; // expected-error{{default argument 
references parameter 'i'}}
@@ -44,7 +45,8 @@ template<typename T>
 void defargs_in_template_used() {
   auto l1 = [](const T& value = T()) { }; // expected-error{{no matching 
constructor for initialization of 'NoDefaultCtor'}} \
                                           // expected-note{{candidate function 
not viable: requires single argument 'value', but no arguments were provided}} \
-                                          // expected-note{{conversion 
candidate of type 'void (*)(const NoDefaultCtor &)'}}
+                                          // nowin32-note{{conversion 
candidate of type 'void (*)(const NoDefaultCtor &)'}}\
+                                          // win32-note{{conversion candidate 
of type 'void (*)(const NoDefaultCtor &) __attribute__((thiscall))'}}
   l1(); // expected-error{{no matching function for call to object of type 
'(lambda at }}
 }
 

diff  --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p6.cpp 
b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p6.cpp
index 90a3aec50cb38..533bea5d5cb74 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p6.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p6.cpp
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
 // RUN: %clang_cc1 -fsyntax-only -std=c++1z %s -verify
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -triple i386-windows-pc -verify
+// RUN: %clang_cc1 -fsyntax-only -std=c++1z %s -triple i386-windows-pc -verify
 
 void test_conversion() {
   int (*fp1)(int) = [](int x) { return x + 1; };

diff  --git a/clang/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp 
b/clang/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
index 8d7845dc607d6..8a0c960acd9e9 100644
--- a/clang/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
+++ b/clang/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm-only %s
 // RUN: %clang_cc1 -std=c++2a -verify -fsyntax-only -fblocks -emit-llvm-only %s
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm-only 
-triple i386-windows-pc %s
+// RUN: %clang_cc1 -std=c++2a -verify -fsyntax-only -fblocks -emit-llvm-only 
-triple i386-windows-pc %s
 // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
 // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks 
-fms-extensions %s -DMS_EXTENSIONS
 // DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS 
-DDELAYED_TEMPLATE_PARSING

diff  --git a/clang/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp 
b/clang/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp
index 5c1eb32ad2c63..868a05357d275 100644
--- a/clang/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp
+++ b/clang/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp
@@ -2,6 +2,10 @@
 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions 
%s -DMS_EXTENSIONS
 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS 
-DDELAYED_TEMPLATE_PARSING
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -triple 
i386-windows %s
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -triple 
i386-windows -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -triple 
i386-windows -fms-extensions %s -DMS_EXTENSIONS
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -triple 
i386-windows -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS 
-DDELAYED_TEMPLATE_PARSING
 
 namespace explicit_argument_variadics {
 

diff  --git a/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp 
b/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp
index 52caaa59dd30f..00a7dc10a785e 100644
--- a/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp
+++ b/clang/test/SemaCXX/cxx1y-generic-lambdas.cpp
@@ -2,6 +2,10 @@
 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions 
%s -DMS_EXTENSIONS
 // RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks 
-fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS 
-DDELAYED_TEMPLATE_PARSING
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -triple 
i386-windows-pc -emit-llvm-only %s
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -triple 
i386-windows-pc -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -triple 
i386-windows-pc -fms-extensions %s -DMS_EXTENSIONS
+// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -triple 
i386-windows-pc -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS 
-DDELAYED_TEMPLATE_PARSING
 
 template<class F, class ...Rest> struct first_impl { typedef F type; };
 template<class ...Args> using first = typename first_impl<Args...>::type;

diff  --git a/clang/test/SemaOpenCLCXX/address-space-lambda.cl 
b/clang/test/SemaOpenCLCXX/address-space-lambda.cl
index e953817442f7b..c9e1ec3735a80 100644
--- a/clang/test/SemaOpenCLCXX/address-space-lambda.cl
+++ b/clang/test/SemaOpenCLCXX/address-space-lambda.cl
@@ -1,4 +1,5 @@
-//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -ast-dump -verify | FileCheck %s
+//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -ast-dump 
-verify=expected,nowin32 | FileCheck %s
+//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -ast-dump -verify=expected,win32 
-triple i386-windows | FileCheck %s
 
 //CHECK: CXXMethodDecl {{.*}} constexpr operator() 'int (__private int){{.*}} 
const __generic'
 auto glambda = [](auto a) { return a; };
@@ -31,12 +32,12 @@ __kernel void test_qual() {
 //CHECK: |-CXXMethodDecl {{.*}} constexpr operator() 'void () {{.*}}const 
__generic'
   auto priv2 = []() __generic {};
   priv2();
-  auto priv3 = []() __global {}; //expected-note{{candidate function not 
viable: 'this' object is in address space '__private', but method expects 
object in address space '__global'}} //expected-note{{conversion candidate of 
type 'void (*)()'}}
+  auto priv3 = []() __global {}; //expected-note{{candidate function not 
viable: 'this' object is in address space '__private', but method expects 
object in address space '__global'}} //nowin32-note{{conversion candidate of 
type 'void (*)()'}}//win32-note{{conversion candidate of type 'void (*)() 
__attribute__((thiscall))'}}
   priv3(); //expected-error{{no matching function for call to object of type}}
 
-  __constant auto const1 = []() __private{}; //expected-note{{candidate 
function not viable: 'this' object is in address space '__constant', but method 
expects object in address space '__private'}} //expected-note{{conversion 
candidate of type 'void (*)()'}}
+  __constant auto const1 = []() __private{}; //expected-note{{candidate 
function not viable: 'this' object is in address space '__constant', but method 
expects object in address space '__private'}} //nowin32-note{{conversion 
candidate of type 'void (*)()'}} //win32-note{{conversion candidate of type 
'void (*)() __attribute__((thiscall))'}}
   const1(); //expected-error{{no matching function for call to object of type 
'__constant (lambda at}}
-  __constant auto const2 = []() __generic{}; //expected-note{{candidate 
function not viable: 'this' object is in address space '__constant', but method 
expects object in address space '__generic'}} //expected-note{{conversion 
candidate of type 'void (*)()'}}
+  __constant auto const2 = []() __generic{}; //expected-note{{candidate 
function not viable: 'this' object is in address space '__constant', but method 
expects object in address space '__generic'}} //nowin32-note{{conversion 
candidate of type 'void (*)()'}} //win32-note{{conversion candidate of type 
'void (*)() __attribute__((thiscall))'}}
   const2(); //expected-error{{no matching function for call to object of type 
'__constant (lambda at}}
 //CHECK: |-CXXMethodDecl {{.*}} constexpr operator() 'void () {{.*}}const 
__constant'
   __constant auto const3 = []() __constant{};


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to