X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fc-convert.c;h=bf306c8ea2fe7e55be4e199a8a1322fc06a245d6;hb=300b0e0817a85c8c855f265eeb6e7bdea3160645;hp=8b783838b1c678989f1344b229e6fcdc1f27eed7;hpb=49d00087091a73bd5ed4e29ea8afd093cac6c58f;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/c-convert.c b/gcc/c-convert.c index 8b783838b1c..bf306c8ea2f 100644 --- a/gcc/c-convert.c +++ b/gcc/c-convert.c @@ -36,6 +36,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "c-tree.h" #include "langhooks.h" #include "toplev.h" +#include "target.h" /* Change of width--truncation and extension of integers or reals-- is represented with NOP_EXPR. Proper functioning of many things @@ -69,14 +70,25 @@ convert (tree type, tree expr) { tree e = expr; enum tree_code code = TREE_CODE (type); + const char *invalid_conv_diag; - if (type == TREE_TYPE (expr) - || TREE_CODE (expr) == ERROR_MARK - || code == ERROR_MARK || TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK) + if (type == error_mark_node + || expr == error_mark_node + || TREE_TYPE (expr) == error_mark_node) + return error_mark_node; + + if ((invalid_conv_diag + = targetm.invalid_conversion (TREE_TYPE (expr), type))) + { + error (invalid_conv_diag); + return error_mark_node; + } + + if (type == TREE_TYPE (expr)) return expr; if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr))) - return fold_build1 (NOP_EXPR, type, expr); + return fold_convert (type, expr); if (TREE_CODE (TREE_TYPE (expr)) == ERROR_MARK) return error_mark_node; if (TREE_CODE (TREE_TYPE (expr)) == VOID_TYPE) @@ -85,28 +97,11 @@ convert (tree type, tree expr) return error_mark_node; } if (code == VOID_TYPE) - return build1 (CONVERT_EXPR, type, e); -#if 0 - /* This is incorrect. A truncation can't be stripped this way. - Extensions will be stripped by the use of get_unwidened. */ - if (TREE_CODE (expr) == NOP_EXPR) - return convert (type, TREE_OPERAND (expr, 0)); -#endif + return fold_convert (type, e); if (code == INTEGER_TYPE || code == ENUMERAL_TYPE) return fold (convert_to_integer (type, e)); if (code == BOOLEAN_TYPE) - { - tree t = c_objc_common_truthvalue_conversion (expr); - if (TREE_CODE (t) == ERROR_MARK) - return t; - - /* If it returns a NOP_EXPR, we must fold it here to avoid - infinite recursion between fold () and convert (). */ - if (TREE_CODE (t) == NOP_EXPR) - return fold_build1 (NOP_EXPR, type, TREE_OPERAND (t, 0)); - else - return fold_build1 (NOP_EXPR, type, t); - } + return fold_convert (type, c_objc_common_truthvalue_conversion (expr)); if (code == POINTER_TYPE || code == REFERENCE_TYPE) return fold (convert_to_pointer (type, e)); if (code == REAL_TYPE)