@@ -4362,6 +4362,13 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc,
4362
4362
Converted, /* UpdateArgsWithConversion=*/ true ))
4363
4363
return true ;
4364
4364
4365
+ // Produce a placeholder value if the specialization is dependent.
4366
+ bool InstantiationDependent = false ;
4367
+ if (Template->getDeclContext ()->isDependentContext () ||
4368
+ TemplateSpecializationType::anyDependentTemplateArguments (
4369
+ TemplateArgs, InstantiationDependent))
4370
+ return DeclResult ();
4371
+
4365
4372
// Find the variable template specialization declaration that
4366
4373
// corresponds to these arguments.
4367
4374
void *InsertPos = nullptr ;
@@ -4389,84 +4396,75 @@ Sema::CheckVarTemplateId(VarTemplateDecl *Template, SourceLocation TemplateLoc,
4389
4396
4390
4397
// 1. Attempt to find the closest partial specialization that this
4391
4398
// specializes, if any.
4392
- // If any of the template arguments is dependent, then this is probably
4393
- // a placeholder for an incomplete declarative context; which must be
4394
- // complete by instantiation time. Thus, do not search through the partial
4395
- // specializations yet.
4396
4399
// TODO: Unify with InstantiateClassTemplateSpecialization()?
4397
4400
// Perhaps better after unification of DeduceTemplateArguments() and
4398
4401
// getMoreSpecializedPartialSpecialization().
4399
- bool InstantiationDependent = false ;
4400
- if (!TemplateSpecializationType::anyDependentTemplateArguments (
4401
- TemplateArgs, InstantiationDependent)) {
4402
-
4403
- SmallVector<VarTemplatePartialSpecializationDecl *, 4 > PartialSpecs;
4404
- Template->getPartialSpecializations (PartialSpecs);
4402
+ SmallVector<VarTemplatePartialSpecializationDecl *, 4 > PartialSpecs;
4403
+ Template->getPartialSpecializations (PartialSpecs);
4405
4404
4406
- for (unsigned I = 0 , N = PartialSpecs.size (); I != N; ++I) {
4407
- VarTemplatePartialSpecializationDecl *Partial = PartialSpecs[I];
4408
- TemplateDeductionInfo Info (FailedCandidates.getLocation ());
4405
+ for (unsigned I = 0 , N = PartialSpecs.size (); I != N; ++I) {
4406
+ VarTemplatePartialSpecializationDecl *Partial = PartialSpecs[I];
4407
+ TemplateDeductionInfo Info (FailedCandidates.getLocation ());
4409
4408
4410
- if (TemplateDeductionResult Result =
4411
- DeduceTemplateArguments (Partial, TemplateArgList, Info)) {
4412
- // Store the failed-deduction information for use in diagnostics, later.
4413
- // TODO: Actually use the failed-deduction info?
4414
- FailedCandidates.addCandidate ().set (
4415
- DeclAccessPair::make (Template, AS_public), Partial,
4416
- MakeDeductionFailureInfo (Context, Result, Info));
4417
- (void )Result;
4418
- } else {
4419
- Matched.push_back (PartialSpecMatchResult ());
4420
- Matched.back ().Partial = Partial;
4421
- Matched.back ().Args = Info.take ();
4422
- }
4409
+ if (TemplateDeductionResult Result =
4410
+ DeduceTemplateArguments (Partial, TemplateArgList, Info)) {
4411
+ // Store the failed-deduction information for use in diagnostics, later.
4412
+ // TODO: Actually use the failed-deduction info?
4413
+ FailedCandidates.addCandidate ().set (
4414
+ DeclAccessPair::make (Template, AS_public), Partial,
4415
+ MakeDeductionFailureInfo (Context, Result, Info));
4416
+ (void )Result;
4417
+ } else {
4418
+ Matched.push_back (PartialSpecMatchResult ());
4419
+ Matched.back ().Partial = Partial;
4420
+ Matched.back ().Args = Info.take ();
4423
4421
}
4422
+ }
4424
4423
4425
- if (Matched.size () >= 1 ) {
4426
- SmallVector<MatchResult, 4 >::iterator Best = Matched.begin ();
4427
- if (Matched.size () == 1 ) {
4428
- // -- If exactly one matching specialization is found, the
4429
- // instantiation is generated from that specialization.
4430
- // We don't need to do anything for this.
4431
- } else {
4432
- // -- If more than one matching specialization is found, the
4433
- // partial order rules (14.5.4.2) are used to determine
4434
- // whether one of the specializations is more specialized
4435
- // than the others. If none of the specializations is more
4436
- // specialized than all of the other matching
4437
- // specializations, then the use of the variable template is
4438
- // ambiguous and the program is ill-formed.
4439
- for (SmallVector<MatchResult, 4 >::iterator P = Best + 1 ,
4440
- PEnd = Matched.end ();
4441
- P != PEnd; ++P) {
4442
- if (getMoreSpecializedPartialSpecialization (P->Partial , Best->Partial ,
4443
- PointOfInstantiation) ==
4444
- P->Partial )
4445
- Best = P;
4446
- }
4424
+ if (Matched.size () >= 1 ) {
4425
+ SmallVector<MatchResult, 4 >::iterator Best = Matched.begin ();
4426
+ if (Matched.size () == 1 ) {
4427
+ // -- If exactly one matching specialization is found, the
4428
+ // instantiation is generated from that specialization.
4429
+ // We don't need to do anything for this.
4430
+ } else {
4431
+ // -- If more than one matching specialization is found, the
4432
+ // partial order rules (14.5.4.2) are used to determine
4433
+ // whether one of the specializations is more specialized
4434
+ // than the others. If none of the specializations is more
4435
+ // specialized than all of the other matching
4436
+ // specializations, then the use of the variable template is
4437
+ // ambiguous and the program is ill-formed.
4438
+ for (SmallVector<MatchResult, 4 >::iterator P = Best + 1 ,
4439
+ PEnd = Matched.end ();
4440
+ P != PEnd; ++P) {
4441
+ if (getMoreSpecializedPartialSpecialization (P->Partial , Best->Partial ,
4442
+ PointOfInstantiation) ==
4443
+ P->Partial )
4444
+ Best = P;
4445
+ }
4447
4446
4448
- // Determine if the best partial specialization is more specialized than
4449
- // the others.
4450
- for (SmallVector<MatchResult, 4 >::iterator P = Matched.begin (),
4451
- PEnd = Matched.end ();
4452
- P != PEnd; ++P) {
4453
- if (P != Best && getMoreSpecializedPartialSpecialization (
4454
- P->Partial , Best->Partial ,
4455
- PointOfInstantiation) != Best->Partial ) {
4456
- AmbiguousPartialSpec = true ;
4457
- break ;
4458
- }
4447
+ // Determine if the best partial specialization is more specialized than
4448
+ // the others.
4449
+ for (SmallVector<MatchResult, 4 >::iterator P = Matched.begin (),
4450
+ PEnd = Matched.end ();
4451
+ P != PEnd; ++P) {
4452
+ if (P != Best && getMoreSpecializedPartialSpecialization (
4453
+ P->Partial , Best->Partial ,
4454
+ PointOfInstantiation) != Best->Partial ) {
4455
+ AmbiguousPartialSpec = true ;
4456
+ break ;
4459
4457
}
4460
4458
}
4461
-
4462
- // Instantiate using the best variable template partial specialization.
4463
- InstantiationPattern = Best->Partial ;
4464
- InstantiationArgs = Best->Args ;
4465
- } else {
4466
- // -- If no match is found, the instantiation is generated
4467
- // from the primary template.
4468
- // InstantiationPattern = Template->getTemplatedDecl();
4469
4459
}
4460
+
4461
+ // Instantiate using the best variable template partial specialization.
4462
+ InstantiationPattern = Best->Partial ;
4463
+ InstantiationArgs = Best->Args ;
4464
+ } else {
4465
+ // -- If no match is found, the instantiation is generated
4466
+ // from the primary template.
4467
+ // InstantiationPattern = Template->getTemplatedDecl();
4470
4468
}
4471
4469
4472
4470
// 2. Create the canonical declaration.
@@ -4514,6 +4512,9 @@ Sema::CheckVarTemplateId(const CXXScopeSpec &SS,
4514
4512
if (Decl.isInvalid ())
4515
4513
return ExprError ();
4516
4514
4515
+ if (!Decl.get ())
4516
+ return ExprResult ();
4517
+
4517
4518
VarDecl *Var = cast<VarDecl>(Decl.get ());
4518
4519
if (!Var->getTemplateSpecializationKind ())
4519
4520
Var->setTemplateSpecializationKind (TSK_ImplicitInstantiation,
@@ -4601,18 +4602,14 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
4601
4602
}
4602
4603
}
4603
4604
4604
- auto AnyDependentArguments = [&]() -> bool {
4605
- bool InstantiationDependent;
4606
- return TemplateArgs &&
4607
- TemplateSpecializationType::anyDependentTemplateArguments (
4608
- *TemplateArgs, InstantiationDependent);
4609
- };
4610
-
4611
4605
// In C++1y, check variable template ids.
4612
- if (R.getAsSingle <VarTemplateDecl>() && !AnyDependentArguments ()) {
4613
- return CheckVarTemplateId (SS, R.getLookupNameInfo (),
4614
- R.getAsSingle <VarTemplateDecl>(),
4615
- TemplateKWLoc, TemplateArgs);
4606
+ if (R.getAsSingle <VarTemplateDecl>()) {
4607
+ ExprResult Res = CheckVarTemplateId (SS, R.getLookupNameInfo (),
4608
+ R.getAsSingle <VarTemplateDecl>(),
4609
+ TemplateKWLoc, TemplateArgs);
4610
+ if (Res.isInvalid () || Res.isUsable ())
4611
+ return Res;
4612
+ // Result is dependent. Carry on to build an UnresolvedLookupEpxr.
4616
4613
}
4617
4614
4618
4615
if (R.getAsSingle <ConceptDecl>()) {
@@ -9921,6 +9918,14 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
9921
9918
if (Res.isInvalid ())
9922
9919
return true ;
9923
9920
9921
+ if (!Res.isUsable ()) {
9922
+ // We somehow specified dependent template arguments in an explicit
9923
+ // instantiation. This should probably only happen during error
9924
+ // recovery.
9925
+ Diag (D.getIdentifierLoc (), diag::err_explicit_instantiation_dependent);
9926
+ return true ;
9927
+ }
9928
+
9924
9929
// Ignore access control bits, we don't need them for redeclaration
9925
9930
// checking.
9926
9931
Prev = cast<VarDecl>(Res.get ());
0 commit comments