diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Sema/Sema.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 23 |
2 files changed, 24 insertions, 0 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index bd7c8515f6..08ccfa4259 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -90,6 +90,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, CollectStats(false), ExternalSource(0), CodeCompleter(CodeCompleter), CurContext(0), OriginalLexicalContext(0), PackContext(0), MSStructPragmaOn(false), VisContext(0), + IsBuildingRecoveryCallExpr(false), ExprNeedsCleanups(false), LateTemplateParser(0), OpaqueParser(0), IdResolver(pp), StdInitializerList(0), CXXTypeInfoDecl(0), MSVCGuidDecl(0), NSNumberDecl(0), diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index fe4cac8630..e9c2c6c5f6 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -9655,6 +9655,20 @@ class NoTypoCorrectionCCC : public CorrectionCandidateCallback { return false; } }; + +class BuildRecoveryCallExprRAII { + Sema &SemaRef; +public: + BuildRecoveryCallExprRAII(Sema &S) : SemaRef(S) { + assert(SemaRef.IsBuildingRecoveryCallExpr == false); + SemaRef.IsBuildingRecoveryCallExpr = true; + } + + ~BuildRecoveryCallExprRAII() { + SemaRef.IsBuildingRecoveryCallExpr = false; + } +}; + } /// Attempts to recover from a call where no functions were found. @@ -9667,6 +9681,15 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, llvm::MutableArrayRef<Expr *> Args, SourceLocation RParenLoc, bool EmptyLookup, bool AllowTypoCorrection) { + // Do not try to recover if it is already building a recovery call. + // This stops infinite loops for template instantiations like + // + // template <typename T> auto foo(T t) -> decltype(foo(t)) {} + // template <typename T> auto foo(T t) -> decltype(foo(&t)) {} + // + if (SemaRef.IsBuildingRecoveryCallExpr) + return ExprError(); + BuildRecoveryCallExprRAII RCE(SemaRef); CXXScopeSpec SS; SS.Adopt(ULE->getQualifierLoc()); |