https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65880
Bug ID: 65880 Summary: Member function issue with argument "pointer to const array of member function pointers" Product: gcc Version: 5.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: habanero_pizza at yahoo dot com CC: habanero_pizza at yahoo dot com Host: i686-pc-linux-gnu Target: i686-pc-linux-gnu Build: i686-pc-linux-gnu Created attachment 35396 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35396&action=edit Test case source: fails if OKAY is not defined... When a member function takes an argument of the form: type (classname::* const *ptr)(void) AND the implementation of the function appears BEFORE its reference by another member function, the compiler believes (at reference time) that the argument type should be: type (classname::* *ptr)(void) That is, the "const" seems to get dropped from the declaration. However, if the implementation of the function appears AFTER references by other member functions, the code compiles correctly. This seems to be a new issue with gcc 5.1.0, as 4.9.2 compiles the problem case properly. Example run demonstrating the problem: $ i386-eabi-g++ -v -save-temps -o test-const-mfp-table-arg test-const-mfp-table-arg.cc Using built-in specs. COLLECT_GCC=i386-eabi-g++ COLLECT_LTO_WRAPPER=/usr/local/i386-eabi-5.1.0/libexec/gcc/i686-pc-linux-gnu/5.1 .0/lto-wrapper Target: i686-pc-linux-gnu Configured with: ../../gcc-5.1.0/configure --prefix=/usr/local/i386-eabi-5.1.0 - -program-prefix=i386-eabi- --enable-languages=c,c++ --with-gmp=/usr/local/i386-e abi-5.1.0 --with-mpfr=/usr/local/i386-eabi-5.1.0 --with-mpc=/usr/local/i386-eabi -5.1.0 --with-isl=/usr/local/i386-eabi-5.1.0 --with-zlib=/usr/local --enable-lto --enable-gold Thread model: posix gcc version 5.1.0 (GCC) COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test-const-mfp-table-arg' '-shared- libgcc' '-mtune=generic' '-march=pentiumpro' /usr/local/i386-eabi-5.1.0/libexec/gcc/i686-pc-linux-gnu/5.1.0/cc1plus -E -quie t -v -D_GNU_SOURCE test-const-mfp-table-arg.cc -mtune=generic -march=pentiumpro -fpch-preprocess -o test-const-mfp-table-arg.ii ignoring nonexistent directory "/usr/local/i386-eabi-5.1.0/lib/gcc/i686-pc-linux -gnu/5.1.0/../../../../i686-pc-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/local/i386-eabi-5.1.0/lib/gcc/i686-pc-linux-gnu/5.1.0/../../../../include/ c++/5.1.0 /usr/local/i386-eabi-5.1.0/lib/gcc/i686-pc-linux-gnu/5.1.0/../../../../include/ c++/5.1.0/i686-pc-linux-gnu /usr/local/i386-eabi-5.1.0/lib/gcc/i686-pc-linux-gnu/5.1.0/../../../../include/ c++/5.1.0/backward /usr/local/i386-eabi-5.1.0/lib/gcc/i686-pc-linux-gnu/5.1.0/include /usr/local/include /usr/local/i386-eabi-5.1.0/include /usr/local/i386-eabi-5.1.0/lib/gcc/i686-pc-linux-gnu/5.1.0/include-fixed /usr/include End of search list. COLLECT_GCC_OPTIONS='-v' '-save-temps' '-o' 'test-const-mfp-table-arg' '-shared- libgcc' '-mtune=generic' '-march=pentiumpro' /usr/local/i386-eabi-5.1.0/libexec/gcc/i686-pc-linux-gnu/5.1.0/cc1plus -fprepro cessed test-const-mfp-table-arg.ii -quiet -dumpbase test-const-mfp-table-arg.cc -mtune=generic -march=pentiumpro -auxbase test-const-mfp-table-arg -version -o t est-const-mfp-table-arg.s GNU C++ (GCC) version 5.1.0 (i686-pc-linux-gnu) compiled by GNU C version 5.1.0, GMP version 5.1.3, MPFR version 3.1.2, MPC version 1.0.3 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 GNU C++ (GCC) version 5.1.0 (i686-pc-linux-gnu) compiled by GNU C version 5.1.0, GMP version 5.1.3, MPFR version 3.1.2, MPC version 1.0.3 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 8a9e49c211f4d1d2fc149d62c24d84d4 test-const-mfp-table-arg.cc: In member function ‘bool Test::barl()’: test-const-mfp-table-arg.cc:67:20: error: invalid conversion from ‘bool (Test::* const*)()’ to ‘bool (Test::**)()’ [-fpermissive] return fool(fms); ^ test-const-mfp-table-arg.cc:40:6: note: initializing argument 1 of ‘bool Test: :fool(bool (Test::**)())’ bool Test::fool(bool (Test::* const *fms)(void)) ^ Preprocessor output (test-const-mfp-table-arg.ii): # 1 "test-const-mfp-table-arg.cc" # 1 "<built-in>" # 1 "<command-line>" # 1 "test-const-mfp-table-arg.cc" class Test { public: Test(); ~Test(); bool barl(void); private: bool fool(bool (Test::* const *fms)(void)); bool foo(void); bool bar(void); }; Test::Test() { } Test::~Test() { } # 40 "test-const-mfp-table-arg.cc" bool Test::fool(bool (Test::* const *fms)(void)) { bool retval = false; int i = 0; bool (Test::*f)(void) = fms[i++]; while (f) { retval = (this->*f)(); if (retval) break; f = fms[i++]; } return retval; } bool Test::barl(void) { static bool (Test::* const fms[])(void) = { &Test::foo, &Test::bar, 0 }; return fool(fms); } bool Test::foo(void) { return false; } bool Test::bar(void) { return true; } int main(int argc, const char *argv[]) { Test t; return t.barl(); }