Bug 15287 - [3.4/4.0 Regression] combination of operator[] and operator .* fails in templates
Summary: [3.4/4.0 Regression] combination of operator[] and operator .* fails in templ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.0
: P2 critical
Target Milestone: 3.4.1
Assignee: Mark Mitchell
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2004-05-04 22:54 UTC by Wirawan Purwanto
Modified: 2004-10-30 21:11 UTC (History)
1 user (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Known to work: 3.3.3
Known to fail: 3.4.0 4.0.0
Last reconfirmed: 2004-05-04 23:15:11


Attachments
Sample code to trigger the error (1.85 KB, application/octet-stream)
2004-05-04 22:56 UTC, Wirawan Purwanto
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Wirawan Purwanto 2004-05-04 22:54:18 UTC
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.
Comment 1 Wirawan Purwanto 2004-05-04 22:56:12 UTC
Created attachment 6224 [details]
Sample code to trigger the error

The output of my g++ compiler is also given in the source code.
Comment 2 Andrew Pinski 2004-05-04 23:15:10 UTC
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)();
}
-----------------------------
Comment 3 Wolfgang Bangerth 2004-05-04 23:51:06 UTC
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. 
Comment 4 Mark Mitchell 2004-05-22 18:26:50 UTC
Working on a fix.
Comment 5 GCC Commits 2004-05-22 19:17:07 UTC
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

Comment 6 GCC Commits 2004-05-22 19:28:40 UTC
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

Comment 7 Mark Mitchell 2004-05-22 19:31:16 UTC
Fixed in GCC 3.4.1.
Comment 8 Mark Mitchell 2004-05-22 19:31:33 UTC
Fixed in GCC 3.4.1.