r274267 - Fix typo-correction crash if a typo occurs within the operand of a

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 30 13:24:30 PDT 2016


Author: rsmith
Date: Thu Jun 30 15:24:30 2016
New Revision: 274267

URL: http://llvm.org/viewvc/llvm-project?rev=274267&view=rev
Log:
Fix typo-correction crash if a typo occurs within the operand of a
function-style cast to a non-dependent type which is then used in an invalid
way. We'd lose the "type dependent" bit here, and downstream Sema processing
would then discard the expression if it was used in a context where its type
rendered it invalid.

Modified:
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/Parser/cxx1z-init-statement.cpp
    cfe/trunk/test/SemaCXX/return.cpp
    cfe/trunk/test/SemaCXX/typo-correction-crash.cpp

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=274267&r1=274266&r2=274267&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Jun 30 15:24:30 2016
@@ -1222,7 +1222,14 @@ Sema::ActOnCXXTypeConstructExpr(ParsedTy
   if (!TInfo)
     TInfo = Context.getTrivialTypeSourceInfo(Ty, SourceLocation());
 
-  return BuildCXXTypeConstructExpr(TInfo, LParenLoc, exprs, RParenLoc);
+  auto Result = BuildCXXTypeConstructExpr(TInfo, LParenLoc, exprs, RParenLoc);
+  // Avoid creating a non-type-dependent expression that contains typos.
+  // Non-type-dependent expressions are liable to be discarded without
+  // checking for embedded typos.
+  if (!Result.isInvalid() && Result.get()->isInstantiationDependent() &&
+      !Result.get()->isTypeDependent())
+    Result = CorrectDelayedTyposInExpr(Result.get());
+  return Result;
 }
 
 /// ActOnCXXTypeConstructExpr - Parse construction of a specified type.

Modified: cfe/trunk/test/Parser/cxx1z-init-statement.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx1z-init-statement.cpp?rev=274267&r1=274266&r2=274267&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx1z-init-statement.cpp (original)
+++ cfe/trunk/test/Parser/cxx1z-init-statement.cpp Thu Jun 30 15:24:30 2016
@@ -10,6 +10,7 @@ int f() {
   if (T(f()), g, h; f()) {} // expected-error {{not yet supported}}
   if (T f(); f()) {} // expected-error {{not yet supported}}
   if (T f(), g, h; f()) {} // expected-error {{not yet supported}}
+  if (T(n) = 0; n) {} // expected-error {{not yet supported}}
 
   // init-statement expressions
   if (T{f()}; f()) {} // expected-error {{not yet supported}}
@@ -20,6 +21,7 @@ int f() {
   if (T(n){g}) {}
   if (T f()) {} // expected-error {{function type}}
   if (T f(), g, h) {} // expected-error {{function type}}
+  if (T(n) = 0) {}
 
   // condition expressions
   if (T(f())) {}
@@ -27,9 +29,9 @@ int f() {
   if (T(f()), g, h) {} // expected-warning 2{{unused}}
   if (T{f()}, g, h) {} // expected-warning 2{{unused}}
 
-  // none of the above
-  // FIXME: This causes a typo-correction crash, as does "void f() { +T(n)(g); }"
-  //if (T(n)(g)) {} // expected-err-FIXME {{not a function}}
+  // none of the above, disambiguated as expression (can't be a declaration)
+  if (T(n)(g)) {} // expected-error {{undeclared identifier 'n'}}
+  if (T(n)(int())) {} // expected-error {{undeclared identifier 'n'}}
 
   // Likewise for 'switch'
   switch (int n; n) {} // expected-error {{not yet supported}}

Modified: cfe/trunk/test/SemaCXX/return.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/return.cpp?rev=274267&r1=274266&r2=274267&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/return.cpp (original)
+++ cfe/trunk/test/SemaCXX/return.cpp Thu Jun 30 15:24:30 2016
@@ -118,5 +118,5 @@ void cxx_unresolved_expr() {
   // CXXUnresolvedConstructExpr, and the missing ')' gives it an invalid source
   // location for its rparen.  Check that emitting a diag on the range of the
   // expr doesn't assert.
-  return int(undeclared, 4; // expected-error {{expected ')'}} expected-note{{to match this '('}} expected-error {{void function 'cxx_unresolved_expr' should not return a value}} expected-error {{use of undeclared identifier 'undeclared'}}
+  return int(undeclared, 4; // expected-error {{expected ')'}} expected-note{{to match this '('}} expected-error {{use of undeclared identifier 'undeclared'}}
 }

Modified: cfe/trunk/test/SemaCXX/typo-correction-crash.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/typo-correction-crash.cpp?rev=274267&r1=274266&r2=274267&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/typo-correction-crash.cpp (original)
+++ cfe/trunk/test/SemaCXX/typo-correction-crash.cpp Thu Jun 30 15:24:30 2016
@@ -17,3 +17,5 @@ typedef int type;
 }
 struct FooRecord { };
 FooRecord::NestedNamespace::type x; // expected-error {{no member named 'NestedNamespace' in 'FooRecord'; did you mean 'BarNamespace::NestedNamespace'?}}
+
+void cast_expr(int g) { +int(n)(g); } // expected-error {{undeclared identifier 'n'}}




More information about the cfe-commits mailing list