Skip to content

Commit 6976fef

Browse files
author
Erich Keane
committed
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.
1 parent f571fe6 commit 6976fef

File tree

7 files changed

+51
-24
lines changed

7 files changed

+51
-24
lines changed

clang/lib/Sema/SemaOverload.cpp

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10217,6 +10217,27 @@ bool Sema::checkAddressOfFunctionIsAvailable(const FunctionDecl *Function,
1021710217
Loc);
1021810218
}
1021910219

10220+
// Don't print candidates other than the one that matches the calling
10221+
// convention of the call operator, since that is guaranteed to exist.
10222+
static bool shouldSkipNotingLambdaConversionDecl(FunctionDecl *Fn) {
10223+
const auto *ConvD = dyn_cast<CXXConversionDecl>(Fn);
10224+
10225+
if (!ConvD)
10226+
return false;
10227+
const auto *RD = cast<CXXRecordDecl>(Fn->getParent());
10228+
if (!RD->isLambda())
10229+
return false;
10230+
10231+
CXXMethodDecl *CallOp = RD->getLambdaCallOperator();
10232+
CallingConv CallOpCC =
10233+
CallOp->getType()->getAs<FunctionType>()->getCallConv();
10234+
QualType ConvRTy = ConvD->getType()->getAs<FunctionType>()->getReturnType();
10235+
CallingConv ConvToCC =
10236+
ConvRTy->getPointeeType()->getAs<FunctionType>()->getCallConv();
10237+
10238+
return ConvToCC != CallOpCC;
10239+
}
10240+
1022010241
// Notes the location of an overload candidate.
1022110242
void Sema::NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn,
1022210243
OverloadCandidateRewriteKind RewriteKind,
@@ -10226,22 +10247,8 @@ void Sema::NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn,
1022610247
if (Fn->isMultiVersion() && Fn->hasAttr<TargetAttr>() &&
1022710248
!Fn->getAttr<TargetAttr>()->isDefaultVersion())
1022810249
return;
10229-
if (isa<CXXConversionDecl>(Fn) &&
10230-
cast<CXXRecordDecl>(Fn->getParent())->isLambda()) {
10231-
// Don't print candidates other than the one that matches the calling
10232-
// convention of the call operator, since that is guaranteed to exist.
10233-
const auto *RD = cast<CXXRecordDecl>(Fn->getParent());
10234-
CXXMethodDecl *CallOp = RD->getLambdaCallOperator();
10235-
CallingConv CallOpCC =
10236-
CallOp->getType()->getAs<FunctionType>()->getCallConv();
10237-
CXXConversionDecl *ConvD = cast<CXXConversionDecl>(Fn);
10238-
QualType ConvRTy = ConvD->getType()->getAs<FunctionType>()->getReturnType();
10239-
CallingConv ConvToCC =
10240-
ConvRTy->getPointeeType()->getAs<FunctionType>()->getCallConv();
10241-
10242-
if (ConvToCC != CallOpCC)
10243-
return;
10244-
}
10250+
if (shouldSkipNotingLambdaConversionDecl(Fn))
10251+
return;
1024510252

1024610253
std::string FnDesc;
1024710254
std::pair<OverloadCandidateKind, OverloadCandidateSelect> KSPair =
@@ -11101,6 +11108,8 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,
1110111108
bool TakingCandidateAddress,
1110211109
LangAS CtorDestAS = LangAS::Default) {
1110311110
FunctionDecl *Fn = Cand->Function;
11111+
if (shouldSkipNotingLambdaConversionDecl(Fn))
11112+
return;
1110411113

1110511114
// Note deleted candidates, but only if they're viable.
1110611115
if (Cand->Viable) {
@@ -11217,6 +11226,9 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand,
1121711226
}
1121811227

1121911228
static void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) {
11229+
if (shouldSkipNotingLambdaConversionDecl(Cand->Surrogate))
11230+
return;
11231+
1122011232
// Desugar the type of the surrogate down to a function type,
1122111233
// retaining as many typedefs as possible while still showing
1122211234
// the function type (and, therefore, its parameter types).

clang/test/CXX/expr/expr.prim/expr.prim.lambda/default-arguments.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
1+
// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify=expected,nowin32
2+
// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify=expected,win32 -triple i386-windows
23

34
void defargs() {
45
auto l1 = [](int i, int j = 17, int k = 18) { return i + j + k; };
@@ -9,8 +10,8 @@ void defargs() {
910

1011

1112
void defargs_errors() {
12-
auto l1 = [](int i,
13-
int j = 17,
13+
auto l1 = [](int i,
14+
int j = 17,
1415
int k) { }; // expected-error{{missing default argument on parameter 'k'}}
1516

1617
auto l2 = [](int i, int j = i) {}; // expected-error{{default argument references parameter 'i'}}
@@ -44,7 +45,8 @@ template<typename T>
4445
void defargs_in_template_used() {
4546
auto l1 = [](const T& value = T()) { }; // expected-error{{no matching constructor for initialization of 'NoDefaultCtor'}} \
4647
// expected-note{{candidate function not viable: requires single argument 'value', but no arguments were provided}} \
47-
// expected-note{{conversion candidate of type 'void (*)(const NoDefaultCtor &)'}}
48+
// nowin32-note{{conversion candidate of type 'void (*)(const NoDefaultCtor &)'}}\
49+
// win32-note{{conversion candidate of type 'void (*)(const NoDefaultCtor &) __attribute__((thiscall))'}}
4850
l1(); // expected-error{{no matching function for call to object of type '(lambda at }}
4951
}
5052

clang/test/CXX/expr/expr.prim/expr.prim.lambda/p6.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
22
// RUN: %clang_cc1 -fsyntax-only -std=c++1z %s -verify
3+
// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -triple i386-windows-pc -verify
4+
// RUN: %clang_cc1 -fsyntax-only -std=c++1z %s -triple i386-windows-pc -verify
35

46
void test_conversion() {
57
int (*fp1)(int) = [](int x) { return x + 1; };

clang/test/SemaCXX/cxx1y-generic-lambdas-capturing.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm-only %s
22
// RUN: %clang_cc1 -std=c++2a -verify -fsyntax-only -fblocks -emit-llvm-only %s
3+
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -emit-llvm-only -triple i386-windows-pc %s
4+
// RUN: %clang_cc1 -std=c++2a -verify -fsyntax-only -fblocks -emit-llvm-only -triple i386-windows-pc %s
35
// DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
46
// DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
57
// DONTRUNYET: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING

clang/test/SemaCXX/cxx1y-generic-lambdas-variadics.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
33
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
44
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
5+
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -triple i386-windows %s
6+
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -triple i386-windows -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
7+
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -triple i386-windows -fms-extensions %s -DMS_EXTENSIONS
8+
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -triple i386-windows -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
59

610
namespace explicit_argument_variadics {
711

clang/test/SemaCXX/cxx1y-generic-lambdas.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
33
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fms-extensions %s -DMS_EXTENSIONS
44
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -fdelayed-template-parsing -fms-extensions %s -DMS_EXTENSIONS -DDELAYED_TEMPLATE_PARSING
5+
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -triple i386-windows-pc -emit-llvm-only %s
6+
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -triple i386-windows-pc -fdelayed-template-parsing %s -DDELAYED_TEMPLATE_PARSING
7+
// RUN: %clang_cc1 -std=c++1y -verify -fsyntax-only -fblocks -triple i386-windows-pc -fms-extensions %s -DMS_EXTENSIONS
8+
// 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
59

610
template<class F, class ...Rest> struct first_impl { typedef F type; };
711
template<class ...Args> using first = typename first_impl<Args...>::type;

clang/test/SemaOpenCLCXX/address-space-lambda.cl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -ast-dump -verify | FileCheck %s
1+
//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -ast-dump -verify=expected,nowin32 | FileCheck %s
2+
//RUN: %clang_cc1 %s -cl-std=clc++ -pedantic -ast-dump -verify=expected,win32 -triple i386-windows | FileCheck %s
23

34
//CHECK: CXXMethodDecl {{.*}} constexpr operator() 'int (__private int){{.*}} const __generic'
45
auto glambda = [](auto a) { return a; };
@@ -31,12 +32,12 @@ __kernel void test_qual() {
3132
//CHECK: |-CXXMethodDecl {{.*}} constexpr operator() 'void () {{.*}}const __generic'
3233
auto priv2 = []() __generic {};
3334
priv2();
34-
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 (*)()'}}
35+
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))'}}
3536
priv3(); //expected-error{{no matching function for call to object of type}}
3637

37-
__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 (*)()'}}
38+
__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))'}}
3839
const1(); //expected-error{{no matching function for call to object of type '__constant (lambda at}}
39-
__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 (*)()'}}
40+
__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))'}}
4041
const2(); //expected-error{{no matching function for call to object of type '__constant (lambda at}}
4142
//CHECK: |-CXXMethodDecl {{.*}} constexpr operator() 'void () {{.*}}const __constant'
4243
__constant auto const3 = []() __constant{};

0 commit comments

Comments
 (0)