Correctly type-check the default arguments of local functions
when eagerly instantiating them. rdar://23721638 llvm-svn: 255325
This commit is contained in:
parent
38f2bfbbe4
commit
dc40b618cf
|
@ -1680,8 +1680,11 @@ ParmVarDecl *Sema::SubstParmVarDecl(ParmVarDecl *OldParm,
|
|||
Sema::ContextRAII SavedContext(*this, OwningFunc);
|
||||
LocalInstantiationScope Local(*this);
|
||||
ExprResult NewArg = SubstExpr(Arg, TemplateArgs);
|
||||
if (NewArg.isUsable())
|
||||
NewParm->setDefaultArg(NewArg.get());
|
||||
if (NewArg.isUsable()) {
|
||||
// It would be nice if we still had this.
|
||||
SourceLocation EqualLoc = NewArg.get()->getLocStart();
|
||||
SetParamDefaultArgument(NewParm, NewArg.get(), EqualLoc);
|
||||
}
|
||||
} else {
|
||||
// FIXME: if we non-lazily instantiated non-dependent default args for
|
||||
// non-dependent parameter types we could remove a bunch of duplicate
|
||||
|
|
|
@ -448,3 +448,30 @@ namespace PR21332 {
|
|||
}
|
||||
template void f7<int>();
|
||||
}
|
||||
|
||||
// rdar://23721638: Ensure that we correctly perform implicit
|
||||
// conversions when instantiating the default arguments of local functions.
|
||||
namespace rdar23721638 {
|
||||
struct A {
|
||||
A(const char *) = delete; // expected-note 2 {{explicitly marked deleted here}}
|
||||
};
|
||||
|
||||
template <typename T> void foo() {
|
||||
struct Inner { // expected-note {{in instantiation}}
|
||||
void operator()(T a = "") {} // expected-error {{conversion function from 'const char [1]' to 'rdar23721638::A' invokes a deleted function}}
|
||||
// expected-note@-1 {{passing argument to parameter 'a' here}}
|
||||
// expected-note@-2 {{candidate function not viable}}
|
||||
};
|
||||
Inner()(); // expected-error {{no matching function}}
|
||||
}
|
||||
template void foo<A>(); // expected-note 2 {{in instantiation}}
|
||||
|
||||
template <typename T> void bar() {
|
||||
auto lambda = [](T a = "") {}; // expected-error {{conversion function from 'const char [1]' to 'rdar23721638::A' invokes a deleted function}}
|
||||
// expected-note@-1 {{passing argument to parameter 'a' here}}
|
||||
// expected-note@-2 {{candidate function not viable}}
|
||||
// expected-note@-3 {{conversion candidate of type}}
|
||||
lambda(); // expected-error {{no matching function}}
|
||||
}
|
||||
template void bar<A>(); // expected-note {{in instantiation}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue