aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/Sema.cpp16
-rw-r--r--lib/Sema/SemaExprCXX.cpp9
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp69
3 files changed, 68 insertions, 26 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index e37f617549..44bb71e57b 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -139,7 +139,8 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
IdResolver(pp.getLangOptions()), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
GlobalNewDeleteDeclared(false),
CompleteTranslationUnit(CompleteTranslationUnit),
- NumSFINAEErrors(0), SuppressAccessChecking(false),
+ NumSFINAEErrors(0), SuppressAccessChecking(false),
+ AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false),
NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1),
CurrentInstantiationScope(0), TyposCorrected(0),
AnalysisWarnings(*this)
@@ -450,14 +451,18 @@ Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() {
if (!isActive())
return;
- if (TemplateDeductionInfo *Info = SemaRef.isSFINAEContext()) {
+ if (llvm::Optional<TemplateDeductionInfo*> Info = SemaRef.isSFINAEContext()) {
switch (DiagnosticIDs::getDiagnosticSFINAEResponse(getDiagID())) {
- case DiagnosticIDs::SFINAE_AccessControl:
case DiagnosticIDs::SFINAE_Report:
// Fall through; we'll report the diagnostic below.
break;
-
+ case DiagnosticIDs::SFINAE_AccessControl:
+ // Unless access checking is specifically called out as a SFINAE
+ // error, report this diagnostic.
+ if (!SemaRef.AccessCheckingSFINAE)
+ break;
+
case DiagnosticIDs::SFINAE_SubstitutionFailure:
// Count this failure so that we know that template argument deduction
// has failed.
@@ -473,7 +478,8 @@ Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder() {
FlushCounts();
DiagnosticInfo DiagInfo(&SemaRef.Diags);
- Info->addSuppressedDiagnostic(DiagInfo.getLocation(),
+ if (*Info)
+ (*Info)->addSuppressedDiagnostic(DiagInfo.getLocation(),
PartialDiagnostic(DiagInfo,
SemaRef.Context.getDiagAllocator()));
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index ca104ef581..cf2e10d531 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -2537,13 +2537,14 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT,
InitializationKind Kind(InitializationKind::CreateCopy(KeyLoc,
SourceLocation()));
- // Perform the initialization within a SFINAE trap.
- // FIXME: We don't implement the access-checking bits yet, because we don't
- // handle access control as part of SFINAE.
- Sema::SFINAETrap SFINAE(Self);
+ // Perform the initialization within a SFINAE trap at translation unit
+ // scope.
+ Sema::SFINAETrap SFINAE(Self, /*AccessCheckingSFINAE=*/true);
+ Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl());
InitializationSequence Init(Self, To, Kind, &FromPtr, 1);
if (Init.getKind() == InitializationSequence::FailedSequence)
return false;
+
ExprResult Result = Init.Perform(Self, To, Kind, MultiExprArg(&FromPtr, 1));
return !Result.isInvalid() && !SFINAE.hasErrorOccurred();
}
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 45fde296e3..f58e744578 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -147,7 +147,10 @@ Sema::InstantiatingTemplate::
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
Decl *Entity,
SourceRange InstantiationRange)
- : SemaRef(SemaRef) {
+ : SemaRef(SemaRef),
+ SavedInNonInstantiationSFINAEContext(
+ SemaRef.InNonInstantiationSFINAEContext)
+{
Invalid = CheckInstantiationDepth(PointOfInstantiation,
InstantiationRange);
if (!Invalid) {
@@ -158,6 +161,7 @@ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
Inst.TemplateArgs = 0;
Inst.NumTemplateArgs = 0;
Inst.InstantiationRange = InstantiationRange;
+ SemaRef.InNonInstantiationSFINAEContext = false;
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
}
}
@@ -168,8 +172,10 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
SourceRange InstantiationRange)
- : SemaRef(SemaRef) {
-
+ : SemaRef(SemaRef),
+ SavedInNonInstantiationSFINAEContext(
+ SemaRef.InNonInstantiationSFINAEContext)
+{
Invalid = CheckInstantiationDepth(PointOfInstantiation,
InstantiationRange);
if (!Invalid) {
@@ -181,6 +187,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
Inst.TemplateArgs = TemplateArgs;
Inst.NumTemplateArgs = NumTemplateArgs;
Inst.InstantiationRange = InstantiationRange;
+ SemaRef.InNonInstantiationSFINAEContext = false;
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
}
}
@@ -193,8 +200,10 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
ActiveTemplateInstantiation::InstantiationKind Kind,
sema::TemplateDeductionInfo &DeductionInfo,
SourceRange InstantiationRange)
- : SemaRef(SemaRef) {
-
+ : SemaRef(SemaRef),
+ SavedInNonInstantiationSFINAEContext(
+ SemaRef.InNonInstantiationSFINAEContext)
+{
Invalid = CheckInstantiationDepth(PointOfInstantiation,
InstantiationRange);
if (!Invalid) {
@@ -206,6 +215,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
Inst.NumTemplateArgs = NumTemplateArgs;
Inst.DeductionInfo = &DeductionInfo;
Inst.InstantiationRange = InstantiationRange;
+ SemaRef.InNonInstantiationSFINAEContext = false;
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
if (!Inst.isInstantiationRecord())
@@ -220,8 +230,10 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
unsigned NumTemplateArgs,
sema::TemplateDeductionInfo &DeductionInfo,
SourceRange InstantiationRange)
- : SemaRef(SemaRef) {
-
+ : SemaRef(SemaRef),
+ SavedInNonInstantiationSFINAEContext(
+ SemaRef.InNonInstantiationSFINAEContext)
+{
Invalid = false;
ActiveTemplateInstantiation Inst;
@@ -232,6 +244,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
Inst.NumTemplateArgs = NumTemplateArgs;
Inst.DeductionInfo = &DeductionInfo;
Inst.InstantiationRange = InstantiationRange;
+ SemaRef.InNonInstantiationSFINAEContext = false;
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
assert(!Inst.isInstantiationRecord());
@@ -244,8 +257,10 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
SourceRange InstantiationRange)
- : SemaRef(SemaRef) {
-
+ : SemaRef(SemaRef),
+ SavedInNonInstantiationSFINAEContext(
+ SemaRef.InNonInstantiationSFINAEContext)
+{
Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
if (!Invalid) {
@@ -257,6 +272,7 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
Inst.TemplateArgs = TemplateArgs;
Inst.NumTemplateArgs = NumTemplateArgs;
Inst.InstantiationRange = InstantiationRange;
+ SemaRef.InNonInstantiationSFINAEContext = false;
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
}
}
@@ -267,7 +283,11 @@ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
NonTypeTemplateParmDecl *Param,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
- SourceRange InstantiationRange) : SemaRef(SemaRef) {
+ SourceRange InstantiationRange)
+ : SemaRef(SemaRef),
+ SavedInNonInstantiationSFINAEContext(
+ SemaRef.InNonInstantiationSFINAEContext)
+{
Invalid = false;
ActiveTemplateInstantiation Inst;
@@ -278,6 +298,7 @@ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
Inst.TemplateArgs = TemplateArgs;
Inst.NumTemplateArgs = NumTemplateArgs;
Inst.InstantiationRange = InstantiationRange;
+ SemaRef.InNonInstantiationSFINAEContext = false;
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
assert(!Inst.isInstantiationRecord());
@@ -290,7 +311,11 @@ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
TemplateTemplateParmDecl *Param,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
- SourceRange InstantiationRange) : SemaRef(SemaRef) {
+ SourceRange InstantiationRange)
+ : SemaRef(SemaRef),
+ SavedInNonInstantiationSFINAEContext(
+ SemaRef.InNonInstantiationSFINAEContext)
+{
Invalid = false;
ActiveTemplateInstantiation Inst;
Inst.Kind = ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution;
@@ -300,6 +325,7 @@ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
Inst.TemplateArgs = TemplateArgs;
Inst.NumTemplateArgs = NumTemplateArgs;
Inst.InstantiationRange = InstantiationRange;
+ SemaRef.InNonInstantiationSFINAEContext = false;
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
assert(!Inst.isInstantiationRecord());
@@ -312,7 +338,11 @@ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
NamedDecl *Param,
const TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
- SourceRange InstantiationRange) : SemaRef(SemaRef) {
+ SourceRange InstantiationRange)
+ : SemaRef(SemaRef),
+ SavedInNonInstantiationSFINAEContext(
+ SemaRef.InNonInstantiationSFINAEContext)
+{
Invalid = false;
ActiveTemplateInstantiation Inst;
@@ -323,6 +353,7 @@ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
Inst.TemplateArgs = TemplateArgs;
Inst.NumTemplateArgs = NumTemplateArgs;
Inst.InstantiationRange = InstantiationRange;
+ SemaRef.InNonInstantiationSFINAEContext = false;
SemaRef.ActiveTemplateInstantiations.push_back(Inst);
assert(!Inst.isInstantiationRecord());
@@ -335,7 +366,8 @@ void Sema::InstantiatingTemplate::Clear() {
assert(SemaRef.NonInstantiationEntries > 0);
--SemaRef.NonInstantiationEntries;
}
-
+ SemaRef.InNonInstantiationSFINAEContext
+ = SavedInNonInstantiationSFINAEContext;
SemaRef.ActiveTemplateInstantiations.pop_back();
Invalid = true;
}
@@ -530,8 +562,11 @@ void Sema::PrintInstantiationStack() {
}
}
-TemplateDeductionInfo *Sema::isSFINAEContext() const {
+llvm::Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
using llvm::SmallVector;
+ if (InNonInstantiationSFINAEContext)
+ return llvm::Optional<TemplateDeductionInfo *>(0);
+
for (SmallVector<ActiveTemplateInstantiation, 16>::const_reverse_iterator
Active = ActiveTemplateInstantiations.rbegin(),
ActiveEnd = ActiveTemplateInstantiations.rend();
@@ -539,10 +574,10 @@ TemplateDeductionInfo *Sema::isSFINAEContext() const {
++Active)
{
switch(Active->Kind) {
- case ActiveTemplateInstantiation::TemplateInstantiation:
case ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation:
+ case ActiveTemplateInstantiation::TemplateInstantiation:
// This is a template instantiation, so there is no SFINAE.
- return 0;
+ return llvm::Optional<TemplateDeductionInfo *>();
case ActiveTemplateInstantiation::DefaultTemplateArgumentInstantiation:
case ActiveTemplateInstantiation::PriorTemplateArgumentSubstitution:
@@ -561,7 +596,7 @@ TemplateDeductionInfo *Sema::isSFINAEContext() const {
}
}
- return 0;
+ return llvm::Optional<TemplateDeductionInfo *>();
}
/// \brief Retrieve the depth and index of a parameter pack.