aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/call.c14
-rw-r--r--gcc/cp/cvt.c12
-rw-r--r--gcc/cp/decl.c8
-rw-r--r--gcc/cp/error.c1
-rw-r--r--gcc/cp/spew.c25
-rw-r--r--gcc/cp/typeck.c2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/warn8.C6
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/cond3.C25
9 files changed, 67 insertions, 36 deletions
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 <mark@codesourcery.com>
+
+ * 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 <bernds@cygnus.co.uk>
* 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 <lsh@lsh.cs.brown.edu>
+
+template <class T>
+class REFptr {
+ public:
+ operator T* () const;
+};
+
+class CamFocus;
+typedef REFptr<CamFocus> CamFocusptr;
+
+class CamFocus {
+ protected:
+ static CamFocusptr _focus;
+ public :
+ static CamFocusptr &cur() { return _focus; }
+};
+
+void
+test()
+{
+ if (CamFocus::cur()) {
+ }
+}