From 5d73aa6323d0795b477d1725ed9e62fcb7e9494c Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Mon, 13 Sep 1999 00:35:00 +0000 Subject: call.c (implicit_conversion): Robustify. * call.c (implicit_conversion): Robustify. Handle OFFSET_REFs. * cvt.c (ocp_convert): Complete the from and destination types. Adjust warning about functions always being `true' in conditionals. * decl.c (duplicate_decls): Don't play funny games with abort. * error.c (dump_expr): Handle OVERLOADs. * spew.c (probe_obstack): Remove. * typeck.c (condition_conversion): Use perform_implicit_conversion. From-SVN: r29366 --- gcc/cp/ChangeLog | 10 ++++++++++ gcc/cp/call.c | 14 ++++++++++++++ gcc/cp/cvt.c | 12 +++++++++++- gcc/cp/decl.c | 8 ++------ gcc/cp/error.c | 1 + gcc/cp/spew.c | 25 ------------------------- gcc/cp/typeck.c | 2 +- gcc/testsuite/g++.old-deja/g++.mike/warn8.C | 6 +++--- gcc/testsuite/g++.old-deja/g++.pt/cond3.C | 25 +++++++++++++++++++++++++ 9 files changed, 67 insertions(+), 36 deletions(-) create mode 100644 gcc/testsuite/g++.old-deja/g++.pt/cond3.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 19812ea..9e953ed 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +1999-09-12 Mark Mitchell + + * call.c (implicit_conversion): Robustify. Handle OFFSET_REFs. + * cvt.c (ocp_convert): Complete the from and destination types. + Adjust warning about functions always being `true' in conditionals. + * decl.c (duplicate_decls): Don't play funny games with abort. + * error.c (dump_expr): Handle OVERLOADs. + * spew.c (probe_obstack): Remove. + * typeck.c (condition_conversion): Use perform_implicit_conversion. + 1999-09-12 Bernd Schmidt * cp-tree.h (auto_function, define_function): Adjust prototypes. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index ac0ad6b..12f4b9b 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -1151,6 +1151,20 @@ implicit_conversion (to, from, expr, flags) tree conv; struct z_candidate *cand; + /* Resolve expressions like `A::p' that we thought might become + pointers-to-members. */ + if (expr && TREE_CODE (expr) == OFFSET_REF) + { + expr = resolve_offset_ref (expr); + from = TREE_TYPE (expr); + } + + if (from == error_mark_node || to == error_mark_node + || expr == error_mark_node) + return NULL_TREE; + + /* Make sure both the FROM and TO types are complete so that + user-defined conversions are available. */ complete_type (from); complete_type (to); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 382a9b2..93d8a43 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -675,6 +675,9 @@ ocp_convert (type, expr, convtype, flags) || TREE_TYPE (e) == error_mark_node) return error_mark_node; + complete_type (type); + complete_type (TREE_TYPE (expr)); + if (TREE_READONLY_DECL_P (e)) e = decl_constant_value (e); @@ -742,10 +745,17 @@ ocp_convert (type, expr, convtype, flags) } if (code == BOOLEAN_TYPE) { + tree fn = NULL_TREE; + /* Common Ada/Pascal programmer's mistake. We always warn about this since it is so bad. */ if (TREE_CODE (expr) == FUNCTION_DECL) - cp_warning ("the address of `%D', will always be `true'", expr); + fn = expr; + else if (TREE_CODE (expr) == ADDR_EXPR + && TREE_CODE (TREE_OPERAND (expr, 0)) == FUNCTION_DECL) + fn = TREE_OPERAND (expr, 0); + if (fn) + cp_warning ("the address of `%D', will always be `true'", fn); return truthvalue_conversion (e); } return fold (convert_to_integer (type, e)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index b70d60d..08bf7eb 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3414,12 +3414,8 @@ duplicate_decls (newdecl, olddecl) if (DECL_SECTION_NAME (newdecl) == NULL_TREE) DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl); - /* Keep the old rtl since we can safely use it, unless it's the - call to abort() used for abstract virtuals. */ - if ((DECL_LANG_SPECIFIC (olddecl) - && !DECL_ABSTRACT_VIRTUAL_P (olddecl)) - || DECL_RTL (olddecl) != DECL_RTL (abort_fndecl)) - DECL_RTL (newdecl) = DECL_RTL (olddecl); + /* Keep the old rtl since we can safely use it. */ + DECL_RTL (newdecl) = DECL_RTL (olddecl); pop_obstacks (); } diff --git a/gcc/cp/error.c b/gcc/cp/error.c index c2a55e8..1d1716a 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1272,6 +1272,7 @@ dump_expr (t, nop) case FUNCTION_DECL: case TEMPLATE_DECL: case NAMESPACE_DECL: + case OVERLOAD: dump_decl (t, -1); break; diff --git a/gcc/cp/spew.c b/gcc/cp/spew.c index 8f853a8..ee9b70f 100644 --- a/gcc/cp/spew.c +++ b/gcc/cp/spew.c @@ -47,7 +47,6 @@ struct token { }; static int do_aggr PROTO((void)); -static int probe_obstack PROTO((struct obstack *, tree, unsigned int)); static void scan_tokens PROTO((unsigned int)); #ifdef SPEW_DEBUG @@ -198,30 +197,6 @@ scan_tokens (n) } } -/* Like _obstack_allocated_p, but stop after checking NLEVELS chunks. */ - -static int -probe_obstack (h, obj, nlevels) - struct obstack *h; - tree obj; - unsigned int nlevels; -{ - register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */ - register struct _obstack_chunk* plp; /* point to previous chunk if any */ - - lp = (h)->chunk; - /* We use >= rather than > since the object cannot be exactly at - the beginning of the chunk but might be an empty object exactly - at the end of an adjacent chunk. */ - for (; nlevels != 0 && lp != 0 && ((tree)lp >= obj || (tree)lp->limit < obj); - nlevels -= 1) - { - plp = lp->prev; - lp = plp; - } - return nlevels != 0 && lp != 0; -} - /* from lex.c: */ /* Value is 1 (or 2) if we should try to make the next identifier look like a typename (when it may be a local variable or a class variable). diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 195877c..f2be13a 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4336,7 +4336,7 @@ condition_conversion (expr) tree t; if (processing_template_decl) return expr; - t = cp_convert (boolean_type_node, expr); + t = perform_implicit_conversion (boolean_type_node, expr); t = fold (build1 (CLEANUP_POINT_EXPR, boolean_type_node, t)); return t; } diff --git a/gcc/testsuite/g++.old-deja/g++.mike/warn8.C b/gcc/testsuite/g++.old-deja/g++.mike/warn8.C index 3c61c8e..d9a4484 100644 --- a/gcc/testsuite/g++.old-deja/g++.mike/warn8.C +++ b/gcc/testsuite/g++.old-deja/g++.mike/warn8.C @@ -10,10 +10,10 @@ void test() { bool (foo::* pmf)() = &foo::test; bool (*pf)() = func; - if (A.test) ; // WARNING - + if (A.test) ; // ERROR - if (func) ; // WARNING - - if (bool(A.test)) ; // WARNING - - if (bool(func)) ; + if (bool(A.test)) ; // ERROR - + if (bool(func)) ; // WARNING - if (pmf) ; if (pf) ; } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/cond3.C b/gcc/testsuite/g++.old-deja/g++.pt/cond3.C new file mode 100644 index 0000000..f73a495 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.pt/cond3.C @@ -0,0 +1,25 @@ +// Build don't link: +// Origin: Loring Holden + +template +class REFptr { + public: + operator T* () const; +}; + +class CamFocus; +typedef REFptr CamFocusptr; + +class CamFocus { + protected: + static CamFocusptr _focus; + public : + static CamFocusptr &cur() { return _focus; } +}; + +void +test() +{ + if (CamFocus::cur()) { + } +} -- cgit v1.1