iid_iunknown created this revision.
iid_iunknown added a project: clang.
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.
Repository:
rL LLVM
https://reviews.llvm.org/D34430
Files:
lib/Sema/SemaExprCXX.cpp
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -7246,10 +7246,13 @@
/// TransformCache). Returns true if there is still any untried combinations
/// of corrections.
bool CheckAndAdvanceTypoExprCorrectionStreams() {
+ bool CheckLimitExceeded =
+ SemaRef.TyposCorrected >=
+ SemaRef.getDiagnostics().getDiagnosticOptions().SpellCheckingLimit;
for (auto TE : TypoExprs) {
auto &State = SemaRef.getTypoExprState(TE);
TransformCache.erase(TE);
- if (!State.Consumer->finished())
+ if (!CheckLimitExceeded && !State.Consumer->finished())
return true;
State.Consumer->resetCorrectionStream();
}
Index: lib/Sema/SemaExprCXX.cpp
===================================================================
--- lib/Sema/SemaExprCXX.cpp
+++ lib/Sema/SemaExprCXX.cpp
@@ -7246,10 +7246,13 @@
/// TransformCache). Returns true if there is still any untried combinations
/// of corrections.
bool CheckAndAdvanceTypoExprCorrectionStreams() {
+ bool CheckLimitExceeded =
+ SemaRef.TyposCorrected >=
+ SemaRef.getDiagnostics().getDiagnosticOptions().SpellCheckingLimit;
for (auto TE : TypoExprs) {
auto &State = SemaRef.getTypoExprState(TE);
TransformCache.erase(TE);
- if (!State.Consumer->finished())
+ if (!CheckLimitExceeded && !State.Consumer->finished())
return true;
State.Consumer->resetCorrectionStream();
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits