[clang] 6976fef - Update 'note-candiate' functions to skip lambda-conversion-op-overloads

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 17 05:49:48 PST 2020


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{};


        


More information about the cfe-commits mailing list