Skip to content

Instantly share code, notes, and snippets.

@pfultz2
Last active January 2, 2016 22:59
Show Gist options
  • Save pfultz2/8373232 to your computer and use it in GitHub Desktop.
Save pfultz2/8373232 to your computer and use it in GitHub Desktop.
Patch for clang to improve sfinae errors.
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