Bug 48035 - [4.4 Regression] Mismatch on size of class when initializing hierarchy involving virtual inheritance and empty base classes
Summary: [4.4 Regression] Mismatch on size of class when initializing hierarchy involv...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.4.5
: P2 normal
Target Milestone: 4.4.7
Assignee: Jakub Jelinek
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2011-03-08 22:14 UTC by Scot Salmon
Modified: 2011-10-13 18:05 UTC (History)
7 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.3.5, 4.5.3, 4.6.0
Known to fail: 4.4.5, 4.5.2
Last reconfirmed: 2011-03-08 22:45:54


Attachments
preprocessed source file (204 bytes, text/plain)
2011-03-08 22:14 UTC, Scot Salmon
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Scot Salmon 2011-03-08 22:14:34 UTC
Created attachment 23585 [details]
preprocessed source file

The attached preprocessed source file is a much-simplified version of a more complex class hierarchy involving several levels of virtual inheritance and empty classes in the hierarchy.

"g++ -v" details:
Using built-in specs.
Target: i686-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux
Thread model: posix
gcc version 4.4.5 20101112 (Red Hat 4.4.5-2) (GCC)

Also tested with a new build:
Using built-in specs.
COLLECT_GCC=./g++
Target: i686-pc-linux-gnu
Configured with: ./configure
Thread model: posix
gcc version 4.5.2 (GCC)

Among others.

Compile with "g++ -c vtable-bug.i".

What we observe (tested on x86 and ARM) is that "operator new" is called to allocate 12 bytes for the class (and sizeof matches that 12 byte size), but the compiled code then proceeds to load four-byte 0's into offsets 0, 4, 8, AND 12 from the allocated buffer, stomping data at byte offsets 12-15.  (More complex hierarchies can result in more than one 4-byte offset being stomped, and/or the same offset being initialized repeatedly.)

Changing which classes are virtual, or adding data to empty base classes, changes or fixes the behavior.
Comment 1 Andrew Pinski 2011-03-08 22:43:13 UTC
On x86_64 with valgrind:


==31260== Invalid write of size 8
==31260==    at 0x4006E0: BadStuffHere() (t.cc:38)
==31260==    by 0x400703: main (t.cc:43)
==31260==  Address 0x5936058 is 0 bytes after a block of size 24 alloc'd
==31260==    at 0x4C24DFA: operator new(unsigned long) (vg_replace_malloc.c:261)
==31260==    by 0x4006C6: BadStuffHere() (t.cc:38)
==31260==    by 0x400703: main (t.cc:43)
Comment 2 Andrew Pinski 2011-03-08 22:45:54 UTC
Confirmed, there was no valgrind errors in 4.3.5.
Comment 3 Jakub Jelinek 2011-03-09 12:46:12 UTC
I think this started with
http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=138355
Comment 4 Jakub Jelinek 2011-03-09 14:03:35 UTC
I think the problem is that build_zero_init isn't aware of the DECL_FIELD_IS_BASE FIELD_DECLs and CLASSTYPE_AS_BASE stuff.  So when simplify_aggr_init_expr decides to call build_zero_init on the SpecificImplementation type, while the first FIELD_DECL has size 8 and its type also size 8, the second FIELD_DECL has size 12 (CLASSTYPE_SIZE_UNIT), its type has size 24 and thus what build_zero_init returns on the subtype isn't directly usable as ctor of the outer type.
Comment 5 Jakub Jelinek 2011-03-11 15:43:42 UTC
Author: jakub
Date: Fri Mar 11 15:43:37 2011
New Revision: 170874

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=170874
Log:
	PR c++/48035
	* init.c (build_zero_init_1): Extracted from build_zero_init.
	Add FIELD_SIZE argument, if non-NULL and field bit_position
	as not smaller than that, don't add that field's initializer.
	Pass DECL_SIZE as last argument to build_zero_init_1
	for DECL_FIELD_IS_BASE fields.
	(build_zero_init): Use build_zero_init_1.

	* g++.dg/inherit/virtual8.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/inherit/virtual8.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/init.c
    trunk/gcc/testsuite/ChangeLog
Comment 6 Jakub Jelinek 2011-03-11 15:45:04 UTC
Fixed on the trunk so far.
Comment 7 Thomas Schwinge 2011-04-11 21:23:27 UTC
FWIW, I'm confirming both the bug and the fix in a 4.5-based tree.
Comment 8 Richard Biener 2011-04-18 14:02:27 UTC
Author: rguenth
Date: Mon Apr 18 14:02:22 2011
New Revision: 172647

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172647
Log:
2011-04-18  Richard Guenther  <rguenther@suse.de>

	Backported from 4.6 branch 
	2011-03-11  Jakub Jelinek  <jakub@redhat.com>

	PR c++/48035
	* init.c (build_zero_init_1): Extracted from build_zero_init.
	Add FIELD_SIZE argument, if non-NULL and field bit_position
	as not smaller than that, don't add that field's initializer.
	Pass DECL_SIZE as last argument to build_zero_init_1
	for DECL_FIELD_IS_BASE fields.
	(build_zero_init): Use build_zero_init_1.

	* g++.dg/inherit/virtual8.C: New test.

	2011-03-05  Zdenek Dvorak  <ook@ucw.cz>

	PR rtl-optimization/47899
	* cfgloopmanip.c (fix_bb_placements): Fix first argument
	to flow_loop_nested_p when moving the loop upward.
 
	* gcc.dg/pr47899.c: New test.

	2011-03-15  Richard Guenther  <rguenther@suse.de>
 
	PR middle-end/48031
	* fold-const.c (fold_indirect_ref_1): Do not create new variable-sized
	or variable-indexed array accesses when in gimple form.

Modified:
    branches/gcc-4_5-branch/gcc/ChangeLog
    branches/gcc-4_5-branch/gcc/cfgloopmanip.c
    branches/gcc-4_5-branch/gcc/cp/ChangeLog
    branches/gcc-4_5-branch/gcc/cp/init.c
    branches/gcc-4_5-branch/gcc/fold-const.c
    branches/gcc-4_5-branch/gcc/testsuite/ChangeLog
Comment 9 Richard Biener 2011-04-18 14:37:17 UTC
Author: rguenth
Date: Mon Apr 18 14:37:08 2011
New Revision: 172652

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172652
Log:
2011-04-18  Richard Guenther  <rguenther@suse.de>

    Backported from 4.6 branch 
    2011-03-11  Jakub Jelinek  <jakub@redhat.com>

    PR c++/48035
    * init.c (build_zero_init_1): Extracted from build_zero_init.
    Add FIELD_SIZE argument, if non-NULL and field bit_position
    as not smaller than that, don't add that field's initializer.
    Pass DECL_SIZE as last argument to build_zero_init_1
    for DECL_FIELD_IS_BASE fields.
    (build_zero_init): Use build_zero_init_1.

    * g++.dg/inherit/virtual8.C: New test.

    2011-03-05  Zdenek Dvorak  <ook@ucw.cz>

    PR rtl-optimization/47899
    * cfgloopmanip.c (fix_bb_placements): Fix first argument
    to flow_loop_nested_p when moving the loop upward.

    * gcc.dg/pr47899.c: New test.

    2011-03-15  Richard Guenther  <rguenther@suse.de>

    PR middle-end/48031
    * fold-const.c (fold_indirect_ref_1): Do not create new variable-sized
    or variable-indexed array accesses when in gimple form.

Added:
    branches/gcc-4_5-branch/gcc/testsuite/g++.dg/inherit/virtual8.C
    branches/gcc-4_5-branch/gcc/testsuite/gcc.dg/pr47899.c
Comment 10 Paolo Carlini 2011-09-23 21:57:15 UTC
Jakub, shall we close this?
Comment 11 Ozkan Sezer 2011-10-05 08:10:50 UTC
Will the fixes for this PR go into 4.4?
Comment 12 Jason Merrill 2011-10-13 18:03:01 UTC
Author: jason
Date: Thu Oct 13 18:02:53 2011
New Revision: 179937

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=179937
Log:
	PR c++/48035
	* init.c (build_zero_init_1): Extracted from build_zero_init.
	Add FIELD_SIZE argument, if non-NULL and field bit_position
	as not smaller than that, don't add that field's initializer.
	Pass DECL_SIZE as last argument to build_zero_init_1
	for DECL_FIELD_IS_BASE fields.
	(build_zero_init): Use build_zero_init_1.

Added:
    branches/gcc-4_4-branch/gcc/testsuite/g++.dg/inherit/virtual8.C
Modified:
    branches/gcc-4_4-branch/gcc/cp/ChangeLog
    branches/gcc-4_4-branch/gcc/cp/init.c
    branches/gcc-4_4-branch/gcc/testsuite/ChangeLog
Comment 13 Jason Merrill 2011-10-13 18:05:36 UTC
Fixed for 4.4.7.