summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2001-10-09 15:42:44 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2001-10-09 15:42:44 +0000
commit1fab1557bc73bc5576ba36f58005f25f4d5074a2 (patch)
treee49040b8bab3a4dbe67305f23cb5674aab23f0b7 /gcc
parent88b5b080c3b9fe5cc480b9e7f201d692700e3460 (diff)
downloadgcc-1fab1557bc73bc5576ba36f58005f25f4d5074a2.tar.gz
* call.c (standard_conversion): Add bad conversion between
integers and pointers. (convert_like_real): Don't use convert_for_initialization for bad conversions; complain here and use cp_convert. (build_over_call): Don't handle bad conversions specially. (perform_implicit_conversion): Allow bad conversions. (can_convert_arg_bad): New fn. * cp-tree.h: Declare it. * typeck.c (convert_for_assignment): Use it. (ptr_reasonably_similar): Any target type is similar to void. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@46123 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog19
-rw-r--r--gcc/cp/call.c61
-rw-r--r--gcc/cp/cp-tree.h1
-rw-r--r--gcc/cp/typeck.c15
-rw-r--r--gcc/testsuite/g++.dg/ext/conv1.C16
5 files changed, 77 insertions, 35 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5b934e3f18b..4ab1f199637 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,20 @@
+2001-10-04 Jason Merrill <jason_merrill@redhat.com>
+
+ * call.c (standard_conversion): Add bad conversion between
+ integers and pointers.
+ (convert_like_real): Don't use convert_for_initialization for bad
+ conversions; complain here and use cp_convert.
+ (build_over_call): Don't handle bad conversions specially.
+ (perform_implicit_conversion): Allow bad conversions.
+ (can_convert_arg_bad): New fn.
+ * cp-tree.h: Declare it.
+ * typeck.c (convert_for_assignment): Use it.
+ (ptr_reasonably_similar): Any target type is similar to void.
+
+2001-10-02 Jason Merrill <jason_merrill@redhat.com>
+
+ * decl2.c (cxx_decode_option): Add 'else'.
+
2001-10-08 Alexandre Oliva <aoliva@redhat.com>
* Make-lang.in (CXX_OBJS): Added cp-lang.o.
@@ -238,7 +255,7 @@ Fri Sep 21 08:16:19 2001 J"orn Rennecke <amylaar@redhat.com>
CLASSTYPE_PURE_VIRTUALS.
(TYPE_RAISES_EXCEPTIONS): Map onto TYPE_BINFO.
* class.c (duplicate_tag_error): Remove TYPE_NONCOPIED_PARTS.
- (layout_class_type): Don't call fixup_inlin_methods here ...
+ (layout_class_type): Don't call fixup_inline_methods here ...
(finish_struct_1): ... call it here.
2001-09-04 Mark Mitchell <mark@codesourcery.com>
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 437d67cf5b8..43d2baf1fb1 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -745,6 +745,14 @@ standard_conversion (to, from, expr)
{
conv = build_conv (STD_CONV, to, conv);
}
+ else if ((tcode == INTEGER_TYPE && fcode == POINTER_TYPE)
+ || (tcode == POINTER_TYPE && fcode == INTEGER_TYPE))
+ {
+ /* For backwards brain damage compatibility, allow interconversion of
+ pointers and integers with a pedwarn. */
+ conv = build_conv (STD_CONV, to, conv);
+ ICS_BAD_FLAG (conv) = 1;
+ }
else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE)
{
enum tree_code ufcode = TREE_CODE (TREE_TYPE (from));
@@ -3750,9 +3758,10 @@ convert_like_real (convs, expr, fn, argnum, inner)
else if (TREE_CODE (t) == IDENTITY_CONV)
break;
}
- return convert_for_initialization
- (NULL_TREE, totype, expr, LOOKUP_NORMAL,
- "conversion", fn, argnum);
+ cp_pedwarn ("invalid conversion from `%T' to `%T'", TREE_TYPE (expr), totype);
+ if (fn)
+ cp_pedwarn (" initializing argument %P of `%D'", argnum, fn);
+ return cp_convert (totype, expr);
}
if (!inner)
@@ -4152,32 +4161,8 @@ build_over_call (cand, args, flags)
tree type = TREE_VALUE (parm);
conv = TREE_VEC_ELT (convs, i);
- if (ICS_BAD_FLAG (conv))
- {
- tree t = conv;
- val = TREE_VALUE (arg);
-
- for (; t; t = TREE_OPERAND (t, 0))
- {
- if (TREE_CODE (t) == USER_CONV
- || TREE_CODE (t) == AMBIG_CONV)
- {
- val = convert_like_with_context (t, val, fn, i - is_method);
- break;
- }
- else if (TREE_CODE (t) == IDENTITY_CONV)
- break;
- }
- val = convert_for_initialization
- (NULL_TREE, type, val, LOOKUP_NORMAL,
- "argument", fn, i - is_method);
- }
- else
- {
- val = TREE_VALUE (arg);
- val = convert_like_with_context
- (conv, TREE_VALUE (arg), fn, i - is_method);
- }
+ val = convert_like_with_context
+ (conv, TREE_VALUE (arg), fn, i - is_method);
if (PROMOTE_PROTOTYPES
&& INTEGRAL_TYPE_P (type)
@@ -5550,7 +5535,21 @@ can_convert_arg (to, from, arg)
return (t && ! ICS_BAD_FLAG (t));
}
-/* Convert EXPR to TYPE. Return the converted expression. */
+/* Like can_convert_arg, but allows dubious conversions as well. */
+
+int
+can_convert_arg_bad (to, from, arg)
+ tree to, from, arg;
+{
+ tree t = implicit_conversion (to, from, arg, LOOKUP_NORMAL);
+ return !!t;
+}
+
+/* Convert EXPR to TYPE. Return the converted expression.
+
+ Note that we allow bad conversions here because by the time we get to
+ this point we are committed to doing the conversion. If we end up
+ doing a bad conversion, convert_like will complain. */
tree
perform_implicit_conversion (type, expr)
@@ -5563,7 +5562,7 @@ perform_implicit_conversion (type, expr)
return error_mark_node;
conv = implicit_conversion (type, TREE_TYPE (expr), expr,
LOOKUP_NORMAL);
- if (!conv || ICS_BAD_FLAG (conv))
+ if (!conv)
{
cp_error ("could not convert `%E' to `%T'", expr, type);
return error_mark_node;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 116a2cd4a64..4f6bcabd788 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3489,6 +3489,7 @@ extern tree build_new_op PARAMS ((enum tree_code, int, tree, tree, tree));
extern tree build_op_delete_call PARAMS ((enum tree_code, tree, tree, int, tree));
extern int can_convert PARAMS ((tree, tree));
extern int can_convert_arg PARAMS ((tree, tree, tree));
+extern int can_convert_arg_bad PARAMS ((tree, tree, tree));
extern int enforce_access PARAMS ((tree, tree));
extern tree convert_default_arg PARAMS ((tree, tree, tree, int));
extern tree convert_arg_to_ellipsis PARAMS ((tree));
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index c57bb08ab3e..850ce8be826 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -6295,8 +6295,12 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
/* [expr.ass]
The expression is implicitly converted (clause _conv_) to the
- cv-unqualified type of the left operand. */
- if (!can_convert_arg (type, rhstype, rhs))
+ cv-unqualified type of the left operand.
+
+ We allow bad conversions here because by the time we get to this point
+ we are committed to doing the conversion. If we end up doing a bad
+ conversion, convert_like will complain. */
+ if (!can_convert_arg_bad (type, rhstype, rhs))
{
/* When -Wno-pmf-conversions is use, we just silently allow
conversions from pointers-to-members to plain pointers. If
@@ -6305,7 +6309,7 @@ convert_for_assignment (type, rhs, errtype, fndecl, parmnum)
&& TYPE_PTR_P (type)
&& TYPE_PTRMEMFUNC_P (rhstype))
rhs = cp_convert (strip_top_quals (type), rhs);
- else
+ else
{
/* If the right-hand side has unknown type, then it is an
overloaded function. Call instantiate_type to get error
@@ -6798,6 +6802,11 @@ ptr_reasonably_similar (to, from)
{
for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from))
{
+ /* Any target type is similar enough to void. */
+ if (TREE_CODE (to) == VOID_TYPE
+ || TREE_CODE (from) == VOID_TYPE)
+ return 1;
+
if (TREE_CODE (to) != TREE_CODE (from))
return 0;
diff --git a/gcc/testsuite/g++.dg/ext/conv1.C b/gcc/testsuite/g++.dg/ext/conv1.C
new file mode 100644
index 00000000000..4c0d848c8cc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/conv1.C
@@ -0,0 +1,16 @@
+// Test for backwards brain-damage compatibility with -fpermissive.
+// { dg-options "-fpermissive -w" }
+
+void f ();
+void f (int *);
+void g (int);
+
+int main ()
+{
+ void *v = 1234;
+ void (*p)() = v;
+ int i = v;
+ f (i);
+ f (v);
+ g (v);
+}