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.
} 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 {
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 {
// 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}}