From e8c66fe0e19849b41b227666405de82bf3391e5f Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Tue, 14 Dec 2004 15:39:12 +0000 Subject: [PATCH] re PR c++/18949 (trouble with const_cast in templates) cp: PR c++/18949 * pt.c (tsubst_copy_and_build): 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 --- gcc/cp/ChangeLog | 9 +++++++++ gcc/cp/pt.c | 7 +++++-- gcc/cp/typeck.c | 8 ++++---- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/template/cast1.C | 22 ++++++++++++++++++++++ 5 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/cast1.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 86610ec2db61..1dd91a12f17e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,12 @@ +2004-12-14 Nathan Sidwell + + PR c++/18949 + * pt.c (tsubst_copy_and_build): 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 * parser.c (cp_parser_uncommitted_to_tentative_parse_p): New function. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6e34ba6926cf..5da280610b42 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 74380d36a92b..9d347c299d19 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 eaebf8a29ad2..d94cb679d0eb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-12-14 Nathan Sidwell + + PR c++/18949 + * g++.dg/template/cast1.C: New. + 2004-12-13 Richard Henderson * 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 000000000000..fca3511e2e95 --- /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 + +// PR 18949. Forgot to convert from reference. +// Origin: Volker Reichelt + +struct A +{ + void foo(); +}; + +template void bar(A& a) +{ + const_cast(a).foo(); + static_cast(a).foo(); + reinterpret_cast(a).foo(); + ((A&)a).foo(); +} + +template void bar<0>(A& a);