In C++98, if an rvalue reference binds to a function lvalue (or an xvalue or an

array prvalue), treat that as a direct binding. Only the class prvalue case
needs to be excluded here; the rest are extensions anyway, so we can treat them
as we would in C++11.

llvm-svn: 212978
This commit is contained in:
Richard Smith 2014-07-14 19:54:05 +00:00
parent 8c98230248
commit b94afe1dd6
2 changed files with 7 additions and 11 deletions

View File

@ -4336,7 +4336,7 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType,
// standard library implementors; therefore, we need the xvalue check here.
ICS.Standard.DirectBinding =
S.getLangOpts().CPlusPlus11 ||
(InitCategory.isPRValue() && !T2->isRecordType());
!(InitCategory.isPRValue() || T2->isRecordType());
ICS.Standard.IsLvalueReference = !isRValRef;
ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
ICS.Standard.BindsToRvalue = InitCategory.isRValue();

View File

@ -592,10 +592,10 @@ void test5() {
}
namespace PR20218 {
void f(void (*const &)()); // expected-note{{candidate}}
void f(void (&&)()) = delete; // expected-note{{candidate}} expected-warning 2{{extension}}
void g(void (&&)()) = delete; // expected-note{{candidate}} expected-warning 2{{extension}}
void g(void (*const &)()); // expected-note{{candidate}}
void f(void (*const &)()); // expected-note 2{{candidate}}
void f(void (&&)()) = delete; // expected-note 2{{candidate}} expected-warning 2{{extension}}
void g(void (&&)()) = delete; // expected-note 2{{candidate}} expected-warning 2{{extension}}
void g(void (*const &)()); // expected-note 2{{candidate}}
void x();
typedef void (&fr)();
@ -604,11 +604,7 @@ namespace PR20218 {
void h() {
f(x); // expected-error {{ambiguous}}
g(x); // expected-error {{ambiguous}}
// OK! These ones try to copy-initialize a temporary of the reference's
// underlying type, which only works for the pointer case and not for the
// reference case.
f(y);
g(y);
f(y); // expected-error {{ambiguous}}
g(y); // expected-error {{ambiguous}}
}
}