c++: Don't reject pointer to virtual method during constant evaluation [PR117615]
We currently reject the following valid code: === cut here === struct Base { virtual void doit (int v) const {} }; struct Derived : Base { void doit (int v) const {} }; using fn_t = void (Base::*)(int) const; struct Helper { fn_t mFn; constexpr Helper (auto && fn) : mFn(static_cast<fn_t>(fn)) {} }; void foo () { constexpr Helper h (&Derived::doit); } === cut here === The problem is that since r6-4014-gdcdbc004d531b4, &Derived::doit is represented with an expression with type pointer to method and using an INTEGER_CST (here 1), and that cxx_eval_constant_expression rejects any such expression with a non-null INTEGER_CST. This patch uses the same strategy as r12-4491-gf45610a45236e9 (fix for PR c++/102786), and simply lets such expressions go through. PR c++/117615 gcc/cp/ChangeLog: * constexpr.cc (cxx_eval_constant_expression): Don't reject INTEGER_CSTs with type POINTER_TYPE to METHOD_TYPE. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/constexpr-virtual22.C: New test.
This commit is contained in:
parent
2055919192
commit
72a2380a30
2 changed files with 28 additions and 0 deletions
|
@ -8275,6 +8275,12 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
|
|||
return t;
|
||||
}
|
||||
}
|
||||
else if (TYPE_PTR_P (type)
|
||||
&& TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
|
||||
/* INTEGER_CST with pointer-to-method type is only used
|
||||
for a virtual method in a pointer to member function.
|
||||
Don't reject those. */
|
||||
;
|
||||
else
|
||||
{
|
||||
/* This detects for example:
|
||||
|
|
22
gcc/testsuite/g++.dg/cpp2a/constexpr-virtual22.C
Normal file
22
gcc/testsuite/g++.dg/cpp2a/constexpr-virtual22.C
Normal file
|
@ -0,0 +1,22 @@
|
|||
// PR c++/117615
|
||||
// { dg-do "compile" { target c++20 } }
|
||||
|
||||
struct Base {
|
||||
virtual void doit (int v) const {}
|
||||
};
|
||||
|
||||
struct Derived : Base {
|
||||
void doit (int v) const {}
|
||||
};
|
||||
|
||||
using fn_t = void (Base::*)(int) const;
|
||||
|
||||
struct Helper {
|
||||
fn_t mFn;
|
||||
constexpr Helper (auto && fn) : mFn(static_cast<fn_t>(fn)) {}
|
||||
};
|
||||
|
||||
void foo () {
|
||||
constexpr Helper h (&Derived::doit);
|
||||
constexpr Helper h2 (&Base::doit);
|
||||
}
|
Loading…
Add table
Reference in a new issue