[PATCH] D20490: [Parser] Fix a crash on invalid where a delayed TypoExpr was corrected twice

Erik Pilkington via cfe-commits cfe-commits at lists.llvm.org
Fri May 20 14:02:36 PDT 2016


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(),


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D20490.57980.patch
Type: text/x-patch
Size: 1248 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160520/a06b2cef/attachment.bin>


More information about the cfe-commits mailing list