[clang] ec6c5e9 - [clang] Improve diagnostics for auto-return-type function if the return expr had an error.
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Mon Nov 30 00:19:28 PST 2020
Author: Haojian Wu
Date: 2020-11-30T09:19:15+01:00
New Revision: ec6c5e920a89db0e1c5f73b8349ee0b84192072d
URL: https://github.com/llvm/llvm-project/commit/ec6c5e920a89db0e1c5f73b8349ee0b84192072d
DIFF: https://github.com/llvm/llvm-project/commit/ec6c5e920a89db0e1c5f73b8349ee0b84192072d.diff
LOG: [clang] Improve diagnostics for auto-return-type function if the return expr had an error.
Given the following case:
```
auto k() {
return undef();
return 1;
}
```
Prior to the patch, clang emits an `cannot initialize return object of type
'auto' with an rvalue of type 'int'` diagnostic on the second return
(because the return type of the function cannot be deduced from the first contain-errors return).
This patch suppresses this error.
Differential Revision: https://reviews.llvm.org/D92211
Added:
Modified:
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
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 195121e1e256..f5bf889b3878 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -3327,9 +3327,14 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
}
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 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
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();
diff --git a/clang/test/SemaCXX/attr-target-mv.cpp b/clang/test/SemaCXX/attr-target-mv.cpp
index 11f3a276c7c7..5ef1d398d2d8 100644
--- a/clang/test/SemaCXX/attr-target-mv.cpp
+++ b/clang/test/SemaCXX/attr-target-mv.cpp
@@ -107,7 +107,6 @@ int __attribute__((target("arch=sandybridge")))
diff _mangle(void) { return 0; }
// expected-error at +1 {{multiversioned functions do not yet support deduced return types}}
auto __attribute__((target("default"))) deduced_return(void) { return 0; }
-// expected-error at -1 {{cannot initialize return object of type 'auto' with an rvalue of type 'int'}}
auto __attribute__((target("default"))) trailing_return(void)-> int { return 0; }
diff --git a/clang/test/SemaCXX/cxx1y-deduced-return-type.cpp b/clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
index 958728b10487..3e544c300884 100644
--- a/clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
+++ b/clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
@@ -22,7 +22,7 @@ int conv1d = conv1.operator int(); // expected-error {{no member named 'operator
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(int n) {
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 @@ namespace PR33222 {
};
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 at -1 {{cannot initialize}}
template<> int B<char[3]>::q() { return 0; } // expected-error {{return type}}
}
diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index 7f7f9c570487..22e0939379f5 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -521,6 +521,10 @@ void foo() {
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.
+ };
}
}
More information about the cfe-commits
mailing list