Last active
January 2, 2016 22:59
-
-
Save pfultz2/8373232 to your computer and use it in GitHub Desktop.
Patch for clang to improve sfinae errors.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Index: include/clang/Sema/TemplateDeduction.h | |
=================================================================== | |
--- a/tools/clang/include/clang/Sema/TemplateDeduction.h (revision 159968) | |
+++ b/tools/clang/include/clang/Sema/TemplateDeduction.h (working copy) | |
@@ -39,6 +39,9 @@ | |
/// deduction is occurring. | |
SourceLocation Loc; | |
+ /// \brief Should we suppress errors during substitution? | |
+ bool IsSFINAEContext; | |
+ | |
/// \brief Have we suppressed an error during deduction? | |
bool HasSFINAEDiagnostic; | |
@@ -52,7 +55,8 @@ | |
public: | |
TemplateDeductionInfo(ASTContext &Context, SourceLocation Loc) | |
- : Context(Context), Deduced(0), Loc(Loc), HasSFINAEDiagnostic(false) { } | |
+ : Context(Context), Deduced(0), Loc(Loc), IsSFINAEContext(true), | |
+ HasSFINAEDiagnostic(false) { } | |
~TemplateDeductionInfo() { | |
// FIXME: if (Deduced) Deduced->Destroy(Context); | |
@@ -87,6 +91,10 @@ | |
Deduced = NewDeduced; | |
} | |
+ /// \brief Should we suppress errors during this deduction? | |
+ bool isSFINAEContext() const { return IsSFINAEContext; } | |
+ void setSFINAEContext(bool SFINAE) { IsSFINAEContext = SFINAE; } | |
+ | |
/// \brief Is a SFINAE diagnostic available? | |
bool hasSFINAEDiagnostic() const { | |
return HasSFINAEDiagnostic; | |
Index: lib/Sema/SemaOverload.cpp | |
=================================================================== | |
--- a/tools/clang/lib/Sema/SemaOverload.cpp (revision 159968) | |
+++ b/tools/clang/lib/Sema/SemaOverload.cpp (working copy) | |
@@ -9780,6 +9780,30 @@ | |
if (!Recovery.isInvalid()) | |
return Recovery; | |
+ // If there was only one candidate, and it wasn't viable due to substitution | |
+ // failure, produce its diagnostics instead of ours. | |
+ if (CandidateSet.begin() + 1 == CandidateSet.end() && | |
+ CandidateSet.begin()->DeductionFailure.Result == | |
+ Sema::TDK_SubstitutionFailure) { | |
+ OverloadCandidateSet::iterator Cand = CandidateSet.begin(); | |
+ TemplateDeductionInfo Info(Context, CandidateSet.getLocation()); | |
+ Info.setSFINAEContext(false); | |
+ FunctionDecl *Specialization = 0; | |
+ TemplateArgumentListInfo TemplateArgStorage, *ExplicitTemplateArgs = 0; | |
+ if (ULE->hasExplicitTemplateArgs()) { | |
+ ULE->getExplicitTemplateArgs().copyInto(TemplateArgStorage); | |
+ ExplicitTemplateArgs = &TemplateArgStorage; | |
+ } | |
+ TemplateDeductionResult Result = | |
+ DeduceTemplateArguments(Cand->Function->getDescribedFunctionTemplate(), | |
+ ExplicitTemplateArgs, | |
+ llvm::ArrayRef<Expr*>(Args, NumArgs), | |
+ Specialization, Info); | |
+ assert(Result && "template deduction didn't fail on retry"); | |
+ if (Result) | |
+ break; | |
+ } | |
+ | |
Diag(Fn->getLocStart(), | |
diag::err_ovl_no_viable_function_in_call) | |
<< ULE->getName() << Fn->getSourceRange(); | |
Index: lib/Sema/SemaTemplateInstantiate.cpp | |
=================================================================== | |
--- a/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp (revision 159968) | |
+++ b/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp (working copy) | |
@@ -655,7 +655,8 @@ | |
// We're either substitution explicitly-specified template arguments | |
// or deduced template arguments, so SFINAE applies. | |
assert(Active->DeductionInfo && "Missing deduction info pointer"); | |
- return Active->DeductionInfo; | |
+ if (Active->DeductionInfo->isSFINAEContext()) | |
+ return Active->DeductionInfo; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment