aboutsummaryrefslogtreecommitdiff
path: root/gcc/convert.c
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-08-20 07:06:47 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-08-20 07:06:47 +0000
commit4b0d3cbe3ef315a363ce89a3264d4791090227fb (patch)
treeaa2d4a7cd3cb10db4c73c55192e37867c0a5455b /gcc/convert.c
parentccc014442a6731846c6e852a8ebbdc889d5c113b (diff)
downloadgcc-4b0d3cbe3ef315a363ce89a3264d4791090227fb.zip
gcc-4b0d3cbe3ef315a363ce89a3264d4791090227fb.tar.gz
gcc-4b0d3cbe3ef315a363ce89a3264d4791090227fb.tar.bz2
re PR c++/11946 (fun and merriment with enums as function arguments)
PR c++/11946 * convert.c (convert_to_integer): Use CONVERT_EXPR (instead of NOP_EXPR) when necessary. * c-common.c (c_common_signed_or_unsigned_type): Correctly handle types with precisions other than those given by native machine modes. PR c++/11684 * cp-tree.h (grok_op_properties): Change prototype. * decl.c (grok_op_properties): Add complain parameter. (grokfndecl): Pass it. * pt.c (tsubst_decl): Adjust accordingly. PR c++/10926 * decl.c (start_method): Return immediately if push_template_decl does not like the declaration. * pt.c (push_template_decl_real): Disallow member template destructors. PR c++/11036.C * cp-tree.h (add_binding): Add prototype. * class.c (add_method): Set TYPE_HAS_DESTRUCTOR if appropriate. (maybe_warn_about_overly_private_class): Use CLASSTYPE_DESTRUCTORS. (pushclass): Adjust call to set_identifier_type_value. * decl.c (add_binding): Give it external linkage. (push_local_binding): Adjust call to add_binding. (push_class_binding): Likewise. (set_identifier_type_value_with_scope): Change prototype. Use add_binding for global bindings. (set_identifier_type_value): Adjust accordingly. (pushtag): Likewise. (pushdecl): Use set_identifier_type_value, not set_identifier_type_value_with_scope. (pushdecl_namespace_level): Adjust calls to SET_IDENTIFIER_TYPE_VALUE to pass a DECL. (pushdecl_class_level): Likewise. (lookup_tag): Use select_decl. (select_decl): Improve comment. (record_builtin_type): Do not call pushdecl. (cxx_init_decl_processing): Do not call xref_tag for bad_alloc. (cp_finish_decl): Adjust call to set_identifier_type_value. (check_elaborated_type_specifier): Improve checks for invalid uses of typedefs. (xref_tag): Adjust call to check_elaborated_type_specifier. * decl2.c (grokclassfn): Do not set TYPE_HAS_DESTRUCTOR. * name-lookup.c (set_namespace_binding): Use add_binding. * parser.c (cp_parser_simple_type_specifier): Return a TYPE_DECL, rather than an IDENTIFIER_NODE, to represent built-in types, if requested by the caller. (cp_parser_postfix_expression): Adjust call. (cp_parser_type_specifier): Likewise. (cp_parser_elaborated_type_specifier): Adjust call to check_elaborated_type_specifier. * typeck2.c (build_functional_cast): Do not perform name lookups. PR c++/10717 * decl.c (expand_static_init): Remove unncessary code. PR c++/10926 * g++.dg/template/dtor2.C: New test. PR c++/11684 * g++.dg/template/operator1.C: New test. * g++.dg/parse/operator4.C: New test. PR c++/11946.C * g++.dg/expr/enum1.C: New test. * gcc.dg/c99-bool-1.c: Remove bogus warning. PR c++/11036.C * g++.dg/parse/elab2.C: New test. * g++.dg/parse/typedef4.C: Change error message. * g++.old-deja/g++.robertl/eb133.C: Remove bogus error markers. * g++.old-deja/g++.robertl/eb133a.C: Remove bogus error markers. * g++.old-deja/g++.robertl/eb133b.C: Remove bogus error markers. From-SVN: r70593
Diffstat (limited to 'gcc/convert.c')
-rw-r--r--gcc/convert.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/gcc/convert.c b/gcc/convert.c
index 5bab1c1..0d3a46c 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -349,7 +349,27 @@ convert_to_integer (tree type, tree expr)
we are truncating EXPR. */
else if (outprec >= inprec)
- return build1 (NOP_EXPR, type, expr);
+ {
+ enum tree_code code;
+
+ /* If the precision of the EXPR's type is K bits and the
+ destination mode has more bits, and the sign is changing,
+ it is not safe to use a NOP_EXPR. For example, suppose
+ that EXPR's type is a 3-bit unsigned integer type, the
+ TYPE is a 3-bit signed integer type, and the machine mode
+ for the types is 8-bit QImode. In that case, the
+ conversion necessitates an explicit sign-extension. In
+ the signed-to-unsigned case the high-order bits have to
+ be cleared. */
+ if (TREE_UNSIGNED (type) != TREE_UNSIGNED (TREE_TYPE (expr))
+ && (TYPE_PRECISION (TREE_TYPE (expr))
+ != GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (expr)))))
+ code = CONVERT_EXPR;
+ else
+ code = NOP_EXPR;
+
+ return build1 (code, type, expr);
+ }
/* If TYPE is an enumeral type or a type with a precision less
than the number of bits in its mode, do the conversion to the