Commit 385bce06 by Mark Mitchell Committed by Mark Mitchell

re PR c++/11867 (static_cast ignores ambiguity)

	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.

	PR c++/11687
	* g++.dg/expr/static_cast5.C: New test.

From-SVN: r71157
parent ef8f74d6
2003-09-06 Mark Mitchell <mark@codesourcery.com>
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.
2003-09-06 Gabriel Dos Reis <gdr@integrable-solutions.net>
* cp-tree.h (add_binding): Remove declaration.
......
......@@ -701,16 +701,25 @@ standard_conversion (tree to, tree from, tree expr)
}
}
else if (IS_AGGR_TYPE (TREE_TYPE (from))
&& IS_AGGR_TYPE (TREE_TYPE (to)))
&& IS_AGGR_TYPE (TREE_TYPE (to))
/* [conv.ptr]
An rvalue of type "pointer to cv D," where D is a
class type, can be converted to an rvalue of type
"pointer to cv B," where B is a base class (clause
_class.derived_) of D. 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. */
/* Therefore, we use DERIVED_FROM_P, and not
ACESSIBLY_UNIQUELY_DERIVED_FROM_P, in this test. */
&& DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
{
if (DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
{
from =
cp_build_qualified_type (TREE_TYPE (to),
cp_type_quals (TREE_TYPE (from)));
from = build_pointer_type (from);
conv = build_conv (PTR_CONV, from, conv);
}
from =
cp_build_qualified_type (TREE_TYPE (to),
cp_type_quals (TREE_TYPE (from)));
from = build_pointer_type (from);
conv = build_conv (PTR_CONV, from, conv);
}
if (tcode == POINTER_TYPE)
......@@ -5970,10 +5979,13 @@ perform_direct_initialization_if_possible (tree type, tree expr)
the overload resolution is ambiguous, the initialization is
ill-formed. */
if (CLASS_TYPE_P (type))
return build_special_member_call (NULL_TREE, complete_ctor_identifier,
build_tree_list (NULL_TREE, expr),
TYPE_BINFO (type),
LOOKUP_NORMAL);
{
expr = build_special_member_call (NULL_TREE, complete_ctor_identifier,
build_tree_list (NULL_TREE, expr),
TYPE_BINFO (type),
LOOKUP_NORMAL);
return build_cplus_new (type, expr);
}
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
LOOKUP_NORMAL);
if (!conv || ICS_BAD_FLAG (conv))
......
......@@ -4427,12 +4427,13 @@ build_static_cast (tree type, tree expr)
(TREE_TYPE (type))))
&& at_least_as_qualified_p (TREE_TYPE (type), intype))
{
/* At this point we have checked all of the conditions except
that B is not a virtual base class of D. That will be
checked by build_base_path. */
tree base = lookup_base (TREE_TYPE (type), intype, ba_any, NULL);
/* There is a standard conversion from "D*" to "B*" even if "B"
is ambiguous or inaccessible. Therefore, we ask lookup_base
to check these conditions. */
tree base = lookup_base (TREE_TYPE (type), intype, ba_check, NULL);
/* Convert from B* to D*. */
/* Convert from "B*" to "D*". This function will check that "B"
is not a virtual base of "D". */
expr = build_base_path (MINUS_EXPR, build_address (expr),
base, /*nonnull=*/false);
/* Convert the pointer to a reference -- but then remember that
......@@ -4491,8 +4492,8 @@ build_static_cast (tree type, tree expr)
tree base;
check_for_casting_away_constness (intype, type, "static_cast");
base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype),
ba_check | ba_quiet, NULL);
base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype), ba_check,
NULL);
return build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false);
}
......
2003-09-06 Mark Mitchell <mark@codesourcery.com>
PR c++/11687
* g++.dg/expr/static_cast5.C: New test.
2003-09-06 Nathan Sidwell <nathan@codesourcery.com>
PR c++/11794
......
void ambig()
{
struct A {};
struct B : A {};
struct C : A {};
struct D : B, C {};
D d;
A* ap = static_cast<B*> (&d);
D* db = static_cast<D*> (ap); // { dg-error "" }
D& dr1 = static_cast<D&> (*ap); // { dg-error "" }
A& ar = static_cast<C&> (d);
D& dr = static_cast<D&> (ar); // { dg-error "" }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment