diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -8326,6 +8326,8 @@ // `TryTransform` which will iterate through corrections in // `TransformTypoExpr`. TransformCache.erase(TE); + const auto *CurrentCorrection = + &SemaRef.getTypoExprState(TE).Consumer->getCurrentCorrection(); ExprResult AmbigRes = CheckForRecursiveTypos(TryTransform(E), IsAmbiguous); if (!AmbigRes.isInvalid() || IsAmbiguous) { @@ -8335,6 +8337,11 @@ IsAmbiguous = true; break; } + // Bail out if we didn't make any correction progress on the checking + // TypoExpr TE, otherwise we risk running the loop forever. + if (CurrentCorrection == + &SemaRef.getTypoExprState(TE).Consumer->getCurrentCorrection()) + break; } while ((Next = SemaRef.getTypoExprState(TE).Consumer->peekNextCorrection()) && Next.getEditDistance(false) == TC.getEditDistance(false)); diff --git a/clang/test/Sema/typo-correction-no-hang.c b/clang/test/Sema/typo-correction-no-hang.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/typo-correction-no-hang.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// PR50797 +struct a { + int xxx; +}; + +int g_107; +int g_108; +int g_109; + +struct a g_999; // expected-note 2{{'g_999' declared here}} + +void b() { (g_910.xxx = g_910.xxx); } //expected-error 2{{use of undeclared identifier 'g_910'; did you mean 'g_999'}}