summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaDecl.cpp31
-rw-r--r--clang/lib/Sema/SemaStmt.cpp4
-rw-r--r--clang/test/SemaCXX/cxx1y-deduced-return-type.cpp5
3 files changed, 24 insertions, 16 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index a50b5e7c7ff..d14b10559d9 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -8849,7 +8849,9 @@ bool Sema::canSkipFunctionBody(Decl *D) {
// We cannot skip the body of a function (or function template) which is
// constexpr, since we may need to evaluate its body in order to parse the
// rest of the file.
- return !FD->isConstexpr();
+ // We cannot skip the body of a function with an undeduced return type,
+ // because any callers of that function need to know the type.
+ return !FD->isConstexpr() && !FD->getResultType()->isUndeducedType();
}
Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) {
@@ -8879,18 +8881,21 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
if (FD) {
FD->setBody(Body);
- if (getLangOpts().CPlusPlus1y && !FD->isInvalidDecl() &&
- !FD->isDependentContext()) {
- if (FD->getResultType()->isUndeducedType()) {
- // If the function has a deduced result type but contains no 'return'
- // statements, the result type as written must be exactly 'auto', and
- // the deduced result type is 'void'.
- if (!FD->getResultType()->getAs<AutoType>()) {
- Diag(dcl->getLocation(), diag::err_auto_fn_no_return_but_not_auto)
- << FD->getResultType();
- FD->setInvalidDecl();
- }
- Context.adjustDeducedFunctionResultType(FD, Context.VoidTy);
+ if (getLangOpts().CPlusPlus1y && !FD->isInvalidDecl() && Body &&
+ !FD->isDependentContext() && FD->getResultType()->isUndeducedType()) {
+ // If the function has a deduced result type but contains no 'return'
+ // statements, the result type as written must be exactly 'auto', and
+ // the deduced result type is 'void'.
+ if (!FD->getResultType()->getAs<AutoType>()) {
+ Diag(dcl->getLocation(), diag::err_auto_fn_no_return_but_not_auto)
+ << FD->getResultType();
+ FD->setInvalidDecl();
+ } else {
+ // Substitute 'void' for the 'auto' in the type.
+ TypeLoc ResultType = FD->getTypeSourceInfo()->getTypeLoc().
+ IgnoreParens().castAs<FunctionProtoTypeLoc>().getResultLoc();
+ Context.adjustDeducedFunctionResultType(
+ FD, SubstAutoType(ResultType.getType(), Context.VoidTy));
}
}
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 248665ac86c..b5ff7a30a9e 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -2553,9 +2553,7 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
if (RetValExp && DiagnoseUnexpandedParameterPack(RetValExp))
return StmtError();
- // FIXME: Unify this and C++1y auto function handling. In particular, we
- // should allow 'return { 1, 2, 3 };' in a lambda to deduce
- // 'std::initializer_list<int>'.
+ // FIXME: Unify this and C++1y auto function handling.
if (isa<CapturingScopeInfo>(getCurFunction()))
return ActOnCapScopeReturnStmt(ReturnLoc, RetValExp);
diff --git a/clang/test/SemaCXX/cxx1y-deduced-return-type.cpp b/clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
index f0146f88d68..eb6f6aaf9bc 100644
--- a/clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
+++ b/clang/test/SemaCXX/cxx1y-deduced-return-type.cpp
@@ -295,7 +295,12 @@ namespace NoReturn {
auto f() {}
void (*p)() = &f;
+ auto f(); // ok
+
auto *g() {} // expected-error {{cannot deduce return type 'auto *' for function with no return statements}}
+
+ auto h() = delete; // expected-note {{explicitly deleted}}
+ auto x = h(); // expected-error {{call to deleted}}
}
namespace UseBeforeComplete {
OpenPOWER on IntegriCloud