aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/call.c14
-rw-r--r--gcc/cp/class.c3
-rw-r--r--gcc/testsuite/g++.dg/expr/cast9.C12
4 files changed, 21 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e8d8adf..1f05c68 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -8,6 +8,12 @@
2008-01-25 Jason Merrill <jason@redhat.com>
+ PR c++/27177
+ * class.c (build_base_path): Don't mess with virtual access if
+ skip_evaluation.
+ * call.c (standard_conversion): Don't check whether source type
+ is complete.
+
* decl2.c (is_late_template_attribute): Don't defer attribute
visibility just because the type is dependent.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 3cd80b4..c4e4c79 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -745,19 +745,7 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
that necessitates this conversion is ill-formed.
Therefore, we use DERIVED_FROM_P, and do not check
access or uniqueness. */
- && DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from))
- /* If FROM is not yet complete, then we must be parsing
- the body of a class. We know what's derived from
- what, but we can't actually perform a
- derived-to-base conversion. For example, in:
-
- struct D : public B {
- static const int i = sizeof((B*)(D*)0);
- };
-
- the D*-to-B* conversion is a reinterpret_cast, not a
- static_cast. */
- && COMPLETE_TYPE_P (TREE_TYPE (from)))
+ && DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from)))
{
from =
cp_build_qualified_type (TREE_TYPE (to),
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 65e7144..6b76bf7 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -291,7 +291,8 @@ build_base_path (enum tree_code code,
target_type = code == PLUS_EXPR ? BINFO_TYPE (binfo) : BINFO_TYPE (d_binfo);
/* Do we need to look in the vtable for the real offset? */
- virtual_access = (v_binfo && fixed_type_p <= 0);
+ /* Don't bother inside sizeof; the source type might not be complete. */
+ virtual_access = (v_binfo && fixed_type_p <= 0) && !skip_evaluation;
/* Do we need to check for a null pointer? */
if (want_pointer && !nonnull)
diff --git a/gcc/testsuite/g++.dg/expr/cast9.C b/gcc/testsuite/g++.dg/expr/cast9.C
new file mode 100644
index 0000000..150183a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/cast9.C
@@ -0,0 +1,12 @@
+// PR c++/27177
+
+struct Z {};
+struct A : Z {};
+
+Z* implicitToZ (Z*);
+
+struct B : A
+{
+ static const int i = sizeof(implicitToZ((B*)0));
+};
+