This is a patch for PR33484.
The clang's typo correction logic may fall into an infinite loop when reaching the typo correction limit.
When some complex expression has multiple typos in it, clang finds possible corrections for each typo and processes various permutations of these corrections. The typo corrections counter is incremented during the process and compared to the max allowed limit (50 by default). Hang may happen if the limit is reached in the middle of complex expression processing. In this case transform of the current part of the expression fails, making clang ignore its subsequent parts and bail out to the main transform loop in TransformTypos::Transform(Expr *E). On the next iteration, clang fails at the very beginning of transform and no longer reaches the rest of the expression immediately bailing out to the main loop. The transform cannot advance since this moment. As the loop exit condition requires either a fully successful transform or having all the permutations processed, it can never become true.
Yet another reproducer with a readable C++ code:
namespace { struct V { float x; }; class H { public: const V& getV() const { return mV; } int getN() const { return mN; } private: V mV; int mN; }; class T { public: const H& getH0() const { return mH0; } const H& getH1() const { return mH1; } const V& getV0() const { return mH0.getV(); } const V& getV1() const { return mH1.getV(); } private: H mH0; H mH1; }; T sT; H sH; } void func() { ( sT.getH2().getM() > sH.getM() ? sT.getH3() : 0 ); }
Here, both the condition and LHS of ?: have typos. If the limit is exceeded, the transform will fail on the condition and will no longer proceed to LHS and process its substitutions.
The patch adds a limit check into the main loop exit condition.