PR18746: If a constexpr function has a dependent return type and no return
statements, don't diagnose; the return type might end up being 'void'. Patch by Rahul Jain! Tiny tweaks by me. llvm-svn: 206929
This commit is contained in:
parent
637cac42ed
commit
06ffb45ce4
|
@ -1175,10 +1175,12 @@ bool Sema::CheckConstexprFunctionBody(const FunctionDecl *Dcl, Stmt *Body) {
|
|||
} else {
|
||||
if (ReturnStmts.empty()) {
|
||||
// C++1y doesn't require constexpr functions to contain a 'return'
|
||||
// statement. We still do, unless the return type is void, because
|
||||
// statement. We still do, unless the return type might be void, because
|
||||
// otherwise if there's no return statement, the function cannot
|
||||
// be used in a core constant expression.
|
||||
bool OK = getLangOpts().CPlusPlus1y && Dcl->getReturnType()->isVoidType();
|
||||
bool OK = getLangOpts().CPlusPlus1y &&
|
||||
(Dcl->getReturnType()->isVoidType() ||
|
||||
Dcl->getReturnType()->isDependentType());
|
||||
Diag(Dcl->getLocation(),
|
||||
OK ? diag::warn_cxx11_compat_constexpr_body_no_return
|
||||
: diag::err_constexpr_body_no_return);
|
||||
|
|
|
@ -261,6 +261,13 @@ namespace DefaultedMethods {
|
|||
|
||||
namespace Constexpr {
|
||||
constexpr auto f1(int n) { return n; }
|
||||
template<typename T> struct X { constexpr auto f() {} }; // PR18746
|
||||
template<typename T> struct Y { constexpr T f() {} }; // expected-note {{control reached end of constexpr function}}
|
||||
void f() {
|
||||
X<int>().f();
|
||||
Y<void>().f();
|
||||
constexpr int q = Y<int>().f(); // expected-error {{must be initialized by a constant expression}} expected-note {{in call to '&Y<int>()->f()'}}
|
||||
}
|
||||
struct NonLiteral { ~NonLiteral(); } nl; // expected-note {{user-provided destructor}}
|
||||
constexpr auto f2(int n) { return nl; } // expected-error {{return type 'Constexpr::NonLiteral' is not a literal type}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue