Bug 22132 - [4.0/4.1 Regression] Wrong code: upcasting a const class pointer to struct the class derives from (C/old-style cast)
Summary: [4.0/4.1 Regression] Wrong code: upcasting a const class pointer to struct th...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.0.0
: P2 normal
Target Milestone: 4.0.2
Assignee: Mark Mitchell
URL:
Keywords: wrong-code
: 22281 23418 (view as bug list)
Depends on: 22281
Blocks: 28357 31074
  Show dependency treegraph
 
Reported: 2005-06-21 01:35 UTC by scott.tupaj
Modified: 2007-03-08 02:06 UTC (History)
7 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-07-11 19:39:56


Attachments
Sample code to illustrate bug (534 bytes, text/plain)
2005-06-21 01:37 UTC, scott.tupaj
Details
preprocessed source file (80.94 KB, text/plain)
2005-06-21 01:38 UTC, scott.tupaj
Details
Compiler Info (303 bytes, text/plain)
2005-06-21 01:38 UTC, scott.tupaj
Details
Compiler output (748 bytes, text/plain)
2005-06-21 01:38 UTC, scott.tupaj
Details

Note You need to log in before you can comment on or make changes to this bug.
Description scott.tupaj 2005-06-21 01:35:47 UTC
Upcasting a const class pointer for a class that was derived from a struct causes the upcasted pointer to 
incorrectly access members of the derived struct.

Conditions:
1) The derived class object must have a virtual destructor (or possibly any v-table entries)
2) The upcast must be a straight 'C' cast that does not preserve the const.

I've attached a code sample that demonstrates the error, but this is the scenario:

struct foo {
   int a;
   int b;
};

class Foobar : public foo {
public:
    Foobar() { a = 1; b = 2; };
    virtual ~Foobar() {};
};

Foobar obj;
const Foobar* objPtr = &obj;
foo* f = (foo*)objPtr;

contents of f->a and f->b during runtime are not 1 and 2 as expected.
f->a is garbage
f->b is 1 (expected value of f->a)
Comment 1 scott.tupaj 2005-06-21 01:37:11 UTC
Created attachment 9120 [details]
Sample code to illustrate bug
Comment 2 scott.tupaj 2005-06-21 01:38:02 UTC
Created attachment 9121 [details]
preprocessed source file
Comment 3 scott.tupaj 2005-06-21 01:38:21 UTC
Created attachment 9122 [details]
Compiler Info
Comment 4 scott.tupaj 2005-06-21 01:38:41 UTC
Created attachment 9123 [details]
Compiler output
Comment 5 Andrew Pinski 2005-06-21 03:05:24 UTC
I think this is invalid, you want:
   OBJ* p1 = const_cast<AnObject*>(objPtr);
but I don't have prove at this point if this invalid.
Comment 6 scott.tupaj 2005-06-21 17:01:38 UTC
Yes, agreeably this is 'bad' c++ practice in my example.  However, if wrong 
code is produced, I think it would be prudent for at least a compiler warning 
or error be produced if the reason for wrong code is because invalid or 
questionable c++ syntax is being used.  

Every other compiler I've used, including gcc 3.x.x doesn't not corrupt access 
to the members in this scenario like gcc 4.0.0 does.  Other compilers either 
error because of the const violation, or accepts it and produces the proper 
results when accessing the pointer.

Comment 7 Mark Mitchell 2005-07-06 16:29:43 UTC
This is a bug in my static_cast rewrite.  I will fix it for 4.0.2.
Comment 8 Mark Mitchell 2005-07-15 16:00:23 UTC
*** Bug 22281 has been marked as a duplicate of this bug. ***
Comment 9 CVS Commits 2005-07-15 16:10:15 UTC
Subject: Bug 22132

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	mmitchel@gcc.gnu.org	2005-07-15 16:10:08

Modified files:
	gcc/testsuite  : ChangeLog 
	gcc/cp         : ChangeLog call.c cp-tree.h typeck.c 
Added files:
	gcc/testsuite/g++.dg/expr: cast4.C 

Log message:
	PR c++/22132
	* call.c (implicit_conversion): Add c_cast_p parameter.
	(standard_conversion): Likewise.  Allow conversions between
	differently-qualified pointer types when performing a C-style
	cast.
	(add_function_candidate): Adjust callee.
	(build_builtin_candidate): Likewise.
	(build_user_type_conversion_1): Likewise.
	(conditional_conversion): Likewise.
	(can_convert_arg): Likewise.
	(can_convert_arg_bad): Likewise.
	(perform_implicit_conversion): Likewise.
	* cp-tree.h (comp_ptr_ttypes_const): Declare.
	* typeck.c (comp_ptr_ttypes_const): Give it external linkage.
	Return bool.
	
	PR c++/22132
	* g++.dg/expr/cast4.C: New test.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.5771&r2=1.5772
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/expr/cast4.C.diff?cvsroot=gcc&r1=NONE&r2=1.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&r1=1.4819&r2=1.4820
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/call.c.diff?cvsroot=gcc&r1=1.543&r2=1.544
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/cp-tree.h.diff?cvsroot=gcc&r1=1.1153&r2=1.1154
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/typeck.c.diff?cvsroot=gcc&r1=1.642&r2=1.643

Comment 11 Mark Mitchell 2005-07-15 18:50:15 UTC
Fixed in 4.0.2.
Comment 12 CVS Commits 2005-08-03 02:17:53 UTC
Subject: Bug 22132

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	apple-local-200502-branch
Changes by:	mrs@gcc.gnu.org	2005-08-03 02:17:44

Modified files:
	gcc/cp         : call.c ChangeLog cp-tree.h typeck.c 
Added files:
	gcc/testsuite/g++.dg/expr: cast4.C 

Log message:
	PR c++/22132
	* call.c (implicit_conversion): Add c_cast_p parameter.
	(standard_conversion): Likewise.  Allow conversions between
	differently-qualified pointer types when performing a C-style
	cast.
	(add_function_candidate): Adjust callee.
	(build_builtin_candidate): Likewise.
	(build_user_type_conversion_1): Likewise.
	(conditional_conversion): Likewise.
	(can_convert_arg): Likewise.
	(can_convert_arg_bad): Likewise.
	(perform_implicit_conversion): Likewise.
	* cp-tree.h (comp_ptr_ttypes_const): Declare.
	* typeck.c (comp_ptr_ttypes_const): Give it external linkage.
	Return bool.
	Radar 4076725

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/call.c.diff?cvsroot=gcc&only_with_tag=apple-local-200502-branch&r1=1.530.4.5&r2=1.530.4.6
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/ChangeLog.diff?cvsroot=gcc&only_with_tag=apple-local-200502-branch&r1=1.4631.2.7&r2=1.4631.2.8
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/cp-tree.h.diff?cvsroot=gcc&only_with_tag=apple-local-200502-branch&r1=1.1104.2.8&r2=1.1104.2.9
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/cp/typeck.c.diff?cvsroot=gcc&only_with_tag=apple-local-200502-branch&r1=1.614.2.14&r2=1.614.2.15
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/g++.dg/expr/cast4.C.diff?cvsroot=gcc&only_with_tag=apple-local-200502-branch&r1=NONE&r2=1.1.14.1

Comment 13 Andrew Pinski 2005-08-16 11:56:51 UTC
*** Bug 23418 has been marked as a duplicate of this bug. ***