]> granicus.if.org Git - clang/commitdiff
Fix typo-correction crash if a typo occurs within the operand of a
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 30 Jun 2016 20:24:30 +0000 (20:24 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 30 Jun 2016 20:24:30 +0000 (20:24 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@274267 91177308-0d34-0410-b5e6-96231b3b80d8

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

index ea1de0c642818c55349bf58650231265b8aff9f0..2cd00f8218a675b18d8540405e4635a9f5588280 100644 (file)
@@ -1222,7 +1222,14 @@ Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep,
   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.
index e8621babaa883b9d599fc2b85ae58e96898e9295..c118522e8c47bb45d917b916b1f9888841c02d77 100644 (file)
@@ -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}}
index 8c1664516a710e6f33278471ae3a8b5720e40fb2..db289240d1ce642718efa211e7de1f3737fb4827 100644 (file)
@@ -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'}}
 }
index 6349937ccd9de1a7590e56faddc07d5bf017bf43..0b8383dbafef44c44e9483c5d941e92aaa84edaf 100644 (file)
@@ -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'}}