diff options
Diffstat (limited to 'clang/lib/Sema/SemaTemplateDeduction.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 77 |
1 files changed, 72 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 048a50a741e..394c81c8279 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -4414,9 +4414,10 @@ namespace { QualType Result = SemaRef.Context.getAutoType( Replacement, TL.getTypePtr()->getKeyword(), Replacement.isNull(), - ReplacementIsPack); + ReplacementIsPack, TL.getTypePtr()->getTypeConstraintConcept(), + TL.getTypePtr()->getTypeConstraintArguments()); auto NewTL = TLB.push<AutoTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); + NewTL.copy(TL); return Result; } @@ -4451,9 +4452,10 @@ namespace { Sema::DeduceAutoResult Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init, QualType &Result, - Optional<unsigned> DependentDeductionDepth) { + Optional<unsigned> DependentDeductionDepth, + bool IgnoreConstraints) { return DeduceAutoType(Type->getTypeLoc(), Init, Result, - DependentDeductionDepth); + DependentDeductionDepth, IgnoreConstraints); } /// Attempt to produce an informative diagostic explaining why auto deduction @@ -4481,6 +4483,49 @@ static bool diagnoseAutoDeductionFailure(Sema &S, } } +static Sema::DeduceAutoResult +CheckDeducedPlaceholderConstraints(Sema &S, const AutoType &Type, + AutoTypeLoc TypeLoc, QualType Deduced) { + ConstraintSatisfaction Satisfaction; + ConceptDecl *Concept = Type.getTypeConstraintConcept(); + TemplateArgumentListInfo TemplateArgs(TypeLoc.getLAngleLoc(), + TypeLoc.getRAngleLoc()); + TemplateArgs.addArgument( + TemplateArgumentLoc(TemplateArgument(Deduced), + S.Context.getTrivialTypeSourceInfo( + Deduced, TypeLoc.getNameLoc()))); + for (unsigned I = 0, C = TypeLoc.getNumArgs(); I != C; ++I) + TemplateArgs.addArgument(TypeLoc.getArgLoc(I)); + + llvm::SmallVector<TemplateArgument, 4> Converted; + if (S.CheckTemplateArgumentList(Concept, SourceLocation(), TemplateArgs, + /*PartialTemplateArgs=*/false, Converted)) + return Sema::DAR_FailedAlreadyDiagnosed; + if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()}, + Converted, TypeLoc.getLocalSourceRange(), + Satisfaction)) + return Sema::DAR_FailedAlreadyDiagnosed; + if (!Satisfaction.IsSatisfied) { + std::string Buf; + llvm::raw_string_ostream OS(Buf); + OS << "'" << Concept->getName(); + if (TypeLoc.hasExplicitTemplateArgs()) { + OS << "<"; + for (const auto &Arg : Type.getTypeConstraintArguments()) + Arg.print(S.getPrintingPolicy(), OS); + OS << ">"; + } + OS << "'"; + OS.flush(); + S.Diag(TypeLoc.getConceptNameLoc(), + diag::err_placeholder_constraints_not_satisfied) + << Deduced << Buf << TypeLoc.getLocalSourceRange(); + S.DiagnoseUnsatisfiedConstraint(Satisfaction); + return Sema::DAR_FailedAlreadyDiagnosed; + } + return Sema::DAR_Succeeded; +} + /// Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6) /// /// Note that this is done even if the initializer is dependent. (This is @@ -4495,9 +4540,12 @@ static bool diagnoseAutoDeductionFailure(Sema &S, /// dependent cases. This is necessary for template partial ordering with /// 'auto' template parameters. The value specified is the template /// parameter depth at which we should perform 'auto' deduction. +/// \param IgnoreConstraints Set if we should not fail if the deduced type does +/// not satisfy the type-constraint in the auto type. Sema::DeduceAutoResult Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, - Optional<unsigned> DependentDeductionDepth) { + Optional<unsigned> DependentDeductionDepth, + bool IgnoreConstraints) { if (Init->getType()->isNonOverloadPlaceholderType()) { ExprResult NonPlaceholder = CheckPlaceholderExpr(Init); if (NonPlaceholder.isInvalid()) @@ -4538,6 +4586,14 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, return DAR_FailedAlreadyDiagnosed; // FIXME: Support a non-canonical deduced type for 'auto'. Deduced = Context.getCanonicalType(Deduced); + if (AT->isConstrained() && !IgnoreConstraints) { + auto ConstraintsResult = + CheckDeducedPlaceholderConstraints(*this, *AT, + Type.getContainedAutoTypeLoc(), + Deduced); + if (ConstraintsResult != DAR_Succeeded) + return ConstraintsResult; + } Result = SubstituteDeducedTypeTransform(*this, Deduced).Apply(Type); if (Result.isNull()) return DAR_FailedAlreadyDiagnosed; @@ -4645,6 +4701,17 @@ Sema::DeduceAutoType(TypeLoc Type, Expr *&Init, QualType &Result, return DAR_FailedAlreadyDiagnosed; } + if (const auto *AT = Type.getType()->getAs<AutoType>()) { + if (AT->isConstrained() && !IgnoreConstraints) { + auto ConstraintsResult = + CheckDeducedPlaceholderConstraints(*this, *AT, + Type.getContainedAutoTypeLoc(), + DeducedType); + if (ConstraintsResult != DAR_Succeeded) + return ConstraintsResult; + } + } + Result = SubstituteDeducedTypeTransform(*this, DeducedType).Apply(Type); if (Result.isNull()) return DAR_FailedAlreadyDiagnosed; |

