diff options
author | Richard Stallman <rms@gnu.org> | 1993-06-05 09:08:32 +0000 |
---|---|---|
committer | Richard Stallman <rms@gnu.org> | 1993-06-05 09:08:32 +0000 |
commit | 2df34974748c2d55cd28d5bf137f943bbdee0c71 (patch) | |
tree | 201282ea3d78e55af01134045127bd79792b1d82 | |
parent | 49ba557ea204dae80f6a847a0c9b5a276dd7d66e (diff) | |
download | gcc-2df34974748c2d55cd28d5bf137f943bbdee0c71.zip gcc-2df34974748c2d55cd28d5bf137f943bbdee0c71.tar.gz gcc-2df34974748c2d55cd28d5bf137f943bbdee0c71.tar.bz2 |
(convert_for_assignment): Allow conversion to union type
for pointer if the pointer could convert to the union member.
From-SVN: r4634
-rw-r--r-- | gcc/c-typeck.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 89a838f..d7bd4ad 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -4173,6 +4173,51 @@ convert_for_assignment (type, rhs, errtype, fundecl, funname, parmnum) pedwarn ("ANSI C prohibits argument conversion to union type"); return build1 (NOP_EXPR, type, rhs); } + else if (coder == POINTER_TYPE + && TREE_CODE (TREE_TYPE (memb_types)) == POINTER_TYPE) + { + tree memb_type = TREE_TYPE (memb_types); + register tree ttl = TREE_TYPE (memb_type); + register tree ttr = TREE_TYPE (rhstype); + + /* Any non-function converts to a [const][volatile] void * + and vice versa; otherwise, targets must be the same. + Meanwhile, the lhs target must have all the qualifiers of the rhs. */ + if (TYPE_MAIN_VARIANT (ttl) == void_type_node + || TYPE_MAIN_VARIANT (ttr) == void_type_node + || comp_target_types (memb_type, rhstype)) + { + /* Const and volatile mean something different for function types, + so the usual warnings are not appropriate. */ + if (TREE_CODE (ttr) != FUNCTION_TYPE + || TREE_CODE (ttl) != FUNCTION_TYPE) + { + if (! TYPE_READONLY (ttl) && TYPE_READONLY (ttr)) + warn_for_assignment ("%s discards `const' from pointer target type", + get_spelling (errtype), funname, parmnum); + if (! TYPE_VOLATILE (ttl) && TYPE_VOLATILE (ttr)) + warn_for_assignment ("%s discards `volatile' from pointer target type", + get_spelling (errtype), funname, parmnum); + } + else + { + /* Because const and volatile on functions are restrictions + that say the function will not do certain things, + it is okay to use a const or volatile function + where an ordinary one is wanted, but not vice-versa. */ + if (TYPE_READONLY (ttl) && ! TYPE_READONLY (ttr)) + warn_for_assignment ("%s makes `const *' function pointer from non-const", + get_spelling (errtype), funname, parmnum); + if (TYPE_VOLATILE (ttl) && ! TYPE_VOLATILE (ttr)) + warn_for_assignment ("%s makes `volatile *' function pointer from non-volatile", + get_spelling (errtype), funname, parmnum); + } + if (pedantic + && !(fundecl != 0 && DECL_IN_SYSTEM_HEADER (fundecl))) + pedwarn ("ANSI C prohibits argument conversion to union type"); + return build1 (NOP_EXPR, type, rhs); + } + } } } /* Conversions among pointers */ |