[clang] 89ff9bf - [clang] Fix the warning for a non-void consteval function without a return value to actually say "consteval".

Bruno Ricci via cfe-commits cfe-commits at lists.llvm.org
Sun Jul 19 09:24:05 PDT 2020


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}}


        


More information about the cfe-commits mailing list