Bug 102786 - [c++20] virtual pmf sometimes rejected as not a constant
Summary: [c++20] virtual pmf sometimes rejected as not a constant
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 12.0
: P3 normal
Target Milestone: 9.5
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks: constexpr pmf, ptmf
  Show dependency treegraph
 
Reported: 2021-10-15 18:05 UTC by Jakub Jelinek
Modified: 2022-10-28 23:28 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work: 10.4.0, 12.1.0, 9.5.0
Known to fail:
Last reconfirmed: 2021-10-15 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2021-10-15 18:05:45 UTC
In the following testcase:

// { dg-do compile { target c++20 } }

struct S {
  virtual constexpr int foo () const { return 42; }
};

constexpr S s;
constexpr auto a = &S::foo;
constexpr auto b = (s.*a) ();
constexpr auto c = (s.*&S::foo) ();

we correctly accept b's initializer, but reject c's initializer with:
error: value ‘1’ of type ‘int (S::*)() const’ is not a constant expression
Comment 1 Andrew Pinski 2021-10-15 19:22:44 UTC
This might be a dup.
Comment 2 Andrew Pinski 2021-10-15 20:32:23 UTC
Confirmed.
Comment 3 GCC Commits 2021-10-19 07:25:44 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:f45610a45236e97616726ca042898d6ac46a082e

commit r12-4491-gf45610a45236e97616726ca042898d6ac46a082e
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Oct 19 09:24:57 2021 +0200

    c++: Don't reject calls through PMF during constant evaluation [PR102786]
    
    The following testcase incorrectly rejects the c initializer,
    while in the s.*a case cxx_eval_* sees .__pfn reads etc.,
    in the s.*&S::foo case get_member_function_from_ptrfunc creates
    expressions which use INTEGER_CSTs with type of pointer to METHOD_TYPE.
    And cxx_eval_constant_expression rejects any INTEGER_CSTs with pointer
    type if they aren't 0.
    Either we'd need to make sure we defer such folding till cp_fold but the
    function and pfn_from_ptrmemfunc is used from lots of places, or
    the following patch just tries to reject only non-zero INTEGER_CSTs
    with pointer types if they don't point to METHOD_TYPE in the hope that
    all such INTEGER_CSTs with POINTER_TYPE to METHOD_TYPE are result of
    folding valid pointer-to-member function expressions.
    I don't immediately see how one could create such INTEGER_CSTs otherwise,
    cast of integers to PMF is rejected and would have the PMF RECORD_TYPE
    anyway, etc.
    
    2021-10-19  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/102786
            * constexpr.c (cxx_eval_constant_expression): Don't reject
            INTEGER_CSTs with type POINTER_TYPE to METHOD_TYPE.
    
            * g++.dg/cpp2a/constexpr-virtual19.C: New test.
Comment 4 GCC Commits 2021-11-29 08:49:23 UTC
The releases/gcc-11 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:62e4f0e8977497e01d2c262a3bd459ab26a5aaca

commit r11-9326-g62e4f0e8977497e01d2c262a3bd459ab26a5aaca
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Oct 19 09:24:57 2021 +0200

    c++: Don't reject calls through PMF during constant evaluation [PR102786]
    
    The following testcase incorrectly rejects the c initializer,
    while in the s.*a case cxx_eval_* sees .__pfn reads etc.,
    in the s.*&S::foo case get_member_function_from_ptrfunc creates
    expressions which use INTEGER_CSTs with type of pointer to METHOD_TYPE.
    And cxx_eval_constant_expression rejects any INTEGER_CSTs with pointer
    type if they aren't 0.
    Either we'd need to make sure we defer such folding till cp_fold but the
    function and pfn_from_ptrmemfunc is used from lots of places, or
    the following patch just tries to reject only non-zero INTEGER_CSTs
    with pointer types if they don't point to METHOD_TYPE in the hope that
    all such INTEGER_CSTs with POINTER_TYPE to METHOD_TYPE are result of
    folding valid pointer-to-member function expressions.
    I don't immediately see how one could create such INTEGER_CSTs otherwise,
    cast of integers to PMF is rejected and would have the PMF RECORD_TYPE
    anyway, etc.
    
    2021-10-19  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/102786
            * constexpr.c (cxx_eval_constant_expression): Don't reject
            INTEGER_CSTs with type POINTER_TYPE to METHOD_TYPE.
    
            * g++.dg/cpp2a/constexpr-virtual19.C: New test.
    
    (cherry picked from commit f45610a45236e97616726ca042898d6ac46a082e)
Comment 5 Jakub Jelinek 2021-11-29 09:08:31 UTC
Fixed.
Comment 6 GCC Commits 2022-05-10 08:21:22 UTC
The releases/gcc-10 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:536b03642ad1a32100f71d414e6bd6dc54fc208a

commit r10-10650-g536b03642ad1a32100f71d414e6bd6dc54fc208a
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Oct 19 09:24:57 2021 +0200

    c++: Don't reject calls through PMF during constant evaluation [PR102786]
    
    The following testcase incorrectly rejects the c initializer,
    while in the s.*a case cxx_eval_* sees .__pfn reads etc.,
    in the s.*&S::foo case get_member_function_from_ptrfunc creates
    expressions which use INTEGER_CSTs with type of pointer to METHOD_TYPE.
    And cxx_eval_constant_expression rejects any INTEGER_CSTs with pointer
    type if they aren't 0.
    Either we'd need to make sure we defer such folding till cp_fold but the
    function and pfn_from_ptrmemfunc is used from lots of places, or
    the following patch just tries to reject only non-zero INTEGER_CSTs
    with pointer types if they don't point to METHOD_TYPE in the hope that
    all such INTEGER_CSTs with POINTER_TYPE to METHOD_TYPE are result of
    folding valid pointer-to-member function expressions.
    I don't immediately see how one could create such INTEGER_CSTs otherwise,
    cast of integers to PMF is rejected and would have the PMF RECORD_TYPE
    anyway, etc.
    
    2021-10-19  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/102786
            * constexpr.c (cxx_eval_constant_expression): Don't reject
            INTEGER_CSTs with type POINTER_TYPE to METHOD_TYPE.
    
            * g++.dg/cpp2a/constexpr-virtual19.C: New test.
    
    (cherry picked from commit f45610a45236e97616726ca042898d6ac46a082e)
Comment 7 GCC Commits 2022-05-11 06:22:53 UTC
The releases/gcc-9 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:662de049d63759b731bed62f9df60edb47120658

commit r9-10106-g662de049d63759b731bed62f9df60edb47120658
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Oct 19 09:24:57 2021 +0200

    c++: Don't reject calls through PMF during constant evaluation [PR102786]
    
    The following testcase incorrectly rejects the c initializer,
    while in the s.*a case cxx_eval_* sees .__pfn reads etc.,
    in the s.*&S::foo case get_member_function_from_ptrfunc creates
    expressions which use INTEGER_CSTs with type of pointer to METHOD_TYPE.
    And cxx_eval_constant_expression rejects any INTEGER_CSTs with pointer
    type if they aren't 0.
    Either we'd need to make sure we defer such folding till cp_fold but the
    function and pfn_from_ptrmemfunc is used from lots of places, or
    the following patch just tries to reject only non-zero INTEGER_CSTs
    with pointer types if they don't point to METHOD_TYPE in the hope that
    all such INTEGER_CSTs with POINTER_TYPE to METHOD_TYPE are result of
    folding valid pointer-to-member function expressions.
    I don't immediately see how one could create such INTEGER_CSTs otherwise,
    cast of integers to PMF is rejected and would have the PMF RECORD_TYPE
    anyway, etc.
    
    2021-10-19  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/102786
            * constexpr.c (cxx_eval_constant_expression): Don't reject
            INTEGER_CSTs with type POINTER_TYPE to METHOD_TYPE.
    
            * g++.dg/cpp2a/constexpr-virtual19.C: New test.
    
    (cherry picked from commit f45610a45236e97616726ca042898d6ac46a082e)