From: Bruno Ricci Date: Sun, 19 Jul 2020 16:08:17 +0000 (+0100) Subject: [clang] Fix the warning for a non-void consteval function without a return value... X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=89ff9bf061b4985d11cd4785958d8f8156d10f5d;p=platform%2Fupstream%2Fllvm.git [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. --- diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 73f3183..948c187 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(getCurMethodDecl()) : cast(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 7ff260c..eac0256 100644 --- a/clang/test/SemaCXX/constant-expression-cxx11.cpp +++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp @@ -2171,7 +2171,7 @@ namespace PR21859 { template constexpr int FunT1() { return; } // expected-error {{non-void constexpr function 'FunT1' should return a value}} template constexpr int FunT2() { return 0; } template <> constexpr int FunT2() { return 0; } - template <> constexpr int FunT2() { return; } // expected-error {{non-void constexpr function 'FunT2' should return a value}} + template <> constexpr int FunT2() { return; } // expected-error {{non-void constexpr function 'FunT2' 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 a5207f4..39e1418 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 consteval int FunT1() { return; } // expected-error {{non-void constexpr function 'FunT1' should return a value}} +template consteval int FunT1() { return; } // expected-error {{non-void consteval function 'FunT1' should return a value}} template consteval int FunT2() { return 0; } template <> consteval int FunT2() { return 0; } -template <> consteval int FunT2() { return; } // expected-error {{non-void constexpr function 'FunT2' should return a value}} +template <> consteval int FunT2() { return; } // expected-error {{non-void consteval function 'FunT2' 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 constexpr E operator-(E,E) { return; } // expected-error {{non-void constexpr function 'operator-' should return a value}} +template consteval E operator-(E,E) { return; } // expected-error {{non-void consteval function 'operator-' should return a value}} + +template constexpr E operator*(E,E); +template consteval E operator/(E,E); +template <> constexpr E operator*(E,E) { return; } // expected-error {{non-void constexpr function 'operator*' should return a value}} +template <> consteval E operator/(E,E) { return; } // expected-error {{non-void consteval function 'operator/' should return a value}}