GCC Bugzilla has been upgraded from version 4.4.9 to 5.0rc3. If you see any problem, please report it to bug 64968.
Bug 15471 - [3.4/4.0 Regression] Incorrect member pointer offsets in anonymous structs/unions
Summary: [3.4/4.0 Regression] Incorrect member pointer offsets in anonymous structs/un...
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: wrong-code
Depends on:
Blocks:
 
Reported: 2004-05-15 21:39 UTC by Udo Steinberg
Modified: 2004-10-30 21:11 UTC (History)
2 users (show)

See Also:
Host: i486-slackware-linux
Target: i486-slackware-linux
Build: n/a
Known to work:
Known to fail: 2.95.3 3.0.4 3.3.3 3.4.0 4.0.0
Last reconfirmed: 2004-05-26 12:07:55


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Udo Steinberg 2004-05-15 21:39:47 UTC
The code below outputs the addresses of member variables of class "myclass"
using a table of pointers to member variables and using an instance of
"myclass". I'd expect both methods to produce the same result, however, the
addresses of member variables x and y are wrong when applying the member
pointers to object "foo".


Compiler version:

Reading specs from /usr/lib/gcc/i486-slackware-linux/3.4.0/specs
Configured with: ../gcc-3.4.0/configure --prefix=/usr --enable-shared
--enable-threads=posix --enable-__cxa_atexit --disable-checking --with-gnu-ld
--verbose --target=i486-slackware-linux --host=i486-slackware-linux
Thread model: posix
gcc version 3.4.0

Example code to demonstrate the problem:

#include <stdio.h>

class myclass
{

public:
  union
  {
    unsigned state[5];
    struct
    {
      unsigned a;
      unsigned b;
      union
      {
        unsigned nums[2];
        struct
        {
          unsigned x, y;
        };
      };
      unsigned c;
    };
  };
};

unsigned
myclass::*
  members[] = {
  &myclass::a,
  &myclass::b,
  &myclass::x,
  &myclass::y,
  &myclass::c,
};

myclass
  foo;

int
main (void)
{
  printf ("a -> %p %p\n", &(foo.*members[0]), &foo.a);
  printf ("b -> %p %p\n", &(foo.*members[1]), &foo.b);
  printf ("x -> %p %p\n", &(foo.*members[2]), &foo.x); // differs
  printf ("y -> %p %p\n", &(foo.*members[3]), &foo.y); // differs
  printf ("c -> %p %p\n", &(foo.*members[4]), &foo.c);

  return 0;
}
Comment 1 Andrew Pinski 2004-05-15 21:56:59 UTC
anonymous structs are an extension to c++ so they could act any way.
Comment 2 Wolfgang Bangerth 2004-05-25 14:20:55 UTC
I don't know what we're supposed to do here, but this is indeed 
surprising: 
----------------------- 
#include <stdio.h> 
 
struct myclass { 
    unsigned a; 
    union { 
        unsigned x; 
    }; 
}; 
 
int main () { 
  myclass foo; 
  unsigned myclass::* member = &myclass::x; 
  printf ("x -> %p %p\n", &(foo.*member), &foo.x); 
} 
----------------------- 
One would expect the two pointers to be the same, but they're not: 
 
g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ x.cc ; ./a.out  
x -> 0xbfffeaa0 0xbfffeaa4 
 
It has indeed to do with the anonymous union (which in this case only 
contains a single element), since if I remove it and bring the variable 
x to the myclass scope, then the problem disappears. 
 
W. 
Comment 3 Giovanni Bajo 2004-05-26 12:07:51 UTC
I couldn't find the relevant paragraph in the standard, thus I am not sure this 
is actually legal code. It must be noted that EDG in strict mode accepts it and 
generates the same address for both pointers (which is by no doubt the correct 
behaviour, once we assume the code is legal).

GCC rejects this snippet up to 3.4. Since 3.4, we accept the snippet but 
generate wrong code with it. I rate this as a regression nonetheless, since 
wrong-code is much worse than what we used to do.
Comment 4 CVS Commits 2004-05-28 22:29:51 UTC
Subject: Bug 15471

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-3_4-branch
Changes by:	mmitchel@gcc.gnu.org	2004-05-28 22:29:44

Modified files:
	gcc/cp         : ChangeLog decl2.c init.c name-lookup.c typeck.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/g++.dg/expr: ptrmem4.C 
	gcc/testsuite/g++.dg/template: operator3.C 
	gcc/testsuite/g++.dg/warn: noeffect5.C 

Log message:
	PR c++/15083
	* decl2.c (delete_sanity): Set TREE_SIDE_EFFECTS on a DELETE_EXPR,
	even in a templat.e
	* init.c (build_new): Likewise.
	
	PR c++/15640
	* name-lookup.c (arg_assoc): Robustify.
	
	PR c++/15471
	* typeck.c (unary_complex_lvalue): Use context_for_name_lookup
	when determining the scope to use for a pointer to member.
	
	PR c++/15083
	* g++.dg/warn/noeffect5.C: New test.
	
	PR c++/15471
	* g++.dg/expr/ptrmem4.C: New test.
	
	PR c++/15640
	* g++.dg/template/operator3.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.107&r2=1.3892.2.108
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl2.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.695.4.7&r2=1.695.4.8
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/init.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.356.2.9&r2=1.356.2.10
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/name-lookup.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.34.2.12&r2=1.34.2.13
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.16&r2=1.519.2.17
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.185&r2=1.3389.2.186
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/expr/ptrmem4.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/operator3.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/warn/noeffect5.C.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=NONE&r2=1.2.4.1

Comment 5 CVS Commits 2004-05-28 22:35:57 UTC
Subject: Bug 15471

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	mmitchel@gcc.gnu.org	2004-05-28 22:35:50

Modified files:
	gcc/cp         : ChangeLog decl2.c init.c name-lookup.c typeck.c 
	gcc/testsuite  : ChangeLog 
Added files:
	gcc/testsuite/g++.dg/expr: ptrmem4.C 
	gcc/testsuite/g++.dg/template: operator3.C 
	gcc/testsuite/g++.dg/warn: noeffect6.C 

Log message:
	PR c++/15083
	* decl2.c (delete_sanity): Set TREE_SIDE_EFFECTS on a DELETE_EXPR,
	even in a templat.e
	* init.c (build_new): Likewise.
	
	PR c++/15640
	* name-lookup.c (arg_assoc): Robustify.
	
	PR c++/15471
	* typeck.c (unary_complex_lvalue): Use context_for_name_lookup
	when determining the scope to use for a pointer to member.
	
	PR c++/15083
	* g++.dg/warn/noeffect5.C: New test.
	
	PR c++/15471
	* g++.dg/expr/ptrmem4.C: New test.
	
	PR c++/15640
	* g++.dg/template/operator3.C: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4064&r2=1.4065
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/decl2.c.diff?cvsroot=gcc&r1=1.709&r2=1.710
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/init.c.diff?cvsroot=gcc&r1=1.370&r2=1.371
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/name-lookup.c.diff?cvsroot=gcc&r1=1.54&r2=1.55
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/typeck.c.diff?cvsroot=gcc&r1=1.544&r2=1.545
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.3789&r2=1.3790
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/expr/ptrmem4.C.diff?cvsroot=gcc&r1=1.1&r2=1.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/template/operator3.C.diff?cvsroot=gcc&r1=1.1&r2=1.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/warn/noeffect6.C.diff?cvsroot=gcc&r1=NONE&r2=1.1

Comment 6 CVS Commits 2004-05-28 23:33:53 UTC
Subject: Bug 15471

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-3_4-branch
Changes by:	mmitchel@gcc.gnu.org	2004-05-28 23:33:40

Modified files:
	gcc/cp         : ChangeLog cp-tree.h expr.c typeck.c 

Log message:
	PR c++/15471
	* typeck.c (unary_complex_lvalue): Use context_for_name_lookup
	when determining the scope to use for a pointer to member.
	(lookup_anon_field): Give it external linkage.
	* cp-tree.h (lookup_anon_field): Declare it.
	* expr.c (cplus_expand_constant): Use it.

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.108&r2=1.3892.2.109
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/cp-tree.h.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.946.4.11&r2=1.946.4.12
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/expr.c.diff?cvsroot=gcc&only_with_tag=gcc-3_4-branch&r1=1.75.4.1&r2=1.75.4.2
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.17&r2=1.519.2.18

Comment 7 CVS Commits 2004-05-28 23:34:43 UTC
Subject: Bug 15471

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	mmitchel@gcc.gnu.org	2004-05-28 23:34:39

Modified files:
	gcc/cp         : ChangeLog cp-tree.h expr.c typeck.c 

Log message:
	PR c++/15471
	* typeck.c (unary_complex_lvalue): Use context_for_name_lookup
	when determining the scope to use for a pointer to member.
	(lookup_anon_field): Give it external linkage.
	* cp-tree.h (lookup_anon_field): Declare it.
	* expr.c (cplus_expand_constant): Use it.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4065&r2=1.4066
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/cp-tree.h.diff?cvsroot=gcc&r1=1.968&r2=1.969
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/expr.c.diff?cvsroot=gcc&r1=1.77&r2=1.78
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/typeck.c.diff?cvsroot=gcc&r1=1.545&r2=1.546

Comment 8 Mark Mitchell 2004-05-28 23:35:50 UTC
Fixed in GCC 3.4.1.