erik.pilkington created this revision.
erik.pilkington added a reviewer: rsmith.
erik.pilkington added a subscriber: cfe-commits.

Previously, Clang crashed when parsing a `BinaryOperator` in C with a typo when 
a typo was already found. This is because the parser called `Sema::ActOnBinOp`, 
which corrects the found typo in C mode, then corrects the typo again from the 
parser. During the first correction pass, the `TypoExprState` corresponding to 
the typo was cleared from Sema when it was corrected. During a second pass, an 
assert fails in `Sema::getTypoExprState` because it cannot find the 
`TypoExprState`. The fix is to avoid correcting delayed typos in the parser in 
that case.

This patch looks like it fixes PR26700, PR27231, and PR27038.

On a more general note, the handling of delayed typo expressions is very messy 
right now, some of them are handled in semantic analysis, and some are handled 
in the parser, leading to easy to make responsibility bugs like this one. I 
think I might take a look at moving the correcting to one side or the other in 
a future patch.

http://reviews.llvm.org/D20490

Files:
  lib/Parse/ParseExpr.cpp
  test/Sema/typo-correction.c

Index: test/Sema/typo-correction.c
===================================================================
--- test/Sema/typo-correction.c
+++ test/Sema/typo-correction.c
@@ -57,3 +57,11 @@
 }
 
 int d = X ? d : L; // expected-error 2 {{use of undeclared identifier}}
+
+int fn_with_ids() { ID = ID == ID >= ID ; } // expected-error 4 {{use of 
undeclared identifier}}
+
+int fn_with_rs(int r) { r = TYPO + r * TYPO; } // expected-error 2 {{use of 
undeclared identifier}}
+
+void fn_with_unknown(int a, int b) {
+  fn_with_unknown(unknown, unknown | unknown); // expected-error 3 {{use of 
undeclared identifier}}
+}
Index: lib/Parse/ParseExpr.cpp
===================================================================
--- lib/Parse/ParseExpr.cpp
+++ lib/Parse/ParseExpr.cpp
@@ -446,6 +446,10 @@
 
         LHS = Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(),
                                  OpToken.getKind(), LHS.get(), RHS.get());
+
+        // In this case, ActOnBinOp performed the CorrectDelayedTyposInExpr 
check.
+        if (!getLangOpts().CPlusPlus)
+          continue;
       } else {
         LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
                                          LHS.get(), TernaryMiddle.get(),


Index: test/Sema/typo-correction.c
===================================================================
--- test/Sema/typo-correction.c
+++ test/Sema/typo-correction.c
@@ -57,3 +57,11 @@
 }
 
 int d = X ? d : L; // expected-error 2 {{use of undeclared identifier}}
+
+int fn_with_ids() { ID = ID == ID >= ID ; } // expected-error 4 {{use of undeclared identifier}}
+
+int fn_with_rs(int r) { r = TYPO + r * TYPO; } // expected-error 2 {{use of undeclared identifier}}
+
+void fn_with_unknown(int a, int b) {
+  fn_with_unknown(unknown, unknown | unknown); // expected-error 3 {{use of undeclared identifier}}
+}
Index: lib/Parse/ParseExpr.cpp
===================================================================
--- lib/Parse/ParseExpr.cpp
+++ lib/Parse/ParseExpr.cpp
@@ -446,6 +446,10 @@
 
         LHS = Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(),
                                  OpToken.getKind(), LHS.get(), RHS.get());
+
+        // In this case, ActOnBinOp performed the CorrectDelayedTyposInExpr check.
+        if (!getLangOpts().CPlusPlus)
+          continue;
       } else {
         LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc,
                                          LHS.get(), TernaryMiddle.get(),
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to