diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-10-09 15:42:44 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-10-09 15:42:44 +0000 |
commit | 1fab1557bc73bc5576ba36f58005f25f4d5074a2 (patch) | |
tree | e49040b8bab3a4dbe67305f23cb5674aab23f0b7 /gcc | |
parent | 88b5b080c3b9fe5cc480b9e7f201d692700e3460 (diff) | |
download | gcc-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/ChangeLog | 19 | ||||
-rw-r--r-- | gcc/cp/call.c | 61 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 1 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 15 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/ext/conv1.C | 16 |
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); +} |