Summary: | [3.3/3.4 Regression] static_cast ignores ambiguity | ||
---|---|---|---|
Product: | gcc | Reporter: | Alfred Minarik <alfred.minarik.1> |
Component: | c++ | Assignee: | Mark Mitchell <mark> |
Status: | RESOLVED FIXED | ||
Severity: | critical | CC: | gcc-bugs, mmitchel, pinskia |
Priority: | P1 | Keywords: | accepts-invalid |
Version: | 3.4.0 | ||
Target Milestone: | 3.3.2 | ||
Host: | i686-pc-linux-gnu | Target: | i686-pc-linux-gnu |
Build: | i686-pc-linux-gnu | Known to work: | |
Known to fail: | Last reconfirmed: | 2003-09-06 15:59:51 |
Description
Alfred Minarik
2003-08-09 12:25:32 UTC
GCC 3.2.3 rejected this: pr11867.cc: In function `void ambig()': pr11867.cc:10: invalid static_cast from type `ambig()::A*' to type `ambig()::D* ' pr11867.cc:12: `ambig()::A' is an ambiguous base of `ambig()::D' pr11867.cc:15: `ambig()::A' is an ambiguous base of `ambig()::D' Where 3.3.1 (20030707) and the mainline (20030808) does not. From Phil's regression hunter: Search converges between 2003-06-25-trunk (#324) and 2003- 06-26-trunk (#325): Search converges between 2003-06-25-3.3 (#149) and 2003-06-26-3.3 (#150). The regression in PR 11867 was introduced or exposed by this patch: --- gcc/gcc/cp/ChangeLog --- 2003-06-25 Mark Mitchell <mark@codesourcery.com> PR c++/10931 * call.c (convert_like): Pass issue_conversion_warnings. (convert_like_with_context): Likewise. (convert_like_real): Add issue_conversion_warnings parameter. (perform_direct_initialization_if_possible): New function. * cp-tree.h (perform_direct_initialization_if_possible): Declare it. * typeck.c (check_for_casting_away_constness): New function. (build_static_cast): Rewrite. The regression hunt took place on i686-pc-linux-gnu using the submitter's test case. Fixed by (had the wrong PR number in it): 2003-09-06 Mark Mitchell PR c++/11687 * call.c (standard_conversion): Improve comments. (perform_direct_initialization): Make sure we return an expression of the correct type. * typeck.c (build_static_cast): Check for ambiguity and accessibility when performing conversions. Thanks for fixing this. And also for adding the accessibility check. I did not report it, as I was not 100% sure about. e.g. Comeau online test pass this without error: (g++ now rejects it as I would have expected.) ------- struct A {}; struct B : private A {}; int main () { B b; A* ap = (A*) &b; B* bp = static_cast<B*> (ap); //Error } --------- Subject: Re: [3.3/3.4 Regression] static_cast ignores
ambiguity
On Sun, 2003-09-07 at 03:28, alfred dot minarik dot 1 at aon dot at
wrote:
> PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11867
>
>
>
> ------- Additional Comments From alfred dot minarik dot 1 at aon dot at 2003-09-07 10:28 -------
> Thanks for fixing this.
>
> And also for adding the accessibility check.
> I did not report it, as I was not 100% sure about.
Now that you mention that, I'd better go back and check the standard one
more time on that to make sure one way or the other.
Thanks,
Subject: Re: [3.3/3.4 Regression] static_cast ignores
ambiguity
> struct A {};
>
> struct B : private A {};
>
> int
> main ()
> {
> B b;
> A* ap = (A*) &b;
> B* bp = static_cast<B*> (ap); //Error
> }
This program is invalid.
The reason is that the only static_cast alternative that would allow
this conversion is the:
An rvalue of type "pointer to cv1 B", where B is a class type, can be
converted to an rvalue of type "pointer to cv2 D", where D is a class
derived (clause _class.derived_) from B, if a valid standard conver-
sion from "pointer to D" to "pointer to B" exists (_conv.ptr_), cv2 is
the same cv-qualification as, or greater cv-qualification than, cv1,
and B is not a virtual base class of D.
The "valid standard conversion" clause must be read to imply that this
restriction from [conv.ptr] applies to the conversion:
If B is an inaccessible (clause _class.access_) or ambiguous
(_class.member.lookup_) base class of D, a program that necessitates
this conversion is ill-formed.
Otherwise, there is nothing in the static_cast language to eliminate a
conversion from an ambiguous base to a derived class.
In fact, this was examined by the committee back in 1998, and is Core
Issue 54:
=====================
54. Static_cast from private base to derived class
Section: 5.2.9 expr.static.cast Status: NAD Submitter: Steve
Adamczyk Date: 13 Oct 1998
Is it okay to use a static_cast to cast from a private base class to a
derived class? That depends on what the words "valid standard
conversion" in paragraph 8 mean — do they mean the conversion exists, or
that it would not get an error if it were done? I think the former was
intended — and therefore a static_cast from a private base to a derived
class would be allowed.
Rationale (04/99): A static_cast from a private base to a derived class
is not allowed outside a member from the derived class, because 4.10
conv.ptr paragraph 3 implies that the conversion is not valid. (Classic
style casts work.)
=====================
|