aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2004-12-14 15:39:12 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2004-12-14 15:39:12 +0000
commite8c66fe0e19849b41b227666405de82bf3391e5f (patch)
tree7dbf4d083fa9aa07d8ff70f0e237f880b53e8a1c /gcc
parent3a42aebe0bc6555520bbd648f491b55079914f5d (diff)
downloadgcc-e8c66fe0e19849b41b227666405de82bf3391e5f.zip
gcc-e8c66fe0e19849b41b227666405de82bf3391e5f.tar.gz
gcc-e8c66fe0e19849b41b227666405de82bf3391e5f.tar.bz2
re PR c++/18949 (trouble with const_cast in templates)
cp: PR c++/18949 * pt.c (tsubst_copy_and_build): <INDIRECT_REF case> Check that a REFERENCE_REF_P is dereferencing a reference type. * typeck.c (build_static_cast): Convert from reference even in a template. (build_reinterpret_cast, build_const_cast, build_c_cast): Likewise. testsuite: PR c++/18949 * g++.dg/template/cast1.C: New. From-SVN: r92136
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/pt.c7
-rw-r--r--gcc/cp/typeck.c8
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/cast1.C22
5 files changed, 45 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 86610ec..1dd91a12 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,12 @@
+2004-12-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18949
+ * pt.c (tsubst_copy_and_build): <INDIRECT_REF case> Check that a
+ REFERENCE_REF_P is dereferencing a reference type.
+ * typeck.c (build_static_cast): Convert from reference even in a
+ template.
+ (build_reinterpret_cast, build_const_cast, build_c_cast): Likewise.
+
2004-12-14 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
* parser.c (cp_parser_uncommitted_to_tentative_parse_p): New function.
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 6e34ba6..5da2806 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -8395,8 +8395,11 @@ tsubst_copy_and_build (tree t,
if (REFERENCE_REF_P (t))
{
- gcc_assert (TREE_CODE (TREE_TYPE (r)) == REFERENCE_TYPE);
- r = convert_from_reference (r);
+ /* A type conversion to reference type will be enclosed in
+ such an indirect ref, but the substitution of the cast
+ will have also added such an indirect ref. */
+ if (TREE_CODE (TREE_TYPE (r)) == REFERENCE_TYPE)
+ r = convert_from_reference (r);
}
else
r = build_x_indirect_ref (r, "unary *");
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 74380d3..9d347c2 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4767,7 +4767,7 @@ build_static_cast (tree type, tree expr)
expr = build_min (STATIC_CAST_EXPR, type, expr);
/* We don't know if it will or will not have side effects. */
TREE_SIDE_EFFECTS (expr) = 1;
- return expr;
+ return convert_from_reference (expr);
}
/* build_c_cast puts on a NOP_EXPR to make the result not an lvalue.
@@ -4983,7 +4983,7 @@ build_reinterpret_cast (tree type, tree expr)
&& type_dependent_expression_p (expr))
/* There might turn out to be side effects inside expr. */
TREE_SIDE_EFFECTS (t) = 1;
- return t;
+ return convert_from_reference (t);
}
return build_reinterpret_cast_1 (type, expr, /*c_cast_p=*/false,
@@ -5111,7 +5111,7 @@ build_const_cast (tree type, tree expr)
&& type_dependent_expression_p (expr))
/* There might turn out to be side effects inside expr. */
TREE_SIDE_EFFECTS (t) = 1;
- return t;
+ return convert_from_reference (t);
}
return build_const_cast_1 (type, expr, /*complain=*/true,
@@ -5137,7 +5137,7 @@ build_c_cast (tree type, tree expr)
tree_cons (NULL_TREE, value, NULL_TREE));
/* We don't know if it will or will not have side effects. */
TREE_SIDE_EFFECTS (t) = 1;
- return t;
+ return convert_from_reference (t);
}
/* Casts to a (pointer to a) specific ObjC class (or 'id' or
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index eaebf8a..d94cb67 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2004-12-14 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18949
+ * g++.dg/template/cast1.C: New.
+
2004-12-13 Richard Henderson <rth@redhat.com>
* gcc.dg/i386-sse-10.c: Fix typo in options.
diff --git a/gcc/testsuite/g++.dg/template/cast1.C b/gcc/testsuite/g++.dg/template/cast1.C
new file mode 100644
index 0000000..fca3511
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/cast1.C
@@ -0,0 +1,22 @@
+// { dg-do compile }
+
+// Copyright (C) 2004 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 14 Dec 2004 <nathan@codesourcery.com>
+
+// PR 18949. Forgot to convert from reference.
+// Origin: Volker Reichelt <reichelt@gcc.gnu.org>
+
+struct A
+{
+ void foo();
+};
+
+template<int> void bar(A& a)
+{
+ const_cast<A&>(a).foo();
+ static_cast<A&>(a).foo();
+ reinterpret_cast<A&>(a).foo();
+ ((A&)a).foo();
+}
+
+template void bar<0>(A& a);