diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-09-25 04:46:05 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-09-25 04:46:05 +0000 |
commit | e49ff3ef3459e97fa76502bd9eae4ed9170fd048 (patch) | |
tree | 4a404becefcdea1230ee2a171be4f4e6f31b4f95 /lib/Sema/SemaOverload.cpp | |
parent | 511e3ae61bc2ff3803195587fe9774cb815726fc (diff) |
Fix crash when a decltype expression in a trailing return type refers to the
function being instantiated. An error recovery codepath was recursively
performing name lookup (and triggering an unbounded stack of template
instantiations which blew out the stack before hitting the depth limit).
Patch by Wei Pan!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164586 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 23 |
1 files changed, 23 insertions, 0 deletions
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()); |