From 4e47ecb6b2e399d2a7cc3a91d1eab9e501c5580f Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 13 Jun 2013 00:57:57 +0000 Subject: [PATCH] When copy-initializing a temporary for a reference binding, don't allow use of explicit constructors. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183879 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaInit.cpp | 12 +++++------- test/SemaCXX/references.cpp | 7 +++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 18b3d8225e..cf595b49de 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -3792,19 +3792,17 @@ static void TryReferenceInitializationCore(Sema &S, // - Otherwise, a temporary of type "cv1 T1" is created and initialized // from the initializer expression using the rules for a non-reference - // copy initialization (8.5). The reference is then bound to the + // copy-initialization (8.5). The reference is then bound to the // temporary. [...] - // Determine whether we are allowed to call explicit constructors or - // explicit conversion operators. - bool AllowExplicit = Kind.AllowExplicit(); - InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(cv1T1); + // FIXME: Why do we use an implicit conversion here rather than trying + // copy-initialization? ImplicitConversionSequence ICS = S.TryImplicitConversion(Initializer, TempEntity.getType(), - /*SuppressUserConversions*/ false, - AllowExplicit, + /*SuppressUserConversions=*/false, + /*AllowExplicit=*/false, /*FIXME:InOverloadResolution=*/false, /*CStyle=*/Kind.isCStyleOrFunctionalCast(), /*AllowObjCWritebackConversion=*/false); diff --git a/test/SemaCXX/references.cpp b/test/SemaCXX/references.cpp index 4f3dab0514..37fc2a856f 100644 --- a/test/SemaCXX/references.cpp +++ b/test/SemaCXX/references.cpp @@ -137,3 +137,10 @@ namespace PR8608 { // The following crashed trying to recursively evaluate the LValue. const int &do_not_crash = do_not_crash; // expected-warning{{reference 'do_not_crash' is not yet bound to a value when used within its own initialization}} + +namespace ExplicitRefInit { + // This is invalid: we can't copy-initialize an 'A' temporary using an + // explicit constructor. + struct A { explicit A(int); }; + const A &a(0); // expected-error {{reference to type 'const ExplicitRefInit::A' could not bind to an rvalue of type 'int'}} +} -- 2.50.1