hokein updated this revision to Diff 307993.
hokein marked 2 inline comments as done.
hokein added a comment.

address comments and add the missing fix for C++14 `auto func`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D92211/new/

https://reviews.llvm.org/D92211

Files:
  clang/lib/Sema/SemaStmt.cpp
  clang/test/SemaCXX/attr-target-mv.cpp
  clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
  clang/test/SemaCXX/lambda-expressions.cpp


Index: clang/test/SemaCXX/lambda-expressions.cpp
===================================================================
--- clang/test/SemaCXX/lambda-expressions.cpp
+++ clang/test/SemaCXX/lambda-expressions.cpp
@@ -521,6 +521,10 @@
       return undeclared_error; // expected-error {{use of undeclared 
identifier}}
     return 0;
   };
+  auto bar = []() {
+    return undef(); // expected-error {{use of undeclared identifier}}
+    return 0; // verify no init_conversion_failed diagnostic emitted.
+  };
 }
 }
 
Index: clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
===================================================================
--- clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
+++ clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
@@ -22,7 +22,7 @@
 
 struct Conv2 {
   operator auto() { return 0; }  // expected-note {{previous}}
-  operator auto() { return 0.; } // expected-error {{cannot be redeclared}} 
expected-error {{cannot initialize return object of type 'auto' with an rvalue 
of type 'double'}}
+  operator auto() { return 0.; } // expected-error {{cannot be redeclared}}
 };
 
 struct Conv3 {
@@ -100,7 +100,7 @@
 auto fac_2(int n) { // expected-note {{declared here}}
   if (n > 2)
     return n * fac_2(n-1); // expected-error {{cannot be used before it is 
defined}}
-  return n; // expected-error {{cannot initialize return object of type 
'auto'}}
+  return n;
 }
 
 auto void_ret() {}
@@ -617,7 +617,6 @@
   };
   template<> auto *B<char[1]>::q() { return (int*)0; }
   template<> auto B<char[2]>::q() { return (int*)0; } // expected-error 
{{return type}}
-  // FIXME: suppress this follow-on error: expected-error@-1 {{cannot 
initialize}}
   template<> int B<char[3]>::q() { return 0; } // expected-error {{return 
type}}
 }
 
Index: clang/test/SemaCXX/attr-target-mv.cpp
===================================================================
--- clang/test/SemaCXX/attr-target-mv.cpp
+++ clang/test/SemaCXX/attr-target-mv.cpp
@@ -107,7 +107,6 @@
 
 // expected-error@+1 {{multiversioned functions do not yet support deduced 
return types}}
 auto __attribute__((target("default"))) deduced_return(void) { return 0; }
-// expected-error@-1 {{cannot initialize return object of type 'auto' with an 
rvalue of type 'int'}}
 
 auto __attribute__((target("default"))) trailing_return(void)-> int { return 
0; }
 
Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -3327,9 +3327,14 @@
   }
 
   if (HasDeducedReturnType) {
+    FunctionDecl *FD = CurLambda->CallOperator;
+    // If we've already decided this lambda is invalid, e.g. because
+    // we saw a `return` whose expression had an error, don't keep
+    // trying to deduce its return type.
+    if (FD->isInvalidDecl())
+      return StmtError();
     // In C++1y, the return type may involve 'auto'.
     // FIXME: Blocks might have a return type of 'auto' explicitly specified.
-    FunctionDecl *FD = CurLambda->CallOperator;
     if (CurCap->ReturnType.isNull())
       CurCap->ReturnType = FD->getReturnType();
 
@@ -3709,6 +3714,11 @@
   if (getLangOpts().CPlusPlus14) {
     if (AutoType *AT = FnRetType->getContainedAutoType()) {
       FunctionDecl *FD = cast<FunctionDecl>(CurContext);
+      // If we've already decided this function is invalid, e.g. because
+      // we saw a `return` whose expression had an error, don't keep
+      // trying to deduce its return type.
+      if (FD->isInvalidDecl())
+        return StmtError();
       if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) {
         FD->setInvalidDecl();
         return StmtError();


Index: clang/test/SemaCXX/lambda-expressions.cpp
===================================================================
--- clang/test/SemaCXX/lambda-expressions.cpp
+++ clang/test/SemaCXX/lambda-expressions.cpp
@@ -521,6 +521,10 @@
       return undeclared_error; // expected-error {{use of undeclared identifier}}
     return 0;
   };
+  auto bar = []() {
+    return undef(); // expected-error {{use of undeclared identifier}}
+    return 0; // verify no init_conversion_failed diagnostic emitted.
+  };
 }
 }
 
Index: clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
===================================================================
--- clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
+++ clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
@@ -22,7 +22,7 @@
 
 struct Conv2 {
   operator auto() { return 0; }  // expected-note {{previous}}
-  operator auto() { return 0.; } // expected-error {{cannot be redeclared}} expected-error {{cannot initialize return object of type 'auto' with an rvalue of type 'double'}}
+  operator auto() { return 0.; } // expected-error {{cannot be redeclared}}
 };
 
 struct Conv3 {
@@ -100,7 +100,7 @@
 auto fac_2(int n) { // expected-note {{declared here}}
   if (n > 2)
     return n * fac_2(n-1); // expected-error {{cannot be used before it is defined}}
-  return n; // expected-error {{cannot initialize return object of type 'auto'}}
+  return n;
 }
 
 auto void_ret() {}
@@ -617,7 +617,6 @@
   };
   template<> auto *B<char[1]>::q() { return (int*)0; }
   template<> auto B<char[2]>::q() { return (int*)0; } // expected-error {{return type}}
-  // FIXME: suppress this follow-on error: expected-error@-1 {{cannot initialize}}
   template<> int B<char[3]>::q() { return 0; } // expected-error {{return type}}
 }
 
Index: clang/test/SemaCXX/attr-target-mv.cpp
===================================================================
--- clang/test/SemaCXX/attr-target-mv.cpp
+++ clang/test/SemaCXX/attr-target-mv.cpp
@@ -107,7 +107,6 @@
 
 // expected-error@+1 {{multiversioned functions do not yet support deduced return types}}
 auto __attribute__((target("default"))) deduced_return(void) { return 0; }
-// expected-error@-1 {{cannot initialize return object of type 'auto' with an rvalue of type 'int'}}
 
 auto __attribute__((target("default"))) trailing_return(void)-> int { return 0; }
 
Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -3327,9 +3327,14 @@
   }
 
   if (HasDeducedReturnType) {
+    FunctionDecl *FD = CurLambda->CallOperator;
+    // If we've already decided this lambda is invalid, e.g. because
+    // we saw a `return` whose expression had an error, don't keep
+    // trying to deduce its return type.
+    if (FD->isInvalidDecl())
+      return StmtError();
     // In C++1y, the return type may involve 'auto'.
     // FIXME: Blocks might have a return type of 'auto' explicitly specified.
-    FunctionDecl *FD = CurLambda->CallOperator;
     if (CurCap->ReturnType.isNull())
       CurCap->ReturnType = FD->getReturnType();
 
@@ -3709,6 +3714,11 @@
   if (getLangOpts().CPlusPlus14) {
     if (AutoType *AT = FnRetType->getContainedAutoType()) {
       FunctionDecl *FD = cast<FunctionDecl>(CurContext);
+      // If we've already decided this function is invalid, e.g. because
+      // we saw a `return` whose expression had an error, don't keep
+      // trying to deduce its return type.
+      if (FD->isInvalidDecl())
+        return StmtError();
       if (DeduceFunctionTypeFromReturnExpr(FD, ReturnLoc, RetValExp, AT)) {
         FD->setInvalidDecl();
         return StmtError();
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to