diff options
author | Marek Polacek <polacek@redhat.com> | 2023-03-03 11:24:24 -0500 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2023-03-07 09:51:52 -0500 |
commit | e09bc034d1b4d692b409fa5af52ae34480a6f4dc (patch) | |
tree | 08a42ccc44decc40190c46b600d0f6945694b872 /gcc/cp/constexpr.cc | |
parent | 247cacc9e381d666a492dfa4ed61b7b19e2d008f (diff) | |
download | gcc-e09bc034d1b4d692b409fa5af52ae34480a6f4dc.zip gcc-e09bc034d1b4d692b409fa5af52ae34480a6f4dc.tar.gz gcc-e09bc034d1b4d692b409fa5af52ae34480a6f4dc.tar.bz2 |
c++: error with constexpr operator() [PR107939]
Similarly to PR107938, this also started with r11-557, whereby cp_finish_decl
can call check_initializer even in a template for a constexpr initializer.
Here we are rejecting
extern const Q q;
template<int>
constexpr auto p = q(0);
even though q has a constexpr operator(). It's deemed non-const by
decl_maybe_constant_var_p because even though 'q' is const it is not
of integral/enum type.
If fun is not a function pointer, we don't know if we're using it as an
lvalue or rvalue, so with this patch we pass 'any' for want_rval. With
that, p_c_e/VAR_DECL doesn't flat out reject the underlying VAR_DECL.
PR c++/107939
gcc/cp/ChangeLog:
* constexpr.cc (potential_constant_expression_1) <case CALL_EXPR>: Pass
'any' when recursing on a VAR_DECL and not a pointer to function.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1y/var-templ74.C: Remove dg-error.
* g++.dg/cpp1y/var-templ77.C: New test.
Diffstat (limited to 'gcc/cp/constexpr.cc')
-rw-r--r-- | gcc/cp/constexpr.cc | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/gcc/cp/constexpr.cc b/gcc/cp/constexpr.cc index 364695b..3079561 100644 --- a/gcc/cp/constexpr.cc +++ b/gcc/cp/constexpr.cc @@ -9179,8 +9179,12 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now, } else if (fun) { - if (RECUR (fun, rval)) - /* Might end up being a constant function pointer. */; + if (RECUR (fun, FUNCTION_POINTER_TYPE_P (fun) ? rval : any)) + /* Might end up being a constant function pointer. But it + could also be a function object with constexpr op(), so + we pass 'any' so that the underlying VAR_DECL is deemed + as potentially-constant even though it wasn't declared + constexpr. */; else return false; } |