Author: Bruno Ricci Date: 2020-07-19T17:08:17+01:00 New Revision: 89ff9bf061b4985d11cd4785958d8f8156d10f5d
URL: https://github.com/llvm/llvm-project/commit/89ff9bf061b4985d11cd4785958d8f8156d10f5d DIFF: https://github.com/llvm/llvm-project/commit/89ff9bf061b4985d11cd4785958d8f8156d10f5d.diff LOG: [clang] Fix the warning for a non-void consteval function without a return value to actually say "consteval". This warning was modified in 796ed03b8412 to use the term "consteval" for consteval functions. However the warning has never worked as intended since the diagnostic's arguments are used in the wrong order. This was unfortunately missed by 796ed03b8412 since no test did exercise this specific warning. Additionally send the NamedDecl* into the diagnostic instead of just the IdentifierInfo* to correctly work with special names and template arguments. Added: Modified: clang/lib/Sema/SemaStmt.cpp clang/test/SemaCXX/constant-expression-cxx11.cpp clang/test/SemaCXX/consteval-return-void.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 73f3183c163f..948c187804dc 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -3766,25 +3766,26 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } else if (!RetValExp && !HasDependentReturnType) { FunctionDecl *FD = getCurFunctionDecl(); - unsigned DiagID; if (getLangOpts().CPlusPlus11 && FD && FD->isConstexpr()) { // C++11 [stmt.return]p2 - DiagID = diag::err_constexpr_return_missing_expr; + Diag(ReturnLoc, diag::err_constexpr_return_missing_expr) + << FD << FD->isConsteval(); FD->setInvalidDecl(); - } else if (getLangOpts().C99) { - // C99 6.8.6.4p1 (ext_ since GCC warns) - DiagID = diag::ext_return_missing_expr; } else { + // C99 6.8.6.4p1 (ext_ since GCC warns) // C90 6.6.6.4p4 - DiagID = diag::warn_return_missing_expr; + unsigned DiagID = getLangOpts().C99 ? diag::ext_return_missing_expr + : diag::warn_return_missing_expr; + // Note that at this point one of getCurFunctionDecl() or + // getCurMethodDecl() must be non-null (see above). + assert((getCurFunctionDecl() || getCurMethodDecl()) && + "Not in a FunctionDecl or ObjCMethodDecl?"); + bool IsMethod = FD == nullptr; + const NamedDecl *ND = + IsMethod ? cast<NamedDecl>(getCurMethodDecl()) : cast<NamedDecl>(FD); + Diag(ReturnLoc, DiagID) << ND << IsMethod; } - if (FD) - Diag(ReturnLoc, DiagID) - << FD->getIdentifier() << 0 /*fn*/ << FD->isConsteval(); - else - Diag(ReturnLoc, DiagID) << getCurMethodDecl()->getDeclName() << 1/*meth*/; - Result = ReturnStmt::Create(Context, ReturnLoc, /* RetExpr=*/nullptr, /* NRVOCandidate=*/nullptr); } else { diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp index 7ff260c37c69..eac0256c4fb2 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -2171,7 +2171,7 @@ namespace PR21859 { template <typename T> constexpr int FunT1() { return; } // expected-error {{non-void constexpr function 'FunT1' should return a value}} template <typename T> constexpr int FunT2() { return 0; } template <> constexpr int FunT2<double>() { return 0; } - template <> constexpr int FunT2<int>() { return; } // expected-error {{non-void constexpr function 'FunT2' should return a value}} + template <> constexpr int FunT2<int>() { return; } // expected-error {{non-void constexpr function 'FunT2<int>' should return a value}} } struct InvalidRedef { diff --git a/clang/test/SemaCXX/consteval-return-void.cpp b/clang/test/SemaCXX/consteval-return-void.cpp index a5207f41bf2c..39e1418306f5 100644 --- a/clang/test/SemaCXX/consteval-return-void.cpp +++ b/clang/test/SemaCXX/consteval-return-void.cpp @@ -1,10 +1,20 @@ // RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s -consteval int Fun() { return; } // expected-error {{non-void constexpr function 'Fun' should return a value}} +consteval int Fun() { return; } // expected-error {{non-void consteval function 'Fun' should return a value}} -// FIXME: The diagnostic is wrong; should be "consteval". - -template <typename T> consteval int FunT1() { return; } // expected-error {{non-void constexpr function 'FunT1' should return a value}} +template <typename T> consteval int FunT1() { return; } // expected-error {{non-void consteval function 'FunT1' should return a value}} template <typename T> consteval int FunT2() { return 0; } template <> consteval int FunT2<double>() { return 0; } -template <> consteval int FunT2<int>() { return; } // expected-error {{non-void constexpr function 'FunT2' should return a value}} +template <> consteval int FunT2<int>() { return; } // expected-error {{non-void consteval function 'FunT2<int>' should return a value}} + +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}} +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); +template <typename T> consteval E operator/(E,E); +template <> constexpr E operator*<int>(E,E) { return; } // expected-error {{non-void constexpr function 'operator*<int>' should return a value}} +template <> consteval E operator/<int>(E,E) { return; } // expected-error {{non-void consteval function 'operator/<int>' should return a value}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits