sammccall created this revision.
sammccall added a reviewer: rsmith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

e.g.

  auto foo() {
    return no_such_thing; // Return value is a TypoExpr
  }
  using T = decltype(foo()); // Uh-oh, undeduced auto.


Repository:
  rC Clang

https://reviews.llvm.org/D61649

Files:
  lib/Sema/SemaStmt.cpp
  test/SemaCXX/typo-correction-crash.cpp


Index: test/SemaCXX/typo-correction-crash.cpp
===================================================================
--- test/SemaCXX/typo-correction-crash.cpp
+++ test/SemaCXX/typo-correction-crash.cpp
@@ -4,12 +4,23 @@
   return s; // expected-error {{use of undeclared identifier 's'}}
 }
 
-int test = 11; // expected-note {{'test' declared here}}
+int test = 11; // expected-note 2 {{'test' declared here}}
 auto check2() {
   return "s";
   return tes; // expected-error {{use of undeclared identifier 'tes'; did you 
mean 'test'?}}
+              // expected-error@-1 {{deduced as 'int' here but deduced as 
'const char *' in earlier}}
 }
 
+template <class A, class B> struct is_same { static constexpr bool value = 
false; };
+template <class A> struct is_same<A,A> { static constexpr bool value = true; };
+
+auto L1 = [] { return s; }; // expected-error {{use of undeclared identifier 
's'}}
+using T1 = decltype(L1());
+static_assert(is_same<T1, void>::value, "Return statement should be 
discarded");
+auto L2 = [] { return tes; }; // expected-error {{use of undeclared identifier 
'tes'; did you mean 'test'?}}
+using T2 = decltype(L2());
+static_assert(is_same<T2, int>::value, "Return statement was corrected");
+
 namespace BarNamespace {
 namespace NestedNamespace { // expected-note {{'BarNamespace::NestedNamespace' 
declared here}}
 typedef int type;
Index: lib/Sema/SemaStmt.cpp
===================================================================
--- lib/Sema/SemaStmt.cpp
+++ lib/Sema/SemaStmt.cpp
@@ -10,6 +10,7 @@
 //
 
//===----------------------------------------------------------------------===//
 
+#include "clang/Sema/Ownership.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDiagnostic.h"
@@ -3503,7 +3504,12 @@
 StmtResult
 Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
                       Scope *CurScope) {
-  StmtResult R = BuildReturnStmt(ReturnLoc, RetValExp);
+  // Correct typos, in case the containing function returns 'auto' and
+  // RetValExp should determine the deduced type.
+  ExprResult RetVal = CorrectDelayedTyposInExpr(RetValExp);
+  if (RetVal.isInvalid())
+    return StmtError();
+  StmtResult R = BuildReturnStmt(ReturnLoc, RetVal.get());
   if (R.isInvalid() || ExprEvalContexts.back().Context ==
                            ExpressionEvaluationContext::DiscardedStatement)
     return R;


Index: test/SemaCXX/typo-correction-crash.cpp
===================================================================
--- test/SemaCXX/typo-correction-crash.cpp
+++ test/SemaCXX/typo-correction-crash.cpp
@@ -4,12 +4,23 @@
   return s; // expected-error {{use of undeclared identifier 's'}}
 }
 
-int test = 11; // expected-note {{'test' declared here}}
+int test = 11; // expected-note 2 {{'test' declared here}}
 auto check2() {
   return "s";
   return tes; // expected-error {{use of undeclared identifier 'tes'; did you mean 'test'?}}
+              // expected-error@-1 {{deduced as 'int' here but deduced as 'const char *' in earlier}}
 }
 
+template <class A, class B> struct is_same { static constexpr bool value = false; };
+template <class A> struct is_same<A,A> { static constexpr bool value = true; };
+
+auto L1 = [] { return s; }; // expected-error {{use of undeclared identifier 's'}}
+using T1 = decltype(L1());
+static_assert(is_same<T1, void>::value, "Return statement should be discarded");
+auto L2 = [] { return tes; }; // expected-error {{use of undeclared identifier 'tes'; did you mean 'test'?}}
+using T2 = decltype(L2());
+static_assert(is_same<T2, int>::value, "Return statement was corrected");
+
 namespace BarNamespace {
 namespace NestedNamespace { // expected-note {{'BarNamespace::NestedNamespace' declared here}}
 typedef int type;
Index: lib/Sema/SemaStmt.cpp
===================================================================
--- lib/Sema/SemaStmt.cpp
+++ lib/Sema/SemaStmt.cpp
@@ -10,6 +10,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/Sema/Ownership.h"
 #include "clang/Sema/SemaInternal.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDiagnostic.h"
@@ -3503,7 +3504,12 @@
 StmtResult
 Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
                       Scope *CurScope) {
-  StmtResult R = BuildReturnStmt(ReturnLoc, RetValExp);
+  // Correct typos, in case the containing function returns 'auto' and
+  // RetValExp should determine the deduced type.
+  ExprResult RetVal = CorrectDelayedTyposInExpr(RetValExp);
+  if (RetVal.isInvalid())
+    return StmtError();
+  StmtResult R = BuildReturnStmt(ReturnLoc, RetVal.get());
   if (R.isInvalid() || ExprEvalContexts.back().Context ==
                            ExpressionEvaluationContext::DiscardedStatement)
     return R;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D61649: [Sema] Correct ... Sam McCall via Phabricator via cfe-commits

Reply via email to