forked from OSchip/llvm-project
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.
This commit is contained in:
parent
f571fe6df5
commit
6976fef05b
|
@ -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).
|
||||
|
|
|
@ -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 }}
|
||||
}
|
||||
|
||||
|
|
|
@ -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; };
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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{};
|
||||
|
|
Loading…
Reference in New Issue