diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 746eb82a5bdc7..6ccef38c2f61d 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -4098,7 +4098,9 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, } else if (!RetValExp && !HasDependentReturnType) { FunctionDecl *FD = getCurFunctionDecl(); - if (getLangOpts().CPlusPlus11 && FD && FD->isConstexpr()) { + if ((FD && FD->isInvalidDecl()) || FnRetType->containsErrors()) { + // The intended return type might have been "void", so don't warn. + } else if (getLangOpts().CPlusPlus11 && FD && FD->isConstexpr()) { // C++11 [stmt.return]p2 Diag(ReturnLoc, diag::err_constexpr_return_missing_expr) << FD << FD->isConsteval(); diff --git a/clang/test/SemaCXX/deduced-return-void.cpp b/clang/test/SemaCXX/deduced-return-void.cpp new file mode 100644 index 0000000000000..7b6c514eab71b --- /dev/null +++ b/clang/test/SemaCXX/deduced-return-void.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -std=c++14 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s + +// Check that we don't get any extra warning for "return" without an +// expression, in a function that might have been intended to return +// void all along. +auto f1() { + return 1; + return; // expected-error {{deduced as 'void' here but deduced as 'int' in earlier return statement}} +} + +decltype(auto) f2() { + return 1; + return; // expected-error {{deduced as 'void' here but deduced as 'int' in earlier return statement}} +} + +auto *g() { + return; // expected-error {{cannot deduce return type 'auto *' from omitted return expression}} +} + +decltype(h1) h1() { // expected-error {{use of undeclared identifier 'h1'}} + return; +}