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
This commit is contained in:
Mark Mitchell 1999-09-13 00:35:00 +00:00 committed by Mark Mitchell
parent b7cf61b5b3
commit 5d73aa6323
9 changed files with 67 additions and 36 deletions

View File

@ -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.

View File

@ -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);

View File

@ -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));

View File

@ -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 ();
}

View File

@ -1272,6 +1272,7 @@ dump_expr (t, nop)
case FUNCTION_DECL:
case TEMPLATE_DECL:
case NAMESPACE_DECL:
case OVERLOAD:
dump_decl (t, -1);
break;

View File

@ -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).

View File

@ -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;
}

View File

@ -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) ;
}

View File

@ -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()) {
}
}