From b4ce9dedd7e0a7dea32d251e660a885a9fd7836a Mon Sep 17 00:00:00 2001 From: mmitchel Date: Sat, 14 Feb 2004 00:49:15 +0000 Subject: [PATCH] PR c++/14122 * cp-tree.h (delete_sanity): Change prototype. * decl2.c (delete_sanity): Make doing_vec a bool, not an int. Remove dead code. Adjust code to warn about deleting an array. * typekc.c (decay_conversion): Use build_address and build_nop. PR c++/14108 * search.c (accessible_p): Do not check access in thunks. PR c++/14122 * g++.dg/template/array4.C: New test. PR c++/14108 * g++.dg/inherit/thunk2.C: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@77786 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 9 +++++++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/decl2.c | 31 +++++++++++-------------------- gcc/cp/search.c | 8 +++++++- gcc/cp/typeck.c | 7 +------ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/g++.dg/inherit/thunk2.C | 19 +++++++++++++++++++ gcc/testsuite/g++.dg/template/array4.C | 11 +++++++++++ 8 files changed, 65 insertions(+), 28 deletions(-) create mode 100644 gcc/testsuite/g++.dg/inherit/thunk2.C create mode 100644 gcc/testsuite/g++.dg/template/array4.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 89d8edc8d81..572b774f7aa 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,14 @@ 2004-02-13 Mark Mitchell + PR c++/14122 + * cp-tree.h (delete_sanity): Change prototype. + * decl2.c (delete_sanity): Make doing_vec a bool, not an int. + Remove dead code. Adjust code to warn about deleting an array. + * typekc.c (decay_conversion): Use build_address and build_nop. + + PR c++/14108 + * search.c (accessible_p): Do not check access in thunks. + PR c++/14083 * call.c (build_conditional_expr): Call force_rvalue on the non-void operand in the case that one result is a throw-expression diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ce826afad90..0097c42f288 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3709,7 +3709,7 @@ extern void maybe_retrofit_in_chrg (tree); extern void maybe_make_one_only (tree); extern void grokclassfn (tree, tree, enum overload_flags, tree); extern tree grok_array_decl (tree, tree); -extern tree delete_sanity (tree, tree, int, int); +extern tree delete_sanity (tree, tree, bool, int); extern tree check_classfn (tree, tree, bool); extern void check_member_template (tree); extern tree grokfield (tree, tree, tree, tree, tree); diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 07acd139f32..d5ee526381c 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -432,18 +432,14 @@ grok_array_decl (tree array_expr, tree index_exp) /* Given the cast expression EXP, checking out its validity. Either return an error_mark_node if there was an unavoidable error, return a cast to void for trying to delete a pointer w/ the value 0, or return the - call to delete. If DOING_VEC is 1, we handle things differently - for doing an array delete. If DOING_VEC is 2, they gave us the - array size as an argument to delete. + call to delete. If DOING_VEC is true, we handle things differently + for doing an array delete. Implements ARM $5.3.4. This is called from the parser. */ tree -delete_sanity (tree exp, tree size, int doing_vec, int use_global_delete) +delete_sanity (tree exp, tree size, bool doing_vec, int use_global_delete) { tree t, type; - /* For a regular vector delete (aka, no size argument) we will pass - this down as a NULL_TREE into build_vec_delete. */ - tree maxindex = NULL_TREE; if (exp == error_mark_node) return exp; @@ -457,6 +453,12 @@ delete_sanity (tree exp, tree size, int doing_vec, int use_global_delete) } exp = convert_from_reference (exp); + + /* An array can't have been allocated by new, so complain. */ + if (TREE_CODE (exp) == VAR_DECL + && TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE) + warning ("deleting array `%#D'", exp); + t = build_expr_type_conversion (WANT_POINTER, exp, true); if (t == NULL_TREE || t == error_mark_node) @@ -466,12 +468,6 @@ delete_sanity (tree exp, tree size, int doing_vec, int use_global_delete) return error_mark_node; } - if (doing_vec == 2) - { - maxindex = cp_build_binary_op (MINUS_EXPR, size, integer_one_node); - pedwarn ("anachronistic use of array size in vector delete"); - } - type = TREE_TYPE (t); /* As of Valley Forge, you can delete a pointer to const. */ @@ -490,18 +486,13 @@ delete_sanity (tree exp, tree size, int doing_vec, int use_global_delete) doing_vec = 0; } - /* An array can't have been allocated by new, so complain. */ - if (TREE_CODE (t) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL - && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == ARRAY_TYPE) - warning ("deleting array `%#D'", TREE_OPERAND (t, 0)); - /* Deleting a pointer with the value zero is valid and has no effect. */ if (integer_zerop (t)) return build1 (NOP_EXPR, void_type_node, t); if (doing_vec) - return build_vec_delete (t, maxindex, sfk_deleting_destructor, + return build_vec_delete (t, /*maxindex=*/NULL_TREE, + sfk_deleting_destructor, use_global_delete); else return build_delete (type, t, sfk_deleting_destructor, diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 08836f0b82d..1b8c8c8afe4 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -905,6 +905,7 @@ accessible_p (tree type, tree decl) { tree binfo; tree t; + tree scope; access_kind access; /* Nonzero if it's OK to access DECL if it has protected @@ -916,6 +917,11 @@ accessible_p (tree type, tree decl) if (!TYPE_P (context_for_name_lookup (decl))) return 1; + /* There is no need to perform access checks inside a thunk. */ + scope = current_scope (); + if (scope && DECL_THUNK_P (scope)) + return 1; + /* In a template declaration, we cannot be sure whether the particular specialization that is instantiated will be a friend or not. Therefore, all access checks are deferred until @@ -958,7 +964,7 @@ accessible_p (tree type, tree decl) /* Now, loop through the classes of which we are a friend. */ if (!protected_ok) - protected_ok = friend_accessible_p (current_scope (), decl, binfo); + protected_ok = friend_accessible_p (scope, decl, binfo); /* Standardize the binfo that access_in_type will use. We don't need to know what path was chosen from this point onwards. */ diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 02858486b46..919d3d75c5b 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -1371,14 +1371,9 @@ decay_conversion (tree exp) if (TREE_CODE (exp) == VAR_DECL) { - /* ??? This is not really quite correct - in that the type of the operand of ADDR_EXPR - is not the target type of the type of the ADDR_EXPR itself. - Question is, can this lossage be avoided? */ - adr = build1 (ADDR_EXPR, ptrtype, exp); if (!cxx_mark_addressable (exp)) return error_mark_node; - TREE_CONSTANT (adr) = staticp (exp); + adr = build_nop (ptrtype, build_address (exp)); TREE_SIDE_EFFECTS (adr) = 0; /* Default would be, same as EXP. */ return adr; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dd136645c6d..0b1289d2412 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,11 @@ 2004-02-13 Mark Mitchell + PR c++/14122 + * g++.dg/template/array4.C: New test. + + PR c++/14108 + * g++.dg/inherit/thunk2.C: New test. + PR c++/14083 * g++.dg/eh/cond2.C: New test. diff --git a/gcc/testsuite/g++.dg/inherit/thunk2.C b/gcc/testsuite/g++.dg/inherit/thunk2.C new file mode 100644 index 00000000000..094891c7a14 --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/thunk2.C @@ -0,0 +1,19 @@ +// PR c++/14108 + +class ClassC { +public: + ~ClassC(); +}; + +class ClassA { + virtual ClassC f(); +}; + +class ClassB : public virtual ClassA { + virtual ClassC f(); +}; + +ClassC ClassB::f() { + return ClassC(); +} + diff --git a/gcc/testsuite/g++.dg/template/array4.C b/gcc/testsuite/g++.dg/template/array4.C new file mode 100644 index 00000000000..c72782b10ee --- /dev/null +++ b/gcc/testsuite/g++.dg/template/array4.C @@ -0,0 +1,11 @@ +// PR c++/14122 + +extern const char str[]; + +template +struct A +{ + template void foo(); +}; + +template class A; -- 2.11.4.GIT