DESCRIPTION G++ 3.4 wrongly recognizes some valid C++ syntax as an error: This in particular happens when a class/structure is operated upon with both `[]' and `.*' operators, like this: (Class[C].*BoolMethod)(); //<1> where Class is any C++ object; C is a size_t variable, and BoolMethod is a pointer to method. An attachment is given as a concrete example of the problem. Some generic conditions are required to trigger the bug: * This problem was originally discovered when `Class' is of the type `std::vector<something>'. But it turns out that any C++ object would trigger the error. * The statement //<1> must be in a templatized function or class method. Look at the example: Uncomment line //[4] and comment //[5], then the error will not happen in `void Proc(_type2)'. WORKAROUND A temporary workaround is possible, by FIRST caching the `[]' operator result, then applying the `.*' operator. But this may or may not work, depending on what actually happens with the `[]' operator. Consider my given example: * If you compile with -DWORK_AROUND_BUG, the error messages disappear. * If you compile with -DWORK_AROUND_BUG=-1 instead, the same error message would re-appear. The addition of parantheses does not help. VERSION KNOWN TO BE AFFECTED: 3.4 My gcc gives the following version/compilation info: [wirawan@snowflake tmp]$ /usr/local/gcc-3.4.0/bin/g++ -v Reading specs from /usr/local/gcc-3.4.0/lib/gcc/i686-pc-linux-gnu/3.4.0/specs Configured with: ../gcc-3.4.0/configure --prefix=/usr/local/gcc-3.4.0 --disable-nls --enable-languages=c,c++,f77 --enable-shared --with-cpu=i686 --with-tune=i686 --with-arch=i686 --enable-threads=posix --enable-__cxa_atexit Thread model: posix gcc version 3.4.0 OTHER VERSIONS This error does NOT happen with GNU C++ version 3.3.x and earlier.
Created attachment 6224 [details] Sample code to trigger the error The output of my g++ compiler is also given in the source code.
Confirmed. Reduced to: ----------------------------- typedef __SIZE_TYPE__ size_t; struct Structure {}; // empty, just a dummy placeholder extern Structure& t; struct Vector2 { typedef Structure& reference; reference operator[](int x) {return t;} }; Vector2 Array; template <int>//t void Print(void (Structure::*BoolMethod)()) { size_t C = 0; (Array[C].*BoolMethod)(); } -----------------------------
Yes, and still a little smaller: ---------------- struct S {}; struct Array { S operator[](int); } array; void (S::*mem_fun_ptr)(); template <int> void foo() { (array[0].*mem_fun_ptr)(); } -------------------- g/x> /home/bangerth/bin/gcc-3.3.4-pre/bin/c++ -c x.cc g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ -c x.cc x.cc: In function `void foo()': x.cc:10: error: invalid operands of types `Array' and `int' to binary `operator+' Another workaround is to write array.operator[](0) instead of array[0] W.
Working on a fix.
Subject: Bug 15287 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_4-branch Changes by: mmitchel@gcc.gnu.org 2004-05-22 19:16:53 Modified files: gcc/cp : ChangeLog class.c typeck.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/g++.dg/inherit: union1.C gcc/testsuite/g++.dg/template: addr1.C array5.C array6.C Log message: PR c++/15507 * g++.dg/inherit/union1.C: New test. PR c++/15542 * g++.dg/template/addr1.C: New test. PR c++/15427 * g++.dg/template/array5.C: New test. PR c++/15287 * g++.dg/template/array6.C: New test. PR c++/15507 * g++.dg/inherit/union1.C: New test. PR c++/15542 * g++.dg/template/addr1.C: New test. PR c++/15427 * g++.dg/template/array5.C: New test. PR c++/15287 * g++.dg/template/array6.C: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3892.2.100&r2=1.3892.2.101 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/class.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.595.4.7&r2=1.595.4.8 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/typeck.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.519.2.14&r2=1.519.2.15 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.3389.2.177&r2=1.3389.2.178 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/inherit/union1.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/addr1.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/array5.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/array6.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.1.2.1
Subject: Bug 15287 CVSROOT: /cvs/gcc Module name: gcc Changes by: mmitchel@gcc.gnu.org 2004-05-22 19:28:31 Modified files: gcc/cp : ChangeLog class.c typeck.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/g++.dg/inherit: union1.C gcc/testsuite/g++.dg/template: addr1.C array5.C array6.C Log message: PR c++/15507 * class.c (layout_nonempty_base_or_field): Do not try to avoid layout conflicts for unions. PR c++/15542 * typeck.c (build_x_unary_op): Instantiate template class specializations before looking for "operator &". PR c++/15427 * typeck.c (complete_type): Layout non-dependent array types, even in templates. PR c++/15287 * typeck.c (build_unary_op): Do not optimize "&x[y]" when in a template. PR c++/15507 * g++.dg/inherit/union1.C: New test. PR c++/15542 * g++.dg/template/addr1.C: New test. PR c++/15427 * g++.dg/template/array5.C: New test. PR c++/15287 * g++.dg/template/array6.C: New test. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4050&r2=1.4051 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/class.c.diff?cvsroot=gcc&r1=1.612&r2=1.613 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/typeck.c.diff?cvsroot=gcc&r1=1.542&r2=1.543 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.3769&r2=1.3770 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/inherit/union1.C.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/addr1.C.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/array5.C.diff?cvsroot=gcc&r1=1.1&r2=1.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/array6.C.diff?cvsroot=gcc&r1=1.1&r2=1.2
Fixed in GCC 3.4.1.