+2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/3416
+ * call.c (build_conditional_expr): Recheck args after
+ conversions.
+ * cp-tree.h (build_conditional_expr): Move to correct file.
+ * typeck.c (decay_conversion): Diagnose any unknown types
+ reaching here.
+ (build_binary_op): Don't do initial decay or default
+ conversions on overloaded functions.
+ (build_static_cast): Don't do a decay conversion here.
+
2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
PR c++/3543
arg3 = decay_conversion (arg3);
arg3_type = TREE_TYPE (arg3);
+ if (arg2 == error_mark_node || arg3 == error_mark_node)
+ return error_mark_node;
+
/* [expr.cond]
After those conversions, one of the following shall hold:
extern tree build_vfield_ref PARAMS ((tree, tree));
extern tree build_scoped_method_call PARAMS ((tree, tree, tree, tree));
+extern tree build_conditional_expr PARAMS ((tree, tree, tree));
extern tree build_addr_func PARAMS ((tree));
extern tree build_call PARAMS ((tree, tree));
extern tree build_method_call PARAMS ((tree, tree, tree, tree, int));
extern tree build_x_unary_op PARAMS ((enum tree_code, tree));
extern tree unary_complex_lvalue PARAMS ((enum tree_code, tree));
extern tree build_x_conditional_expr PARAMS ((tree, tree, tree));
-extern tree build_conditional_expr PARAMS ((tree, tree, tree));
extern tree build_x_compound_expr PARAMS ((tree));
extern tree build_compound_expr PARAMS ((tree));
extern tree build_static_cast PARAMS ((tree, tree));
if (type == error_mark_node)
return error_mark_node;
+ if (type_unknown_p (exp))
+ {
+ incomplete_type_error (exp, TREE_TYPE (exp));
+ return error_mark_node;
+ }
+
/* Constants can be used directly unless they're not loadable. */
if (TREE_CODE (exp) == CONST_DECL)
exp = DECL_INITIAL (exp);
int common = 0;
/* Apply default conversions. */
+ op0 = orig_op0;
+ op1 = orig_op1;
+
if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
|| code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
|| code == TRUTH_XOR_EXPR)
{
- op0 = decay_conversion (orig_op0);
- op1 = decay_conversion (orig_op1);
+ if (!really_overloaded_fn (op0))
+ op0 = decay_conversion (op0);
+ if (!really_overloaded_fn (op1))
+ op1 = decay_conversion (op1);
}
else
{
- op0 = default_conversion (orig_op0);
- op1 = default_conversion (orig_op1);
+ if (!really_overloaded_fn (op0))
+ op0 = default_conversion (op0);
+ if (!really_overloaded_fn (op1))
+ op1 = default_conversion (op1);
}
/* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */
build_tree_list (NULL_TREE, expr),
TYPE_BINFO (type), LOOKUP_NORMAL)));
- expr = decay_conversion (expr);
intype = TREE_TYPE (expr);
/* FIXME handle casting to array type. */
+2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
+
+ * g++.old-deja/g++.other/cond7.C: New test.
+
2001-07-25 Nathan Sidwell <nathan@codesourcery.com>
* g++.old-deja/g++.other/optimize4.C: New test.
--- /dev/null
+// Build don't link:
+//
+// Copyright (C) 2001 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 24 Jul 2001 <nathan@codesourcery.com>
+
+// Bug 3416. We left some unchecked overloaded functions lying around.
+
+struct X
+{
+ void operator << (int);
+ void operator << (float);
+};
+
+void OVL1 (int);
+void OVL1 (float);
+
+void OVL2 (int);
+void OVL2 (float);
+
+X x;
+
+void foo (bool a)
+{
+ x << (a ? OVL1 : OVL2); // ERROR - incomplete type
+ a ? OVL1 : OVL2; // ERROR - incomplete type
+}