diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h --- a/clang/include/clang/Sema/Initialization.h +++ b/clang/include/clang/Sema/Initialization.h @@ -1097,7 +1097,7 @@ private: /// The reason why initialization failed. - FailureKind Failure; + SmallVector Failures; /// The failed result of overload resolution. OverloadingResult FailedOverloadResult; @@ -1358,7 +1358,7 @@ /// Note that this initialization sequence failed. void SetFailed(FailureKind Failure) { SequenceKind = FailedSequence; - this->Failure = Failure; + this->Failures.push_back(Failure); assert((Failure != FK_Incomplete || !FailedIncompleteType.isNull()) && "Incomplete type failure requires a type!"); } @@ -1387,9 +1387,9 @@ } /// Determine why initialization failed. - FailureKind getFailureKind() const { + SmallVector getFailureKind() const { assert(Failed() && "Not an initialization failure!"); - return Failure; + return Failures; } /// Dump a representation of this initialization sequence to diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -427,21 +427,24 @@ return false; InitializedEntity entity = InitializedEntity::InitializeTemporary(destType); - InitializationKind initKind - = (CT == CT_CStyle)? InitializationKind::CreateCStyleCast(range.getBegin(), - range, listInitialization) - : (CT == CT_Functional)? InitializationKind::CreateFunctionalCast(range, - listInitialization) - : InitializationKind::CreateCast(/*type range?*/ range); + InitializationKind initKind = + (CT == CT_CStyle) ? InitializationKind::CreateCStyleCast( + range.getBegin(), range, listInitialization) + : (CT == CT_Functional) + ? InitializationKind::CreateFunctionalCast(range, listInitialization) + : InitializationKind::CreateCast(/*type range?*/ range); InitializationSequence sequence(S, entity, initKind, src); assert(sequence.Failed() && "initialization succeeded on second try?"); - switch (sequence.getFailureKind()) { - default: return false; + for (auto Failure : sequence.getFailureKind()) { + switch (Failure) { + default: + return false; - case InitializationSequence::FK_ConstructorOverloadFailed: - case InitializationSequence::FK_UserConversionOverloadFailed: - break; + case InitializationSequence::FK_ConstructorOverloadFailed: + case InitializationSequence::FK_UserConversionOverloadFailed: + break; + } } OverloadCandidateSet &candidates = sequence.getFailedCandidateSet(); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -526,48 +526,52 @@ // stlport does so too. Look for std::__debug for libstdc++, and for // std:: for stlport. This is effectively a compiler-side implementation of // LWG2193. - if (!InitSeq && EmptyInitList && InitSeq.getFailureKind() == - InitializationSequence::FK_ExplicitConstructor) { - OverloadCandidateSet::iterator Best; - OverloadingResult O = - InitSeq.getFailedCandidateSet() - .BestViableFunction(SemaRef, Kind.getLocation(), Best); - (void)O; - assert(O == OR_Success && "Inconsistent overload resolution"); - CXXConstructorDecl *CtorDecl = cast(Best->Function); - CXXRecordDecl *R = CtorDecl->getParent(); - - if (CtorDecl->getMinRequiredArguments() == 0 && - CtorDecl->isExplicit() && R->getDeclName() && - SemaRef.SourceMgr.isInSystemHeader(CtorDecl->getLocation())) { - bool IsInStd = false; - for (NamespaceDecl *ND = dyn_cast(R->getDeclContext()); - ND && !IsInStd; ND = dyn_cast(ND->getParent())) { - if (SemaRef.getStdNamespace()->InEnclosingNamespaceSetOf(ND)) - IsInStd = true; - } + if (!InitSeq && EmptyInitList) { + auto Failures = InitSeq.getFailureKind(); + if (Failures.end() != + std::find(Failures.begin(), Failures.end(), + InitializationSequence::FK_ExplicitConstructor)) { + OverloadCandidateSet::iterator Best; + OverloadingResult O = InitSeq.getFailedCandidateSet().BestViableFunction( + SemaRef, Kind.getLocation(), Best); + (void)O; + assert(O == OR_Success && "Inconsistent overload resolution"); + CXXConstructorDecl *CtorDecl = cast(Best->Function); + CXXRecordDecl *R = CtorDecl->getParent(); + + if (CtorDecl->getMinRequiredArguments() == 0 && CtorDecl->isExplicit() && + R->getDeclName() && + SemaRef.SourceMgr.isInSystemHeader(CtorDecl->getLocation())) { + bool IsInStd = false; + for (NamespaceDecl *ND = dyn_cast(R->getDeclContext()); + ND && !IsInStd; ND = dyn_cast(ND->getParent())) { + if (SemaRef.getStdNamespace()->InEnclosingNamespaceSetOf(ND)) + IsInStd = true; + } - if (IsInStd && llvm::StringSwitch(R->getName()) - .Cases("basic_string", "deque", "forward_list", true) - .Cases("list", "map", "multimap", "multiset", true) - .Cases("priority_queue", "queue", "set", "stack", true) - .Cases("unordered_map", "unordered_set", "vector", true) - .Default(false)) { - InitSeq.InitializeFrom( - SemaRef, Entity, - InitializationKind::CreateValue(Loc, Loc, Loc, true), - MultiExprArg(), /*TopLevelOfInitList=*/false, - TreatUnavailableAsInvalid); - // Emit a warning for this. System header warnings aren't shown - // by default, but people working on system headers should see it. - if (!VerifyOnly) { - SemaRef.Diag(CtorDecl->getLocation(), - diag::warn_invalid_initializer_from_system_header); - if (Entity.getKind() == InitializedEntity::EK_Member) - SemaRef.Diag(Entity.getDecl()->getLocation(), - diag::note_used_in_initialization_here); - else if (Entity.getKind() == InitializedEntity::EK_ArrayElement) - SemaRef.Diag(Loc, diag::note_used_in_initialization_here); + if (IsInStd && + llvm::StringSwitch(R->getName()) + .Cases("basic_string", "deque", "forward_list", true) + .Cases("list", "map", "multimap", "multiset", true) + .Cases("priority_queue", "queue", "set", "stack", true) + .Cases("unordered_map", "unordered_set", "vector", true) + .Default(false)) { + InitSeq.InitializeFrom( + SemaRef, Entity, + InitializationKind::CreateValue(Loc, Loc, Loc, true), + MultiExprArg(), /*TopLevelOfInitList=*/false, + TreatUnavailableAsInvalid); + // Emit a warning for this. System header warnings aren't shown + // by default, but people working on system headers should see it. + if (!VerifyOnly) { + SemaRef.Diag(CtorDecl->getLocation(), + diag::warn_invalid_initializer_from_system_header); + if (Entity.getKind() == InitializedEntity::EK_Member) + SemaRef.Diag(Entity.getDecl()->getLocation(), + diag::note_used_in_initialization_here); + else if (Entity.getKind() == InitializedEntity::EK_ArrayElement) + SemaRef.Diag(Loc, diag::note_used_in_initialization_here); + } } } } @@ -3488,49 +3492,51 @@ if (!Failed()) return false; - switch (getFailureKind()) { - case FK_TooManyInitsForReference: - case FK_ParenthesizedListInitForReference: - case FK_ArrayNeedsInitList: - case FK_ArrayNeedsInitListOrStringLiteral: - case FK_ArrayNeedsInitListOrWideStringLiteral: - case FK_NarrowStringIntoWideCharArray: - case FK_WideStringIntoCharArray: - case FK_IncompatWideStringIntoWideChar: - case FK_PlainStringIntoUTF8Char: - case FK_UTF8StringIntoPlainChar: - case FK_AddressOfOverloadFailed: // FIXME: Could do better - case FK_NonConstLValueReferenceBindingToTemporary: - case FK_NonConstLValueReferenceBindingToBitfield: - case FK_NonConstLValueReferenceBindingToVectorElement: - case FK_NonConstLValueReferenceBindingToMatrixElement: - case FK_NonConstLValueReferenceBindingToUnrelated: - case FK_RValueReferenceBindingToLValue: - case FK_ReferenceAddrspaceMismatchTemporary: - case FK_ReferenceInitDropsQualifiers: - case FK_ReferenceInitFailed: - case FK_ConversionFailed: - case FK_ConversionFromPropertyFailed: - case FK_TooManyInitsForScalar: - case FK_ParenthesizedListInitForScalar: - case FK_ReferenceBindingToInitList: - case FK_InitListBadDestinationType: - case FK_DefaultInitOfConst: - case FK_Incomplete: - case FK_ArrayTypeMismatch: - case FK_NonConstantArrayInit: - case FK_ListInitializationFailed: - case FK_VariableLengthArrayHasInitializer: - case FK_PlaceholderType: - case FK_ExplicitConstructor: - case FK_AddressOfUnaddressableFunction: - return false; + for (auto Failure : getFailureKind()) { + switch (Failure) { + case FK_TooManyInitsForReference: + case FK_ParenthesizedListInitForReference: + case FK_ArrayNeedsInitList: + case FK_ArrayNeedsInitListOrStringLiteral: + case FK_ArrayNeedsInitListOrWideStringLiteral: + case FK_NarrowStringIntoWideCharArray: + case FK_WideStringIntoCharArray: + case FK_IncompatWideStringIntoWideChar: + case FK_PlainStringIntoUTF8Char: + case FK_UTF8StringIntoPlainChar: + case FK_AddressOfOverloadFailed: // FIXME: Could do better + case FK_NonConstLValueReferenceBindingToTemporary: + case FK_NonConstLValueReferenceBindingToBitfield: + case FK_NonConstLValueReferenceBindingToVectorElement: + case FK_NonConstLValueReferenceBindingToMatrixElement: + case FK_NonConstLValueReferenceBindingToUnrelated: + case FK_RValueReferenceBindingToLValue: + case FK_ReferenceAddrspaceMismatchTemporary: + case FK_ReferenceInitDropsQualifiers: + case FK_ReferenceInitFailed: + case FK_ConversionFailed: + case FK_ConversionFromPropertyFailed: + case FK_TooManyInitsForScalar: + case FK_ParenthesizedListInitForScalar: + case FK_ReferenceBindingToInitList: + case FK_InitListBadDestinationType: + case FK_DefaultInitOfConst: + case FK_Incomplete: + case FK_ArrayTypeMismatch: + case FK_NonConstantArrayInit: + case FK_ListInitializationFailed: + case FK_VariableLengthArrayHasInitializer: + case FK_PlaceholderType: + case FK_ExplicitConstructor: + case FK_AddressOfUnaddressableFunction: + return false; - case FK_ReferenceInitOverloadFailed: - case FK_UserConversionOverloadFailed: - case FK_ConstructorOverloadFailed: - case FK_ListConstructorOverloadFailed: - return FailedOverloadResult == OR_Ambiguous; + case FK_ReferenceInitOverloadFailed: + case FK_UserConversionOverloadFailed: + case FK_ConstructorOverloadFailed: + case FK_ListConstructorOverloadFailed: + return FailedOverloadResult == OR_Ambiguous; + } } llvm_unreachable("Invalid EntityKind!"); @@ -3775,7 +3781,7 @@ void InitializationSequence::SetOverloadFailure(FailureKind Failure, OverloadingResult Result) { setSequenceKind(FailedSequence); - this->Failure = Failure; + this->Failures.push_back(Failure); this->FailedOverloadResult = Result; } @@ -4143,34 +4149,33 @@ } CXXConstructorDecl *CtorDecl = cast(Best->Function); - if (Result != OR_Deleted) { // TODO: Support for more than one failure. - // C++11 [dcl.init]p6: - // If a program calls for the default initialization of an object - // of a const-qualified type T, T shall be a class type with a - // user-provided default constructor. - // C++ core issue 253 proposal: - // If the implicit default constructor initializes all subobjects, no - // initializer should be required. - // The 253 proposal is for example needed to process libstdc++ headers - // in 5.x. - if (Kind.getKind() == InitializationKind::IK_Default && - Entity.getType().isConstQualified()) { - if (!CtorDecl->getParent()->allowConstDefaultInit()) { - if (!maybeRecoverWithZeroInitialization(S, Sequence, Entity)) - Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst); - return; - } + // C++11 [dcl.init]p6: + // If a program calls for the default initialization of an object + // of a const-qualified type T, T shall be a class type with a + // user-provided default constructor. + // C++ core issue 253 proposal: + // If the implicit default constructor initializes all subobjects, no + // initializer should be required. + // The 253 proposal is for example needed to process libstdc++ headers + // in 5.x. + if (Kind.getKind() == InitializationKind::IK_Default && + Entity.getType().isConstQualified()) { + if (!CtorDecl->getParent()->allowConstDefaultInit()) { + if (!maybeRecoverWithZeroInitialization(S, Sequence, Entity)) + Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst); } + } - // C++11 [over.match.list]p1: - // In copy-list-initialization, if an explicit constructor is chosen, the - // initializer is ill-formed. - if (IsListInit && !Kind.AllowExplicit() && CtorDecl->isExplicit()) { - Sequence.SetFailed(InitializationSequence::FK_ExplicitConstructor); - return; - } + // C++11 [over.match.list]p1: + // In copy-list-initialization, if an explicit constructor is chosen, the + // initializer is ill-formed. + if (IsListInit && !Kind.AllowExplicit() && CtorDecl->isExplicit()) { + Sequence.SetFailed(InitializationSequence::FK_ExplicitConstructor); } + if (Result == OR_Success && Sequence.Failed()) + return; + // [class.copy.elision]p3: // In some copy-initialization contexts, a two-stage overload resolution // is performed. @@ -8916,311 +8921,306 @@ OnlyArg = List->getInit(0); else OnlyArg = Args[0]; - } - else + } else OnlyArg = nullptr; QualType DestType = Entity.getType(); - switch (Failure) { - case FK_TooManyInitsForReference: - // FIXME: Customize for the initialized entity? - if (Args.empty()) { - // Dig out the reference subobject which is uninitialized and diagnose it. - // If this is value-initialization, this could be nested some way within - // the target type. - assert(Kind.getKind() == InitializationKind::IK_Value || - DestType->isReferenceType()); - bool Diagnosed = - DiagnoseUninitializedReference(S, Kind.getLocation(), DestType); - assert(Diagnosed && "couldn't find uninitialized reference to diagnose"); - (void)Diagnosed; - } else // FIXME: diagnostic below could be better! - S.Diag(Kind.getLocation(), diag::err_reference_has_multiple_inits) - << SourceRange(Args.front()->getBeginLoc(), Args.back()->getEndLoc()); - break; - case FK_ParenthesizedListInitForReference: - S.Diag(Kind.getLocation(), diag::err_list_init_in_parens) - << 1 << Entity.getType() << Args[0]->getSourceRange(); - break; - - case FK_ArrayNeedsInitList: - S.Diag(Kind.getLocation(), diag::err_array_init_not_init_list) << 0; - break; - case FK_ArrayNeedsInitListOrStringLiteral: - S.Diag(Kind.getLocation(), diag::err_array_init_not_init_list) << 1; - break; - case FK_ArrayNeedsInitListOrWideStringLiteral: - S.Diag(Kind.getLocation(), diag::err_array_init_not_init_list) << 2; - break; - case FK_NarrowStringIntoWideCharArray: - S.Diag(Kind.getLocation(), diag::err_array_init_narrow_string_into_wchar); - break; - case FK_WideStringIntoCharArray: - S.Diag(Kind.getLocation(), diag::err_array_init_wide_string_into_char); - break; - case FK_IncompatWideStringIntoWideChar: - S.Diag(Kind.getLocation(), - diag::err_array_init_incompat_wide_string_into_wchar); - break; - case FK_PlainStringIntoUTF8Char: - S.Diag(Kind.getLocation(), - diag::err_array_init_plain_string_into_char8_t); - S.Diag(Args.front()->getBeginLoc(), - diag::note_array_init_plain_string_into_char8_t) - << FixItHint::CreateInsertion(Args.front()->getBeginLoc(), "u8"); - break; - case FK_UTF8StringIntoPlainChar: - S.Diag(Kind.getLocation(), - diag::err_array_init_utf8_string_into_char) - << S.getLangOpts().CPlusPlus20; - break; - case FK_ArrayTypeMismatch: - case FK_NonConstantArrayInit: - S.Diag(Kind.getLocation(), - (Failure == FK_ArrayTypeMismatch - ? diag::err_array_init_different_type - : diag::err_array_init_non_constant_array)) - << DestType.getNonReferenceType() - << OnlyArg->getType() - << Args[0]->getSourceRange(); - break; - - case FK_VariableLengthArrayHasInitializer: - S.Diag(Kind.getLocation(), diag::err_variable_object_no_init) - << Args[0]->getSourceRange(); - break; + for (auto Failure : Failures) { + switch (Failure) { + case FK_TooManyInitsForReference: + // FIXME: Customize for the initialized entity? + if (Args.empty()) { + // Dig out the reference subobject which is uninitialized and diagnose + // it. If this is value-initialization, this could be nested some way + // within the target type. + assert(Kind.getKind() == InitializationKind::IK_Value || + DestType->isReferenceType()); + bool Diagnosed = + DiagnoseUninitializedReference(S, Kind.getLocation(), DestType); + assert(Diagnosed && + "couldn't find uninitialized reference to diagnose"); + (void)Diagnosed; + } else // FIXME: diagnostic below could be better! + S.Diag(Kind.getLocation(), diag::err_reference_has_multiple_inits) + << SourceRange(Args.front()->getBeginLoc(), + Args.back()->getEndLoc()); + break; + case FK_ParenthesizedListInitForReference: + S.Diag(Kind.getLocation(), diag::err_list_init_in_parens) + << 1 << Entity.getType() << Args[0]->getSourceRange(); + break; - case FK_AddressOfOverloadFailed: { - DeclAccessPair Found; - S.ResolveAddressOfOverloadedFunction(OnlyArg, - DestType.getNonReferenceType(), - true, - Found); - break; - } + case FK_ArrayNeedsInitList: + S.Diag(Kind.getLocation(), diag::err_array_init_not_init_list) << 0; + break; + case FK_ArrayNeedsInitListOrStringLiteral: + S.Diag(Kind.getLocation(), diag::err_array_init_not_init_list) << 1; + break; + case FK_ArrayNeedsInitListOrWideStringLiteral: + S.Diag(Kind.getLocation(), diag::err_array_init_not_init_list) << 2; + break; + case FK_NarrowStringIntoWideCharArray: + S.Diag(Kind.getLocation(), diag::err_array_init_narrow_string_into_wchar); + break; + case FK_WideStringIntoCharArray: + S.Diag(Kind.getLocation(), diag::err_array_init_wide_string_into_char); + break; + case FK_IncompatWideStringIntoWideChar: + S.Diag(Kind.getLocation(), + diag::err_array_init_incompat_wide_string_into_wchar); + break; + case FK_PlainStringIntoUTF8Char: + S.Diag(Kind.getLocation(), + diag::err_array_init_plain_string_into_char8_t); + S.Diag(Args.front()->getBeginLoc(), + diag::note_array_init_plain_string_into_char8_t) + << FixItHint::CreateInsertion(Args.front()->getBeginLoc(), "u8"); + break; + case FK_UTF8StringIntoPlainChar: + S.Diag(Kind.getLocation(), diag::err_array_init_utf8_string_into_char) + << S.getLangOpts().CPlusPlus20; + break; + case FK_ArrayTypeMismatch: + case FK_NonConstantArrayInit: + S.Diag(Kind.getLocation(), + (Failure == FK_ArrayTypeMismatch + ? diag::err_array_init_different_type + : diag::err_array_init_non_constant_array)) + << DestType.getNonReferenceType() << OnlyArg->getType() + << Args[0]->getSourceRange(); + break; - case FK_AddressOfUnaddressableFunction: { - auto *FD = cast(cast(OnlyArg)->getDecl()); - S.checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true, - OnlyArg->getBeginLoc()); - break; - } + case FK_VariableLengthArrayHasInitializer: + S.Diag(Kind.getLocation(), diag::err_variable_object_no_init) + << Args[0]->getSourceRange(); + break; - case FK_ReferenceInitOverloadFailed: - case FK_UserConversionOverloadFailed: - switch (FailedOverloadResult) { - case OR_Ambiguous: - - FailedCandidateSet.NoteCandidates( - PartialDiagnosticAt( - Kind.getLocation(), - Failure == FK_UserConversionOverloadFailed - ? (S.PDiag(diag::err_typecheck_ambiguous_condition) - << OnlyArg->getType() << DestType - << Args[0]->getSourceRange()) - : (S.PDiag(diag::err_ref_init_ambiguous) - << DestType << OnlyArg->getType() - << Args[0]->getSourceRange())), - S, OCD_AmbiguousCandidates, Args); + case FK_AddressOfOverloadFailed: { + DeclAccessPair Found; + S.ResolveAddressOfOverloadedFunction( + OnlyArg, DestType.getNonReferenceType(), true, Found); break; + } - case OR_No_Viable_Function: { - auto Cands = FailedCandidateSet.CompleteCandidates(S, OCD_AllCandidates, Args); - if (!S.RequireCompleteType(Kind.getLocation(), - DestType.getNonReferenceType(), - diag::err_typecheck_nonviable_condition_incomplete, - OnlyArg->getType(), Args[0]->getSourceRange())) - S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition) - << (Entity.getKind() == InitializedEntity::EK_Result) - << OnlyArg->getType() << Args[0]->getSourceRange() - << DestType.getNonReferenceType(); - - FailedCandidateSet.NoteCandidates(S, Args, Cands); + case FK_AddressOfUnaddressableFunction: { + auto *FD = cast(cast(OnlyArg)->getDecl()); + S.checkAddressOfFunctionIsAvailable(FD, /*Complain=*/true, + OnlyArg->getBeginLoc()); break; } - case OR_Deleted: { - S.Diag(Kind.getLocation(), diag::err_typecheck_deleted_function) - << OnlyArg->getType() << DestType.getNonReferenceType() - << Args[0]->getSourceRange(); - OverloadCandidateSet::iterator Best; - OverloadingResult Ovl - = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best); - if (Ovl == OR_Deleted) { - S.NoteDeletedFunction(Best->Function); - } else { - llvm_unreachable("Inconsistent overload resolution?"); + + case FK_ReferenceInitOverloadFailed: + case FK_UserConversionOverloadFailed: + switch (FailedOverloadResult) { + case OR_Ambiguous: + + FailedCandidateSet.NoteCandidates( + PartialDiagnosticAt( + Kind.getLocation(), + Failure == FK_UserConversionOverloadFailed + ? (S.PDiag(diag::err_typecheck_ambiguous_condition) + << OnlyArg->getType() << DestType + << Args[0]->getSourceRange()) + : (S.PDiag(diag::err_ref_init_ambiguous) + << DestType << OnlyArg->getType() + << Args[0]->getSourceRange())), + S, OCD_AmbiguousCandidates, Args); + break; + + case OR_No_Viable_Function: { + auto Cands = + FailedCandidateSet.CompleteCandidates(S, OCD_AllCandidates, Args); + if (!S.RequireCompleteType( + Kind.getLocation(), DestType.getNonReferenceType(), + diag::err_typecheck_nonviable_condition_incomplete, + OnlyArg->getType(), Args[0]->getSourceRange())) + S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition) + << (Entity.getKind() == InitializedEntity::EK_Result) + << OnlyArg->getType() << Args[0]->getSourceRange() + << DestType.getNonReferenceType(); + + FailedCandidateSet.NoteCandidates(S, Args, Cands); + break; + } + case OR_Deleted: { + S.Diag(Kind.getLocation(), diag::err_typecheck_deleted_function) + << OnlyArg->getType() << DestType.getNonReferenceType() + << Args[0]->getSourceRange(); + OverloadCandidateSet::iterator Best; + OverloadingResult Ovl = + FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best); + if (Ovl == OR_Deleted) { + S.NoteDeletedFunction(Best->Function); + } else { + llvm_unreachable("Inconsistent overload resolution?"); + } + break; + } + + case OR_Success: + llvm_unreachable("Conversion did not fail!"); } break; - } - case OR_Success: - llvm_unreachable("Conversion did not fail!"); - } - break; + case FK_NonConstLValueReferenceBindingToTemporary: + if (isa(Args[0])) { + S.Diag(Kind.getLocation(), diag::err_lvalue_reference_bind_to_initlist) + << DestType.getNonReferenceType().isVolatileQualified() + << DestType.getNonReferenceType() << Args[0]->getSourceRange(); + break; + } + LLVM_FALLTHROUGH; - case FK_NonConstLValueReferenceBindingToTemporary: - if (isa(Args[0])) { + case FK_NonConstLValueReferenceBindingToUnrelated: S.Diag(Kind.getLocation(), - diag::err_lvalue_reference_bind_to_initlist) - << DestType.getNonReferenceType().isVolatileQualified() - << DestType.getNonReferenceType() - << Args[0]->getSourceRange(); + Failure == FK_NonConstLValueReferenceBindingToTemporary + ? diag::err_lvalue_reference_bind_to_temporary + : diag::err_lvalue_reference_bind_to_unrelated) + << DestType.getNonReferenceType().isVolatileQualified() + << DestType.getNonReferenceType() << OnlyArg->getType() + << Args[0]->getSourceRange(); break; - } - LLVM_FALLTHROUGH; - - case FK_NonConstLValueReferenceBindingToUnrelated: - S.Diag(Kind.getLocation(), - Failure == FK_NonConstLValueReferenceBindingToTemporary - ? diag::err_lvalue_reference_bind_to_temporary - : diag::err_lvalue_reference_bind_to_unrelated) - << DestType.getNonReferenceType().isVolatileQualified() - << DestType.getNonReferenceType() - << OnlyArg->getType() - << Args[0]->getSourceRange(); - break; - case FK_NonConstLValueReferenceBindingToBitfield: { - // We don't necessarily have an unambiguous source bit-field. - FieldDecl *BitField = Args[0]->getSourceBitField(); - S.Diag(Kind.getLocation(), diag::err_reference_bind_to_bitfield) - << DestType.isVolatileQualified() - << (BitField ? BitField->getDeclName() : DeclarationName()) - << (BitField != nullptr) - << Args[0]->getSourceRange(); - if (BitField) - S.Diag(BitField->getLocation(), diag::note_bitfield_decl); - break; - } + case FK_NonConstLValueReferenceBindingToBitfield: { + // We don't necessarily have an unambiguous source bit-field. + FieldDecl *BitField = Args[0]->getSourceBitField(); + S.Diag(Kind.getLocation(), diag::err_reference_bind_to_bitfield) + << DestType.isVolatileQualified() + << (BitField ? BitField->getDeclName() : DeclarationName()) + << (BitField != nullptr) << Args[0]->getSourceRange(); + if (BitField) + S.Diag(BitField->getLocation(), diag::note_bitfield_decl); + break; + } - case FK_NonConstLValueReferenceBindingToVectorElement: - S.Diag(Kind.getLocation(), diag::err_reference_bind_to_vector_element) - << DestType.isVolatileQualified() - << Args[0]->getSourceRange(); - break; + case FK_NonConstLValueReferenceBindingToVectorElement: + S.Diag(Kind.getLocation(), diag::err_reference_bind_to_vector_element) + << DestType.isVolatileQualified() << Args[0]->getSourceRange(); + break; - case FK_NonConstLValueReferenceBindingToMatrixElement: - S.Diag(Kind.getLocation(), diag::err_reference_bind_to_matrix_element) - << DestType.isVolatileQualified() << Args[0]->getSourceRange(); - break; + case FK_NonConstLValueReferenceBindingToMatrixElement: + S.Diag(Kind.getLocation(), diag::err_reference_bind_to_matrix_element) + << DestType.isVolatileQualified() << Args[0]->getSourceRange(); + break; - case FK_RValueReferenceBindingToLValue: - S.Diag(Kind.getLocation(), diag::err_lvalue_to_rvalue_ref) - << DestType.getNonReferenceType() << OnlyArg->getType() - << Args[0]->getSourceRange(); - break; + case FK_RValueReferenceBindingToLValue: + S.Diag(Kind.getLocation(), diag::err_lvalue_to_rvalue_ref) + << DestType.getNonReferenceType() << OnlyArg->getType() + << Args[0]->getSourceRange(); + break; - case FK_ReferenceAddrspaceMismatchTemporary: - S.Diag(Kind.getLocation(), diag::err_reference_bind_temporary_addrspace) - << DestType << Args[0]->getSourceRange(); - break; + case FK_ReferenceAddrspaceMismatchTemporary: + S.Diag(Kind.getLocation(), diag::err_reference_bind_temporary_addrspace) + << DestType << Args[0]->getSourceRange(); + break; - case FK_ReferenceInitDropsQualifiers: { - QualType SourceType = OnlyArg->getType(); - QualType NonRefType = DestType.getNonReferenceType(); - Qualifiers DroppedQualifiers = - SourceType.getQualifiers() - NonRefType.getQualifiers(); + case FK_ReferenceInitDropsQualifiers: { + QualType SourceType = OnlyArg->getType(); + QualType NonRefType = DestType.getNonReferenceType(); + Qualifiers DroppedQualifiers = + SourceType.getQualifiers() - NonRefType.getQualifiers(); + + if (!NonRefType.getQualifiers().isAddressSpaceSupersetOf( + SourceType.getQualifiers())) + S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals) + << NonRefType << SourceType << 1 /*addr space*/ + << Args[0]->getSourceRange(); + else if (DroppedQualifiers.hasQualifiers()) + S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals) + << NonRefType << SourceType << 0 /*cv quals*/ + << Qualifiers::fromCVRMask(DroppedQualifiers.getCVRQualifiers()) + << DroppedQualifiers.getCVRQualifiers() + << Args[0]->getSourceRange(); + else + // FIXME: Consider decomposing the type and explaining which qualifiers + // were dropped where, or on which level a 'const' is missing, etc. + S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals) + << NonRefType << SourceType << 2 /*incompatible quals*/ + << Args[0]->getSourceRange(); + break; + } - if (!NonRefType.getQualifiers().isAddressSpaceSupersetOf( - SourceType.getQualifiers())) - S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals) - << NonRefType << SourceType << 1 /*addr space*/ - << Args[0]->getSourceRange(); - else if (DroppedQualifiers.hasQualifiers()) - S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals) - << NonRefType << SourceType << 0 /*cv quals*/ - << Qualifiers::fromCVRMask(DroppedQualifiers.getCVRQualifiers()) - << DroppedQualifiers.getCVRQualifiers() << Args[0]->getSourceRange(); - else - // FIXME: Consider decomposing the type and explaining which qualifiers - // were dropped where, or on which level a 'const' is missing, etc. - S.Diag(Kind.getLocation(), diag::err_reference_bind_drops_quals) - << NonRefType << SourceType << 2 /*incompatible quals*/ + case FK_ReferenceInitFailed: + S.Diag(Kind.getLocation(), diag::err_reference_bind_failed) + << DestType.getNonReferenceType() + << DestType.getNonReferenceType()->isIncompleteType() + << OnlyArg->isLValue() << OnlyArg->getType() << Args[0]->getSourceRange(); - break; - } + emitBadConversionNotes(S, Entity, Args[0]); + break; - case FK_ReferenceInitFailed: - S.Diag(Kind.getLocation(), diag::err_reference_bind_failed) - << DestType.getNonReferenceType() - << DestType.getNonReferenceType()->isIncompleteType() - << OnlyArg->isLValue() - << OnlyArg->getType() - << Args[0]->getSourceRange(); - emitBadConversionNotes(S, Entity, Args[0]); - break; + case FK_ConversionFailed: { + QualType FromType = OnlyArg->getType(); + PartialDiagnostic PDiag = S.PDiag(diag::err_init_conversion_failed) + << (int)Entity.getKind() << DestType + << OnlyArg->isLValue() << FromType + << Args[0]->getSourceRange(); + S.HandleFunctionTypeMismatch(PDiag, FromType, DestType); + S.Diag(Kind.getLocation(), PDiag); + emitBadConversionNotes(S, Entity, Args[0]); + break; + } - case FK_ConversionFailed: { - QualType FromType = OnlyArg->getType(); - PartialDiagnostic PDiag = S.PDiag(diag::err_init_conversion_failed) - << (int)Entity.getKind() - << DestType - << OnlyArg->isLValue() - << FromType - << Args[0]->getSourceRange(); - S.HandleFunctionTypeMismatch(PDiag, FromType, DestType); - S.Diag(Kind.getLocation(), PDiag); - emitBadConversionNotes(S, Entity, Args[0]); - break; - } + case FK_ConversionFromPropertyFailed: + // No-op. This error has already been reported. + break; - case FK_ConversionFromPropertyFailed: - // No-op. This error has already been reported. - break; + case FK_TooManyInitsForScalar: { + SourceRange R; - case FK_TooManyInitsForScalar: { - SourceRange R; + auto *InitList = dyn_cast(Args[0]); + if (InitList && InitList->getNumInits() >= 1) { + R = SourceRange(InitList->getInit(0)->getEndLoc(), + InitList->getEndLoc()); + } else { + assert(Args.size() > 1 && "Expected multiple initializers!"); + R = SourceRange(Args.front()->getEndLoc(), Args.back()->getEndLoc()); + } - auto *InitList = dyn_cast(Args[0]); - if (InitList && InitList->getNumInits() >= 1) { - R = SourceRange(InitList->getInit(0)->getEndLoc(), InitList->getEndLoc()); - } else { - assert(Args.size() > 1 && "Expected multiple initializers!"); - R = SourceRange(Args.front()->getEndLoc(), Args.back()->getEndLoc()); + R.setBegin(S.getLocForEndOfToken(R.getBegin())); + if (Kind.isCStyleOrFunctionalCast()) + S.Diag(Kind.getLocation(), + diag::err_builtin_func_cast_more_than_one_arg) + << R; + else + S.Diag(Kind.getLocation(), diag::err_excess_initializers) + << /*scalar=*/2 << R; + break; } - R.setBegin(S.getLocForEndOfToken(R.getBegin())); - if (Kind.isCStyleOrFunctionalCast()) - S.Diag(Kind.getLocation(), diag::err_builtin_func_cast_more_than_one_arg) - << R; - else - S.Diag(Kind.getLocation(), diag::err_excess_initializers) - << /*scalar=*/2 << R; - break; - } - - case FK_ParenthesizedListInitForScalar: - S.Diag(Kind.getLocation(), diag::err_list_init_in_parens) - << 0 << Entity.getType() << Args[0]->getSourceRange(); - break; - - case FK_ReferenceBindingToInitList: - S.Diag(Kind.getLocation(), diag::err_reference_bind_init_list) - << DestType.getNonReferenceType() << Args[0]->getSourceRange(); - break; + case FK_ParenthesizedListInitForScalar: + S.Diag(Kind.getLocation(), diag::err_list_init_in_parens) + << 0 << Entity.getType() << Args[0]->getSourceRange(); + break; - case FK_InitListBadDestinationType: - S.Diag(Kind.getLocation(), diag::err_init_list_bad_dest_type) - << (DestType->isRecordType()) << DestType << Args[0]->getSourceRange(); - break; + case FK_ReferenceBindingToInitList: + S.Diag(Kind.getLocation(), diag::err_reference_bind_init_list) + << DestType.getNonReferenceType() << Args[0]->getSourceRange(); + break; - case FK_ListConstructorOverloadFailed: - case FK_ConstructorOverloadFailed: { - SourceRange ArgsRange; - if (Args.size()) - ArgsRange = - SourceRange(Args.front()->getBeginLoc(), Args.back()->getEndLoc()); + case FK_InitListBadDestinationType: + S.Diag(Kind.getLocation(), diag::err_init_list_bad_dest_type) + << (DestType->isRecordType()) << DestType + << Args[0]->getSourceRange(); + break; - if (Failure == FK_ListConstructorOverloadFailed) { - assert(Args.size() == 1 && - "List construction from other than 1 argument."); - InitListExpr *InitList = cast(Args[0]); - Args = MultiExprArg(InitList->getInits(), InitList->getNumInits()); - } + case FK_ListConstructorOverloadFailed: + case FK_ConstructorOverloadFailed: { + SourceRange ArgsRange; + if (Args.size()) + ArgsRange = + SourceRange(Args.front()->getBeginLoc(), Args.back()->getEndLoc()); + + if (Failure == FK_ListConstructorOverloadFailed) { + assert(Args.size() == 1 && + "List construction from other than 1 argument."); + InitListExpr *InitList = cast(Args[0]); + Args = MultiExprArg(InitList->getInits(), InitList->getNumInits()); + } - // FIXME: Using "DestType" for the entity we're printing is probably - // bad. - switch (FailedOverloadResult) { + // FIXME: Using "DestType" for the entity we're printing is probably + // bad. + switch (FailedOverloadResult) { case OR_Ambiguous: FailedCandidateSet.NoteCandidates( PartialDiagnosticAt(Kind.getLocation(), @@ -9238,39 +9238,39 @@ // base within a constructor. If no viable function was // found, notify the user that they need to explicitly // initialize this base/member. - CXXConstructorDecl *Constructor - = cast(S.CurContext); + CXXConstructorDecl *Constructor = + cast(S.CurContext); const CXXRecordDecl *InheritedFrom = nullptr; if (auto Inherited = Constructor->getInheritedConstructor()) InheritedFrom = Inherited.getShadowDecl()->getNominatedBaseClass(); if (Entity.getKind() == InitializedEntity::EK_Base) { S.Diag(Kind.getLocation(), diag::err_missing_default_ctor) - << (InheritedFrom ? 2 : Constructor->isImplicit() ? 1 : 0) - << S.Context.getTypeDeclType(Constructor->getParent()) - << /*base=*/0 - << Entity.getType() - << InheritedFrom; - - RecordDecl *BaseDecl - = Entity.getBaseSpecifier()->getType()->castAs() - ->getDecl(); + << (InheritedFrom ? 2 + : Constructor->isImplicit() ? 1 + : 0) + << S.Context.getTypeDeclType(Constructor->getParent()) + << /*base=*/0 << Entity.getType() << InheritedFrom; + + RecordDecl *BaseDecl = Entity.getBaseSpecifier() + ->getType() + ->castAs() + ->getDecl(); S.Diag(BaseDecl->getLocation(), diag::note_previous_decl) - << S.Context.getTagDeclType(BaseDecl); + << S.Context.getTagDeclType(BaseDecl); } else { S.Diag(Kind.getLocation(), diag::err_missing_default_ctor) - << (InheritedFrom ? 2 : Constructor->isImplicit() ? 1 : 0) - << S.Context.getTypeDeclType(Constructor->getParent()) - << /*member=*/1 - << Entity.getName() - << InheritedFrom; + << (InheritedFrom ? 2 + : Constructor->isImplicit() ? 1 + : 0) + << S.Context.getTypeDeclType(Constructor->getParent()) + << /*member=*/1 << Entity.getName() << InheritedFrom; S.Diag(Entity.getDecl()->getLocation(), diag::note_member_declared_at); - if (const RecordType *Record - = Entity.getType()->getAs()) - S.Diag(Record->getDecl()->getLocation(), - diag::note_previous_decl) - << S.Context.getTagDeclType(Record->getDecl()); + if (const RecordType *Record = + Entity.getType()->getAs()) + S.Diag(Record->getDecl()->getLocation(), diag::note_previous_decl) + << S.Context.getTagDeclType(Record->getDecl()); } break; } @@ -9285,8 +9285,8 @@ case OR_Deleted: { OverloadCandidateSet::iterator Best; - OverloadingResult Ovl - = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best); + OverloadingResult Ovl = + FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best); if (Ovl != OR_Deleted) { S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init) << DestType << ArgsRange; @@ -9299,8 +9299,8 @@ // implicit. if (S.isImplicitlyDeleted(Best->Function)) S.Diag(Kind.getLocation(), diag::err_ovl_deleted_special_init) - << S.getSpecialMember(cast(Best->Function)) - << DestType << ArgsRange; + << S.getSpecialMember(cast(Best->Function)) + << DestType << ArgsRange; else S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init) << DestType << ArgsRange; @@ -9311,61 +9311,64 @@ case OR_Success: llvm_unreachable("Conversion did not fail!"); - } - } - break; - - case FK_DefaultInitOfConst: - if (Entity.getKind() == InitializedEntity::EK_Member && - isa(S.CurContext)) { - // This is implicit default-initialization of a const member in - // a constructor. Complain that it needs to be explicitly - // initialized. - CXXConstructorDecl *Constructor = cast(S.CurContext); - S.Diag(Kind.getLocation(), diag::err_uninitialized_member_in_ctor) - << (Constructor->getInheritedConstructor() ? 2 : - Constructor->isImplicit() ? 1 : 0) - << S.Context.getTypeDeclType(Constructor->getParent()) - << /*const=*/1 - << Entity.getName(); - S.Diag(Entity.getDecl()->getLocation(), diag::note_previous_decl) - << Entity.getName(); - } else { - S.Diag(Kind.getLocation(), diag::err_default_init_const) - << DestType << (bool)DestType->getAs(); - } - break; + } + } break; - case FK_Incomplete: - S.RequireCompleteType(Kind.getLocation(), FailedIncompleteType, - diag::err_init_incomplete_type); - break; + case FK_DefaultInitOfConst: + if (Entity.getKind() == InitializedEntity::EK_Member && + isa(S.CurContext)) { + // This is implicit default-initialization of a const member in + // a constructor. Complain that it needs to be explicitly + // initialized. + CXXConstructorDecl *Constructor = + cast(S.CurContext); + S.Diag(Kind.getLocation(), diag::err_uninitialized_member_in_ctor) + << (Constructor->getInheritedConstructor() ? 2 + : Constructor->isImplicit() ? 1 + : 0) + << S.Context.getTypeDeclType(Constructor->getParent()) + << /*const=*/1 << Entity.getName(); + S.Diag(Entity.getDecl()->getLocation(), diag::note_previous_decl) + << Entity.getName(); + } else { + S.Diag(Kind.getLocation(), diag::err_default_init_const) + << DestType << (bool)DestType->getAs(); + } + break; - case FK_ListInitializationFailed: { - // Run the init list checker again to emit diagnostics. - InitListExpr *InitList = cast(Args[0]); - diagnoseListInit(S, Entity, InitList); - break; - } + case FK_Incomplete: + S.RequireCompleteType(Kind.getLocation(), FailedIncompleteType, + diag::err_init_incomplete_type); + break; - case FK_PlaceholderType: { - // FIXME: Already diagnosed! - break; - } + case FK_ListInitializationFailed: { + // Run the init list checker again to emit diagnostics. + InitListExpr *InitList = cast(Args[0]); + diagnoseListInit(S, Entity, InitList); + break; + } - case FK_ExplicitConstructor: { - S.Diag(Kind.getLocation(), diag::err_selected_explicit_constructor) - << Args[0]->getSourceRange(); - OverloadCandidateSet::iterator Best; - OverloadingResult Ovl - = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best); - (void)Ovl; - assert(Ovl == OR_Success && "Inconsistent overload resolution"); - CXXConstructorDecl *CtorDecl = cast(Best->Function); - S.Diag(CtorDecl->getLocation(), - diag::note_explicit_ctor_deduction_guide_here) << false; - break; - } + case FK_PlaceholderType: { + // FIXME: Already diagnosed! + break; + } + + case FK_ExplicitConstructor: { + S.Diag(Kind.getLocation(), diag::err_selected_explicit_constructor) + << Args[0]->getSourceRange(); + OverloadCandidateSet::iterator Best; + OverloadingResult Ovl = + FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best); + (void)Ovl; + assert((Ovl == OR_Success || Ovl == OR_Deleted) && + "Inconsistent overload resolution"); + CXXConstructorDecl *CtorDecl = cast(Best->Function); + S.Diag(CtorDecl->getLocation(), + diag::note_explicit_ctor_deduction_guide_here) + << false; + break; + } + } } PrintInitLocationNote(S, Entity); @@ -9376,164 +9379,166 @@ switch (SequenceKind) { case FailedSequence: { OS << "Failed sequence: "; - switch (Failure) { - case FK_TooManyInitsForReference: - OS << "too many initializers for reference"; - break; + for (auto Failure : Failures) { + switch (Failure) { + case FK_TooManyInitsForReference: + OS << "too many initializers for reference"; + break; - case FK_ParenthesizedListInitForReference: - OS << "parenthesized list init for reference"; - break; + case FK_ParenthesizedListInitForReference: + OS << "parenthesized list init for reference"; + break; - case FK_ArrayNeedsInitList: - OS << "array requires initializer list"; - break; + case FK_ArrayNeedsInitList: + OS << "array requires initializer list"; + break; - case FK_AddressOfUnaddressableFunction: - OS << "address of unaddressable function was taken"; - break; + case FK_AddressOfUnaddressableFunction: + OS << "address of unaddressable function was taken"; + break; - case FK_ArrayNeedsInitListOrStringLiteral: - OS << "array requires initializer list or string literal"; - break; + case FK_ArrayNeedsInitListOrStringLiteral: + OS << "array requires initializer list or string literal"; + break; - case FK_ArrayNeedsInitListOrWideStringLiteral: - OS << "array requires initializer list or wide string literal"; - break; + case FK_ArrayNeedsInitListOrWideStringLiteral: + OS << "array requires initializer list or wide string literal"; + break; - case FK_NarrowStringIntoWideCharArray: - OS << "narrow string into wide char array"; - break; + case FK_NarrowStringIntoWideCharArray: + OS << "narrow string into wide char array"; + break; - case FK_WideStringIntoCharArray: - OS << "wide string into char array"; - break; + case FK_WideStringIntoCharArray: + OS << "wide string into char array"; + break; - case FK_IncompatWideStringIntoWideChar: - OS << "incompatible wide string into wide char array"; - break; + case FK_IncompatWideStringIntoWideChar: + OS << "incompatible wide string into wide char array"; + break; - case FK_PlainStringIntoUTF8Char: - OS << "plain string literal into char8_t array"; - break; + case FK_PlainStringIntoUTF8Char: + OS << "plain string literal into char8_t array"; + break; - case FK_UTF8StringIntoPlainChar: - OS << "u8 string literal into char array"; - break; + case FK_UTF8StringIntoPlainChar: + OS << "u8 string literal into char array"; + break; - case FK_ArrayTypeMismatch: - OS << "array type mismatch"; - break; + case FK_ArrayTypeMismatch: + OS << "array type mismatch"; + break; - case FK_NonConstantArrayInit: - OS << "non-constant array initializer"; - break; + case FK_NonConstantArrayInit: + OS << "non-constant array initializer"; + break; - case FK_AddressOfOverloadFailed: - OS << "address of overloaded function failed"; - break; + case FK_AddressOfOverloadFailed: + OS << "address of overloaded function failed"; + break; - case FK_ReferenceInitOverloadFailed: - OS << "overload resolution for reference initialization failed"; - break; + case FK_ReferenceInitOverloadFailed: + OS << "overload resolution for reference initialization failed"; + break; - case FK_NonConstLValueReferenceBindingToTemporary: - OS << "non-const lvalue reference bound to temporary"; - break; + case FK_NonConstLValueReferenceBindingToTemporary: + OS << "non-const lvalue reference bound to temporary"; + break; - case FK_NonConstLValueReferenceBindingToBitfield: - OS << "non-const lvalue reference bound to bit-field"; - break; + case FK_NonConstLValueReferenceBindingToBitfield: + OS << "non-const lvalue reference bound to bit-field"; + break; - case FK_NonConstLValueReferenceBindingToVectorElement: - OS << "non-const lvalue reference bound to vector element"; - break; + case FK_NonConstLValueReferenceBindingToVectorElement: + OS << "non-const lvalue reference bound to vector element"; + break; - case FK_NonConstLValueReferenceBindingToMatrixElement: - OS << "non-const lvalue reference bound to matrix element"; - break; + case FK_NonConstLValueReferenceBindingToMatrixElement: + OS << "non-const lvalue reference bound to matrix element"; + break; - case FK_NonConstLValueReferenceBindingToUnrelated: - OS << "non-const lvalue reference bound to unrelated type"; - break; + case FK_NonConstLValueReferenceBindingToUnrelated: + OS << "non-const lvalue reference bound to unrelated type"; + break; - case FK_RValueReferenceBindingToLValue: - OS << "rvalue reference bound to an lvalue"; - break; + case FK_RValueReferenceBindingToLValue: + OS << "rvalue reference bound to an lvalue"; + break; - case FK_ReferenceInitDropsQualifiers: - OS << "reference initialization drops qualifiers"; - break; + case FK_ReferenceInitDropsQualifiers: + OS << "reference initialization drops qualifiers"; + break; - case FK_ReferenceAddrspaceMismatchTemporary: - OS << "reference with mismatching address space bound to temporary"; - break; + case FK_ReferenceAddrspaceMismatchTemporary: + OS << "reference with mismatching address space bound to temporary"; + break; - case FK_ReferenceInitFailed: - OS << "reference initialization failed"; - break; + case FK_ReferenceInitFailed: + OS << "reference initialization failed"; + break; - case FK_ConversionFailed: - OS << "conversion failed"; - break; + case FK_ConversionFailed: + OS << "conversion failed"; + break; - case FK_ConversionFromPropertyFailed: - OS << "conversion from property failed"; - break; + case FK_ConversionFromPropertyFailed: + OS << "conversion from property failed"; + break; - case FK_TooManyInitsForScalar: - OS << "too many initializers for scalar"; - break; + case FK_TooManyInitsForScalar: + OS << "too many initializers for scalar"; + break; - case FK_ParenthesizedListInitForScalar: - OS << "parenthesized list init for reference"; - break; + case FK_ParenthesizedListInitForScalar: + OS << "parenthesized list init for reference"; + break; - case FK_ReferenceBindingToInitList: - OS << "referencing binding to initializer list"; - break; + case FK_ReferenceBindingToInitList: + OS << "referencing binding to initializer list"; + break; - case FK_InitListBadDestinationType: - OS << "initializer list for non-aggregate, non-scalar type"; - break; + case FK_InitListBadDestinationType: + OS << "initializer list for non-aggregate, non-scalar type"; + break; - case FK_UserConversionOverloadFailed: - OS << "overloading failed for user-defined conversion"; - break; + case FK_UserConversionOverloadFailed: + OS << "overloading failed for user-defined conversion"; + break; - case FK_ConstructorOverloadFailed: - OS << "constructor overloading failed"; - break; + case FK_ConstructorOverloadFailed: + OS << "constructor overloading failed"; + break; - case FK_DefaultInitOfConst: - OS << "default initialization of a const variable"; - break; + case FK_DefaultInitOfConst: + OS << "default initialization of a const variable"; + break; - case FK_Incomplete: - OS << "initialization of incomplete type"; - break; + case FK_Incomplete: + OS << "initialization of incomplete type"; + break; - case FK_ListInitializationFailed: - OS << "list initialization checker failure"; - break; + case FK_ListInitializationFailed: + OS << "list initialization checker failure"; + break; - case FK_VariableLengthArrayHasInitializer: - OS << "variable length array has an initializer"; - break; + case FK_VariableLengthArrayHasInitializer: + OS << "variable length array has an initializer"; + break; - case FK_PlaceholderType: - OS << "initializer expression isn't contextually valid"; - break; + case FK_PlaceholderType: + OS << "initializer expression isn't contextually valid"; + break; - case FK_ListConstructorOverloadFailed: - OS << "list constructor overloading failed"; - break; + case FK_ListConstructorOverloadFailed: + OS << "list constructor overloading failed"; + break; - case FK_ExplicitConstructor: - OS << "list copy initialization chose explicit constructor"; - break; + case FK_ExplicitConstructor: + OS << "list copy initialization chose explicit constructor"; + break; + } + OS << '\n'; } - OS << '\n'; return; } diff --git a/clang/test/SemaCXX/diagnostic-initialization.cpp b/clang/test/SemaCXX/diagnostic-initialization.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/diagnostic-initialization.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify=expected %s + +namespace std { +typedef decltype(sizeof(int)) size_t; + +template +class initializer_list { + const _E *__begin_; + size_t __size_; + + initializer_list(const _E *__b, size_t __s) + : __begin_(__b), + __size_(__s) {} + +public: + typedef _E value_type; + typedef const _E &reference; + typedef const _E &const_reference; + typedef size_t size_type; + + typedef const _E *iterator; + typedef const _E *const_iterator; + + initializer_list() : __begin_(nullptr), __size_(0) {} + + size_t size() const { return __size_; } + const _E *begin() const { return __begin_; } + const _E *end() const { return __begin_ + __size_; } +}; +} // namespace std + +// C++11 [over.match.list]p1: +// In copy-list-initialization, if an explicit constructor is chosen, the +// initializer is ill-formed. +struct A { + explicit A(std::initializer_list) = delete; + // expected-note@-1 {{'A' has been explicitly marked deleted here}} + // expected-note@-2 {{explicit constructor declared here}} +}; + +A a = {1, 2, 3}; +// expected-error@-1 {{call to deleted constructor of 'A'}} +// expected-error@-2 {{chosen constructor is explicit in copy-initialization}}