Quuxplusone updated this revision to Diff 406838. Quuxplusone added a comment.
Oops. I'd put `[clang] [test] Fix an apparent typo in SemaCXX/consteval-return-void.cpp` in a separate commit for hygiene purposes, and forgot to include that commit in this diff. Updated. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D119094/new/ https://reviews.llvm.org/D119094 Files: clang/lib/Sema/SemaStmt.cpp clang/test/SemaCXX/consteval-return-void.cpp clang/test/SemaCXX/deduced-return-void.cpp Index: clang/test/SemaCXX/deduced-return-void.cpp =================================================================== --- /dev/null +++ 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; +} Index: clang/test/SemaCXX/consteval-return-void.cpp =================================================================== --- clang/test/SemaCXX/consteval-return-void.cpp +++ clang/test/SemaCXX/consteval-return-void.cpp @@ -10,8 +10,8 @@ enum E {}; constexpr E operator+(E,E) { return; } // expected-error {{non-void constexpr function 'operator+' should return a value}} -consteval E operator+(E,E) { return; } // expected-error {{non-void consteval function 'operator+' should return a value}} -template <typename T> constexpr E operator-(E,E) { return; } // expected-error {{non-void constexpr function 'operator-' should return a value}} +consteval E operator-(E,E) { return; } // expected-error {{non-void consteval function 'operator-' should return a value}} +template <typename T> constexpr E operator+(E,E) { return; } // expected-error {{non-void constexpr function 'operator+' should return a value}} template <typename T> consteval E operator-(E,E) { return; } // expected-error {{non-void consteval function 'operator-' should return a value}} template <typename T> constexpr E operator*(E,E); Index: clang/lib/Sema/SemaStmt.cpp =================================================================== --- clang/lib/Sema/SemaStmt.cpp +++ clang/lib/Sema/SemaStmt.cpp @@ -4098,7 +4098,9 @@ } 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();
Index: clang/test/SemaCXX/deduced-return-void.cpp =================================================================== --- /dev/null +++ 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; +} Index: clang/test/SemaCXX/consteval-return-void.cpp =================================================================== --- clang/test/SemaCXX/consteval-return-void.cpp +++ clang/test/SemaCXX/consteval-return-void.cpp @@ -10,8 +10,8 @@ enum E {}; constexpr E operator+(E,E) { return; } // expected-error {{non-void constexpr function 'operator+' should return a value}} -consteval E operator+(E,E) { return; } // expected-error {{non-void consteval function 'operator+' should return a value}} -template <typename T> constexpr E operator-(E,E) { return; } // expected-error {{non-void constexpr function 'operator-' should return a value}} +consteval E operator-(E,E) { return; } // expected-error {{non-void consteval function 'operator-' should return a value}} +template <typename T> constexpr E operator+(E,E) { return; } // expected-error {{non-void constexpr function 'operator+' should return a value}} template <typename T> consteval E operator-(E,E) { return; } // expected-error {{non-void consteval function 'operator-' should return a value}} template <typename T> constexpr E operator*(E,E); Index: clang/lib/Sema/SemaStmt.cpp =================================================================== --- clang/lib/Sema/SemaStmt.cpp +++ clang/lib/Sema/SemaStmt.cpp @@ -4098,7 +4098,9 @@ } 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();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits