[backport from gcc-4.8/trunk r185226, needed by PR53676 fix ] Date: Wed, 7 Mar 2012 13:22:57 +0100 (CET) From: Richard Guenther Subject: [PATCH] Do not use lang_hooks.types.type_for_size in signed_or_unsigned_type_for List-Archive: This makes us use build_nonstandard_integer_type in signed_or_unsigned_type_for and adjusts the function to return NULL_TREE for non-sensical inputs (only allowing pointer and integeral types). This way we make sure that the precision of the result type matches that of the input - something which fold-const.c definitely expects for example (it uses type_for_size itself if it doesn't). In the long run type_for_size should go - or it should be a wrapper that calls type_for_mode (int_mode_for_size ()) instead. I'm working towards that. Bootstrapped and tested on x86_64-unknown-linux-gnu for all languages. I get FAIL: gcc.dg/tree-ssa/pr31261.c scan-tree-dump-times original "return \\(char\\) -\\(unsigned char\\) c & 31;" 1 FAIL: gcc.dg/tree-ssa/pr31261.c scan-tree-dump-times original "return \\(int\\) \\(12 - \\(unsigned int\\) d\\) & 7;" 1 because we dump the unsigned type variant differently now. What do people think - adjust the testcase? Adjust how we pretty-print these non-standard integer types? Thanks, Richard. gcc/ 2012-03-12 Richard Guenther * tree.c (signed_or_unsigned_type_for): Use build_nonstandard_integer_type. (signed_type_for): Adjust documentation. (unsigned_type_for): Likewise. * tree-pretty-print.c (dump_generic_node): Use standard names for non-standard integer types if available. --- gcc-4.7.2/gcc/tree-pretty-print.c.~1~ 2011-12-23 23:07:16.000000000 +0100 +++ gcc-4.7.2/gcc/tree-pretty-print.c 2013-03-23 16:46:22.929243966 +0100 @@ -723,11 +723,41 @@ dump_generic_node (pretty_printer *buffe } else if (TREE_CODE (node) == INTEGER_TYPE) { - pp_string (buffer, (TYPE_UNSIGNED (node) - ? ""); + if (TYPE_PRECISION (node) == CHAR_TYPE_SIZE) + pp_string (buffer, (TYPE_UNSIGNED (node) + ? "unsigned char" + : "signed char")); + else if (TYPE_PRECISION (node) == SHORT_TYPE_SIZE) + pp_string (buffer, (TYPE_UNSIGNED (node) + ? "unsigned short" + : "signed short")); + else if (TYPE_PRECISION (node) == INT_TYPE_SIZE) + pp_string (buffer, (TYPE_UNSIGNED (node) + ? "unsigned int" + : "signed int")); + else if (TYPE_PRECISION (node) == LONG_TYPE_SIZE) + pp_string (buffer, (TYPE_UNSIGNED (node) + ? "unsigned long" + : "signed long")); + else if (TYPE_PRECISION (node) == LONG_LONG_TYPE_SIZE) + pp_string (buffer, (TYPE_UNSIGNED (node) + ? "unsigned long long" + : "signed long long")); + else if (TYPE_PRECISION (node) >= CHAR_TYPE_SIZE + && exact_log2 (TYPE_PRECISION (node))) + { + pp_string (buffer, (TYPE_UNSIGNED (node) ? "uint" : "int")); + pp_decimal_int (buffer, TYPE_PRECISION (node)); + pp_string (buffer, "_t"); + } + else + { + pp_string (buffer, (TYPE_UNSIGNED (node) + ? ""); + } } else if (TREE_CODE (node) == COMPLEX_TYPE) { --- gcc-4.7.2/gcc/tree.c.~1~ 2012-08-06 16:34:27.000000000 +0200 +++ gcc-4.7.2/gcc/tree.c 2013-03-23 16:46:22.929243966 +0100 @@ -10182,32 +10182,26 @@ widest_int_cst_value (const_tree x) return val; } -/* If TYPE is an integral type, return an equivalent type which is - unsigned iff UNSIGNEDP is true. If TYPE is not an integral type, - return TYPE itself. */ +/* If TYPE is an integral or pointer type, return an integer type with + the same precision which is unsigned iff UNSIGNEDP is true, or itself + if TYPE is already an integer type of signedness UNSIGNEDP. */ tree signed_or_unsigned_type_for (int unsignedp, tree type) { - tree t = type; - if (POINTER_TYPE_P (type)) - { - /* If the pointer points to the normal address space, use the - size_type_node. Otherwise use an appropriate size for the pointer - based on the named address space it points to. */ - if (!TYPE_ADDR_SPACE (TREE_TYPE (t))) - t = size_type_node; - else - return lang_hooks.types.type_for_size (TYPE_PRECISION (t), unsignedp); - } + if (TREE_CODE (type) == INTEGER_TYPE && TYPE_UNSIGNED (type) == unsignedp) + return type; - if (!INTEGRAL_TYPE_P (t) || TYPE_UNSIGNED (t) == unsignedp) - return t; + if (!INTEGRAL_TYPE_P (type) + && !POINTER_TYPE_P (type)) + return NULL_TREE; - return lang_hooks.types.type_for_size (TYPE_PRECISION (t), unsignedp); + return build_nonstandard_integer_type (TYPE_PRECISION (type), unsignedp); } -/* Returns unsigned variant of TYPE. */ +/* If TYPE is an integral or pointer type, return an integer type with + the same precision which is unsigned, or itself if TYPE is already an + unsigned integer type. */ tree unsigned_type_for (tree type) @@ -10215,7 +10209,9 @@ unsigned_type_for (tree type) return signed_or_unsigned_type_for (1, type); } -/* Returns signed variant of TYPE. */ +/* If TYPE is an integral or pointer type, return an integer type with + the same precision which is signed, or itself if TYPE is already a + signed integer type. */ tree signed_type_for (tree type)