diff options
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 239 |
1 files changed, 166 insertions, 73 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 10c0c6bf33..e8a8887736 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -1,9 +1,8 @@ //===--- SemaInit.cpp - Semantic Analysis for Initializers ----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -145,16 +144,43 @@ static StringInitFailureKind IsStringInit(Expr *init, QualType declType, static void updateStringLiteralType(Expr *E, QualType Ty) { while (true) { E->setType(Ty); - if (isa<StringLiteral>(E) || isa<ObjCEncodeExpr>(E)) + E->setValueKind(VK_RValue); + if (isa<StringLiteral>(E) || isa<ObjCEncodeExpr>(E)) { break; - else if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) + } else if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) { E = PE->getSubExpr(); - else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) + } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { + assert(UO->getOpcode() == UO_Extension); E = UO->getSubExpr(); - else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E)) + } else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E)) { E = GSE->getResultExpr(); - else + } else if (ChooseExpr *CE = dyn_cast<ChooseExpr>(E)) { + E = CE->getChosenSubExpr(); + } else { llvm_unreachable("unexpected expr in string literal init"); + } + } +} + +/// Fix a compound literal initializing an array so it's correctly marked +/// as an rvalue. +static void updateGNUCompoundLiteralRValue(Expr *E) { + while (true) { + E->setValueKind(VK_RValue); + if (isa<CompoundLiteralExpr>(E)) { + break; + } else if (ParenExpr *PE = dyn_cast<ParenExpr>(E)) { + E = PE->getSubExpr(); + } else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) { + assert(UO->getOpcode() == UO_Extension); + E = UO->getSubExpr(); + } else if (GenericSelectionExpr *GSE = dyn_cast<GenericSelectionExpr>(E)) { + E = GSE->getResultExpr(); + } else if (ChooseExpr *CE = dyn_cast<ChooseExpr>(E)) { + E = CE->getChosenSubExpr(); + } else { + llvm_unreachable("unexpected expr in array compound literal init"); + } } } @@ -2182,7 +2208,7 @@ namespace { // Callback to only accept typo corrections that are for field members of // the given struct or union. -class FieldInitializerValidatorCCC : public CorrectionCandidateCallback { +class FieldInitializerValidatorCCC final : public CorrectionCandidateCallback { public: explicit FieldInitializerValidatorCCC(RecordDecl *RD) : Record(RD) {} @@ -2192,6 +2218,10 @@ class FieldInitializerValidatorCCC : public CorrectionCandidateCallback { return FD && FD->getDeclContext()->getRedeclContext()->Equals(Record); } + std::unique_ptr<CorrectionCandidateCallback> clone() override { + return llvm::make_unique<FieldInitializerValidatorCCC>(*this); + } + private: RecordDecl *Record; }; @@ -2394,10 +2424,10 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, // Name lookup didn't find anything. // Determine whether this was a typo for another field name. + FieldInitializerValidatorCCC CCC(RT->getDecl()); if (TypoCorrection Corrected = SemaRef.CorrectTypo( DeclarationNameInfo(FieldName, D->getFieldLoc()), - Sema::LookupMemberName, /*Scope=*/nullptr, /*SS=*/nullptr, - llvm::make_unique<FieldInitializerValidatorCCC>(RT->getDecl()), + Sema::LookupMemberName, /*Scope=*/nullptr, /*SS=*/nullptr, CCC, Sema::CTK_ErrorRecovery, RT->getDecl())) { SemaRef.diagnoseTypo( Corrected, @@ -4671,19 +4701,23 @@ static void TryReferenceInitializationCore(Sema &S, // applied. // Postpone address space conversions to after the temporary materialization // conversion to allow creating temporaries in the alloca address space. - auto AS1 = T1Quals.getAddressSpace(); - auto AS2 = T2Quals.getAddressSpace(); - T1Quals.removeAddressSpace(); - T2Quals.removeAddressSpace(); - QualType cv1T4 = S.Context.getQualifiedType(cv2T2, T1Quals); - if (T1Quals != T2Quals) + auto T1QualsIgnoreAS = T1Quals; + auto T2QualsIgnoreAS = T2Quals; + if (T1Quals.getAddressSpace() != T2Quals.getAddressSpace()) { + T1QualsIgnoreAS.removeAddressSpace(); + T2QualsIgnoreAS.removeAddressSpace(); + } + QualType cv1T4 = S.Context.getQualifiedType(cv2T2, T1QualsIgnoreAS); + if (T1QualsIgnoreAS != T2QualsIgnoreAS) Sequence.AddQualificationConversionStep(cv1T4, ValueKind); Sequence.AddReferenceBindingStep(cv1T4, ValueKind == VK_RValue); ValueKind = isLValueRef ? VK_LValue : VK_XValue; - if (AS1 != AS2) { - T1Quals.addAddressSpace(AS1); - QualType cv1AST4 = S.Context.getQualifiedType(cv2T2, T1Quals); - Sequence.AddQualificationConversionStep(cv1AST4, ValueKind); + // Add addr space conversion if required. + if (T1Quals.getAddressSpace() != T2Quals.getAddressSpace()) { + auto T4Quals = cv1T4.getQualifiers(); + T4Quals.addAddressSpace(T1Quals.getAddressSpace()); + QualType cv1T4WithAS = S.Context.getQualifiedType(T2, T4Quals); + Sequence.AddQualificationConversionStep(cv1T4WithAS, ValueKind); } // In any case, the reference is bound to the resulting glvalue (or to @@ -4730,7 +4764,15 @@ static void TryReferenceInitializationCore(Sema &S, // copy-initialization (8.5). The reference is then bound to the // temporary. [...] - InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(cv1T1); + // Ignore address space of reference type at this point and perform address + // space conversion after the reference binding step. + QualType cv1T1IgnoreAS = + T1Quals.hasAddressSpace() + ? S.Context.getQualifiedType(T1, T1Quals.withoutAddressSpace()) + : cv1T1; + + InitializedEntity TempEntity = + InitializedEntity::InitializeTemporary(cv1T1IgnoreAS); // FIXME: Why do we use an implicit conversion here rather than trying // copy-initialization? @@ -4765,8 +4807,9 @@ static void TryReferenceInitializationCore(Sema &S, // than, cv2; otherwise, the program is ill-formed. unsigned T1CVRQuals = T1Quals.getCVRQualifiers(); unsigned T2CVRQuals = T2Quals.getCVRQualifiers(); - if (RefRelationship == Sema::Ref_Related && - (T1CVRQuals | T2CVRQuals) != T1CVRQuals) { + if ((RefRelationship == Sema::Ref_Related && + (T1CVRQuals | T2CVRQuals) != T1CVRQuals) || + !T1Quals.isAddressSpaceSupersetOf(T2Quals)) { Sequence.SetFailed(InitializationSequence::FK_ReferenceInitDropsQualifiers); return; } @@ -4780,7 +4823,11 @@ static void TryReferenceInitializationCore(Sema &S, return; } - Sequence.AddReferenceBindingStep(cv1T1, /*bindingTemporary=*/true); + Sequence.AddReferenceBindingStep(cv1T1IgnoreAS, /*bindingTemporary=*/true); + + if (T1Quals.hasAddressSpace()) + Sequence.AddQualificationConversionStep(cv1T1, isLValueRef ? VK_LValue + : VK_XValue); } /// Attempt character array initialization from a string literal @@ -5538,8 +5585,7 @@ void InitializationSequence::InitializeFrom(Sema &S, // array from a compound literal that creates an array of the same // type, so long as the initializer has no side effects. if (!S.getLangOpts().CPlusPlus && Initializer && - (isa<ConstantExpr>(Initializer->IgnoreParens()) || - isa<CompoundLiteralExpr>(Initializer->IgnoreParens())) && + isa<CompoundLiteralExpr>(Initializer->IgnoreParens()) && Initializer->getType()->isArrayType()) { const ArrayType *SourceAT = Context.getAsArrayType(Initializer->getType()); @@ -5925,21 +5971,25 @@ static ExprResult CopyObject(Sema &S, break; case OR_No_Viable_Function: - S.Diag(Loc, IsExtraneousCopy && !S.isSFINAEContext() - ? diag::ext_rvalue_to_reference_temp_copy_no_viable - : diag::err_temp_copy_no_viable) - << (int)Entity.getKind() << CurInitExpr->getType() - << CurInitExpr->getSourceRange(); - CandidateSet.NoteCandidates(S, OCD_AllCandidates, CurInitExpr); + CandidateSet.NoteCandidates( + PartialDiagnosticAt( + Loc, S.PDiag(IsExtraneousCopy && !S.isSFINAEContext() + ? diag::ext_rvalue_to_reference_temp_copy_no_viable + : diag::err_temp_copy_no_viable) + << (int)Entity.getKind() << CurInitExpr->getType() + << CurInitExpr->getSourceRange()), + S, OCD_AllCandidates, CurInitExpr); if (!IsExtraneousCopy || S.isSFINAEContext()) return ExprError(); return CurInit; case OR_Ambiguous: - S.Diag(Loc, diag::err_temp_copy_ambiguous) - << (int)Entity.getKind() << CurInitExpr->getType() - << CurInitExpr->getSourceRange(); - CandidateSet.NoteCandidates(S, OCD_ViableCandidates, CurInitExpr); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(Loc, S.PDiag(diag::err_temp_copy_ambiguous) + << (int)Entity.getKind() + << CurInitExpr->getType() + << CurInitExpr->getSourceRange()), + S, OCD_ViableCandidates, CurInitExpr); return ExprError(); case OR_Deleted: @@ -6074,13 +6124,13 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S, break; case OR_No_Viable_Function: - S.Diag(Loc, Diag); - CandidateSet.NoteCandidates(S, OCD_AllCandidates, CurInitExpr); + CandidateSet.NoteCandidates(PartialDiagnosticAt(Loc, Diag), S, + OCD_AllCandidates, CurInitExpr); break; case OR_Ambiguous: - S.Diag(Loc, Diag); - CandidateSet.NoteCandidates(S, OCD_ViableCandidates, CurInitExpr); + CandidateSet.NoteCandidates(PartialDiagnosticAt(Loc, Diag), S, + OCD_ViableCandidates, CurInitExpr); break; case OR_Deleted: @@ -7275,9 +7325,19 @@ ExprResult Sema::TemporaryMaterializationConversion(Expr *E) { ExprResult Sema::PerformQualificationConversion(Expr *E, QualType Ty, ExprValueKind VK, CheckedConversionKind CCK) { - CastKind CK = (Ty.getAddressSpace() != E->getType().getAddressSpace()) - ? CK_AddressSpaceConversion - : CK_NoOp; + + CastKind CK = CK_NoOp; + + if (VK == VK_RValue) { + auto PointeeTy = Ty->getPointeeType(); + auto ExprPointeeTy = E->getType()->getPointeeType(); + if (!PointeeTy.isNull() && + PointeeTy.getAddressSpace() != ExprPointeeTy.getAddressSpace()) + CK = CK_AddressSpaceConversion; + } else if (Ty.getAddressSpace() != E->getType().getAddressSpace()) { + CK = CK_AddressSpaceConversion; + } + return ImpCastExprToType(E, Ty, CK, VK, /*BasePath=*/nullptr, CCK); } @@ -7952,6 +8012,7 @@ ExprResult InitializationSequence::Perform(Sema &S, S.Diag(Kind.getLocation(), diag::ext_array_init_copy) << Step->Type << CurInit.get()->getType() << CurInit.get()->getSourceRange(); + updateGNUCompoundLiteralRValue(CurInit.get()); LLVM_FALLTHROUGH; case SK_ArrayInit: // If the destination type is an incomplete array type, update the @@ -8342,19 +8403,22 @@ bool InitializationSequence::Diagnose(Sema &S, case FK_UserConversionOverloadFailed: switch (FailedOverloadResult) { case OR_Ambiguous: - if (Failure == FK_UserConversionOverloadFailed) - S.Diag(Kind.getLocation(), diag::err_typecheck_ambiguous_condition) - << OnlyArg->getType() << DestType - << Args[0]->getSourceRange(); - else - S.Diag(Kind.getLocation(), diag::err_ref_init_ambiguous) - << DestType << OnlyArg->getType() - << Args[0]->getSourceRange(); - FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates, Args); + 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_ViableCandidates, Args); break; - case OR_No_Viable_Function: + 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, @@ -8364,9 +8428,9 @@ bool InitializationSequence::Diagnose(Sema &S, << OnlyArg->getType() << Args[0]->getSourceRange() << DestType.getNonReferenceType(); - FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args); + FailedCandidateSet.NoteCandidates(S, Args, Cands); break; - + } case OR_Deleted: { S.Diag(Kind.getLocation(), diag::err_typecheck_deleted_function) << OnlyArg->getType() << DestType.getNonReferenceType() @@ -8451,6 +8515,7 @@ bool InitializationSequence::Diagnose(Sema &S, case FK_ReferenceInitFailed: S.Diag(Kind.getLocation(), diag::err_reference_bind_failed) << DestType.getNonReferenceType() + << DestType.getNonReferenceType()->isIncompleteType() << OnlyArg->isLValue() << OnlyArg->getType() << Args[0]->getSourceRange(); @@ -8529,9 +8594,11 @@ bool InitializationSequence::Diagnose(Sema &S, // bad. switch (FailedOverloadResult) { case OR_Ambiguous: - S.Diag(Kind.getLocation(), diag::err_ovl_ambiguous_init) - << DestType << ArgsRange; - FailedCandidateSet.NoteCandidates(S, OCD_ViableCandidates, Args); + FailedCandidateSet.NoteCandidates( + PartialDiagnosticAt(Kind.getLocation(), + S.PDiag(diag::err_ovl_ambiguous_init) + << DestType << ArgsRange), + S, OCD_ViableCandidates, Args); break; case OR_No_Viable_Function: @@ -8580,9 +8647,12 @@ bool InitializationSequence::Diagnose(Sema &S, break; } - S.Diag(Kind.getLocation(), diag::err_ovl_no_viable_function_in_init) - << DestType << ArgsRange; - FailedCandidateSet.NoteCandidates(S, OCD_AllCandidates, Args); + FailedCandidateSet.NoteCandidates( + PartialDiagnosticAt( + Kind.getLocation(), + S.PDiag(diag::err_ovl_no_viable_function_in_init) + << DestType << ArgsRange), + S, OCD_AllCandidates, Args); break; case OR_Deleted: { @@ -8591,7 +8661,7 @@ bool InitializationSequence::Diagnose(Sema &S, = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best); if (Ovl != OR_Deleted) { S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init) - << true << DestType << ArgsRange; + << DestType << ArgsRange; llvm_unreachable("Inconsistent overload resolution?"); break; } @@ -8605,7 +8675,7 @@ bool InitializationSequence::Diagnose(Sema &S, << DestType << ArgsRange; else S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init) - << true << DestType << ArgsRange; + << DestType << ArgsRange; S.NoteDeletedFunction(Best->Function); break; @@ -9264,9 +9334,14 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( OverloadCandidateSet Candidates(Kind.getLocation(), OverloadCandidateSet::CSK_Normal); OverloadCandidateSet::iterator Best; + + bool HasAnyDeductionGuide = false; + auto tryToResolveOverload = [&](bool OnlyListConstructors) -> OverloadingResult { Candidates.clear(OverloadCandidateSet::CSK_Normal); + HasAnyDeductionGuide = false; + for (auto I = Guides.begin(), E = Guides.end(); I != E; ++I) { NamedDecl *D = (*I)->getUnderlyingDecl(); if (D->isInvalidDecl()) @@ -9278,6 +9353,9 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( if (!GD) continue; + if (!GD->isImplicit()) + HasAnyDeductionGuide = true; + // C++ [over.match.ctor]p1: (non-list copy-initialization from non-class) // For copy-initialization, the candidate functions are all the // converting constructors (12.3.1) of that class. @@ -9372,12 +9450,15 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( switch (Result) { case OR_Ambiguous: - Diag(Kind.getLocation(), diag::err_deduced_class_template_ctor_ambiguous) - << TemplateName; // FIXME: For list-initialization candidates, it'd usually be better to // list why they were not viable when given the initializer list itself as // an argument. - Candidates.NoteCandidates(*this, OCD_ViableCandidates, Inits); + Candidates.NoteCandidates( + PartialDiagnosticAt( + Kind.getLocation(), + PDiag(diag::err_deduced_class_template_ctor_ambiguous) + << TemplateName), + *this, OCD_ViableCandidates, Inits); return QualType(); case OR_No_Viable_Function: { @@ -9385,11 +9466,13 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( cast<ClassTemplateDecl>(Template)->getTemplatedDecl(); bool Complete = isCompleteType(Kind.getLocation(), Context.getTypeDeclType(Primary)); - Diag(Kind.getLocation(), - Complete ? diag::err_deduced_class_template_ctor_no_viable - : diag::err_deduced_class_template_incomplete) - << TemplateName << !Guides.empty(); - Candidates.NoteCandidates(*this, OCD_AllCandidates, Inits); + Candidates.NoteCandidates( + PartialDiagnosticAt( + Kind.getLocation(), + PDiag(Complete ? diag::err_deduced_class_template_ctor_no_viable + : diag::err_deduced_class_template_incomplete) + << TemplateName << !Guides.empty()), + *this, OCD_AllCandidates, Inits); return QualType(); } @@ -9430,5 +9513,15 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer( Diag(TSInfo->getTypeLoc().getBeginLoc(), diag::warn_cxx14_compat_class_template_argument_deduction) << TSInfo->getTypeLoc().getSourceRange() << 1 << DeducedType; + + // Warn if CTAD was used on a type that does not have any user-defined + // deduction guides. + if (!HasAnyDeductionGuide) { + Diag(TSInfo->getTypeLoc().getBeginLoc(), + diag::warn_ctad_maybe_unsupported) + << TemplateName; + Diag(Template->getLocation(), diag::note_suppress_ctad_maybe_unsupported); + } + return DeducedType; } |