Bug 100752 - [11 Regression] error: cannot call member function ‘void S::f()’ without object
Summary: [11 Regression] error: cannot call member function ‘void S::f()’ without object
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 11.1.1
: P2 normal
Target Milestone: 11.2
Assignee: Marek Polacek
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2021-05-25 09:01 UTC by Jonathan Wakely
Modified: 2022-02-01 19:09 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work: 10.3.0
Known to fail: 11.1.0, 12.0
Last reconfirmed: 2021-05-26 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan Wakely 2021-05-25 09:01:37 UTC
As noted in Bug 52869 comment 20, this has started to fail:

struct S
{
    void f() noexcept {}
    S &g() noexcept(noexcept(f())) { f(); return *this; }
};

noex.C:4:32: error: cannot call member function ‘void S::f()’ without object
    4 |     S &g() noexcept(noexcept(f())) { f(); return *this; }
      |                                ^


It started with r11-289:

     c++: Use of 'this' in parameter declaration [PR90748]
    
    We were incorrectly accepting the use of 'this' at parse time and then
    crashing when we tried to instantiate it.  It is invalid because 'this' is
    not in scope until after the function-cv-quals.  So let's hoist setting
    current_class_ptr up from cp_parser_late_return_type_opt into
    cp_parser_direct_declarator where it can work for noexcept as well.
    
    
            PR c++/90748
            * parser.c (inject_parm_decls): Set current_class_ptr here.
            (cp_parser_direct_declarator): And here.
            (cp_parser_late_return_type_opt): Not here.
            (cp_parser_noexcept_specification_opt): Nor here.
            (cp_parser_exception_specification_opt)
            (cp_parser_late_noexcept_specifier): Remove unneeded parameters.
Comment 1 Jason Merrill 2021-05-26 19:35:37 UTC
This is happening because we aren't deferring the parse of this noexcept the way we're supposed to.  Marek?
Comment 2 Marek Polacek 2021-05-26 19:40:27 UTC
Mine then.
Comment 3 Marek Polacek 2021-06-08 21:10:55 UTC
Duh, we don't defer parsing of noexcept for any ptr-operator, like

struct S {
  int& f() noexcept(noexcept(i));
  int i;
};

Awkward, but the fix should be simple.
Comment 4 Jason Merrill 2021-06-08 21:12:18 UTC
As I mentioned on IRC, it seems like this may just be a matter of properly passing down flags/member_p in the recursive call to cp_parser_declarator.
Comment 5 GCC Commits 2021-06-26 00:12:20 UTC
The master branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>:

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

commit r12-1822-gf9c80eb12c58126a94ad869380af5b88b752c06f
Author: Marek Polacek <polacek@redhat.com>
Date:   Tue Jun 8 17:44:13 2021 -0400

    c++: Failure to delay noexcept parsing with ptr-operator [PR100752]
    
    We weren't passing 'flags' to the recursive call to cp_parser_declarator
    in the ptr-operator case and as an effect, delayed parsing of noexcept
    didn't work as advertised.  The following change passes more than just
    CP_PARSER_FLAGS_DELAY_NOEXCEPT but that doesn't seem to break anything.
    
    I'm now also passing member_p and static_p, as a consequence, two tests
    needed small tweaks.
    
            PR c++/100752
    
    gcc/cp/ChangeLog:
    
            * parser.c (cp_parser_declarator): Pass flags down to
            cp_parser_declarator.  Also pass static_p/member_p.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp0x/noexcept69.C: New test.
            * g++.dg/parse/saved1.C: Adjust dg-error.
            * g++.dg/template/crash50.C: Likewise.
Comment 6 Marek Polacek 2021-06-26 00:12:49 UTC
Fixed on trunk so far.
Comment 7 GCC Commits 2021-06-29 13:18:50 UTC
The releases/gcc-11 branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>:

https://gcc.gnu.org/g:2cf8d3fc05737684a16fa080b0c0d24048da782b

commit r11-8662-g2cf8d3fc05737684a16fa080b0c0d24048da782b
Author: Marek Polacek <polacek@redhat.com>
Date:   Tue Jun 8 17:44:13 2021 -0400

    c++: Failure to delay noexcept parsing with ptr-operator [PR100752]
    
    We weren't passing 'flags' to the recursive call to cp_parser_declarator
    in the ptr-operator case and as an effect, delayed parsing of noexcept
    didn't work as advertised.  The following change passes more than just
    CP_PARSER_FLAGS_DELAY_NOEXCEPT but that doesn't seem to break anything.
    
    I'm now also passing member_p and static_p, as a consequence, two tests
    needed small tweaks.
    
            PR c++/100752
    
    gcc/cp/ChangeLog:
    
            * parser.c (cp_parser_declarator): Pass flags down to
            cp_parser_declarator.  Also pass static_p/member_p.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp0x/noexcept69.C: New test.
            * g++.dg/parse/saved1.C: Adjust dg-error.
            * g++.dg/template/crash50.C: Likewise.
    
    (cherry picked from commit f9c80eb12c58126a94ad869380af5b88b752c06f)
Comment 8 Marek Polacek 2021-06-29 13:19:06 UTC
Fixed.