From: law Date: Thu, 4 Oct 2018 02:55:10 +0000 (+0000) Subject: * gimple-ssa-sprintf.c (format_string): Do not hardcode size of X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3c487f08f15c6a303941473f671c49bafaec8543;p=thirdparty%2Fgcc.git * gimple-ssa-sprintf.c (format_string): Do not hardcode size of target's wchar_t. * tree.c (get_typenode_from_name): Moved from fortran/trans-types.c. * tree.h (get_typenode_from_name): Prototype. * trans-types.c (get_typenode_from_name): Moved into gcc/tree.c. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@264833 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f365b249aeff..03bc5727c23d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-10-03 Jeff Law + + * gimple-ssa-sprintf.c (format_string): Do not hardcode size of + target's wchar_t. + * tree.c (get_typenode_from_name): Moved from fortran/trans-types.c. + * tree.h (get_typenode_from_name): Prototype. + 2018-10-03 Uros Bizjak * config/i386/i386.md (*cmp__i387): diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index d513f2a0c6a3..521247c2dcc7 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,7 @@ +2018-10-03 Jeff Law + + * trans-types.c (get_typenode_from_name): Moved into gcc/tree.c. + 2018-10-01 Paul Thomas PR fortran/65677 diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index 46f6d8c03a64..1a813eaf4d4f 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -218,43 +218,6 @@ get_int_kind_from_node (tree type) return -1; } -/* Return a typenode for the "standard" C type with a given name. */ -static tree -get_typenode_from_name (const char *name) -{ - if (name == NULL || *name == '\0') - return NULL_TREE; - - if (strcmp (name, "char") == 0) - return char_type_node; - if (strcmp (name, "unsigned char") == 0) - return unsigned_char_type_node; - if (strcmp (name, "signed char") == 0) - return signed_char_type_node; - - if (strcmp (name, "short int") == 0) - return short_integer_type_node; - if (strcmp (name, "short unsigned int") == 0) - return short_unsigned_type_node; - - if (strcmp (name, "int") == 0) - return integer_type_node; - if (strcmp (name, "unsigned int") == 0) - return unsigned_type_node; - - if (strcmp (name, "long int") == 0) - return long_integer_type_node; - if (strcmp (name, "long unsigned int") == 0) - return long_unsigned_type_node; - - if (strcmp (name, "long long int") == 0) - return long_long_integer_type_node; - if (strcmp (name, "long long unsigned int") == 0) - return long_long_unsigned_type_node; - - gcc_unreachable (); -} - static int get_int_kind_from_name (const char *name) { diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c index 88e952828e1c..471bfc45eb87 100644 --- a/gcc/gimple-ssa-sprintf.c +++ b/gcc/gimple-ssa-sprintf.c @@ -2179,7 +2179,19 @@ format_string (const directive &dir, tree arg, vr_values *) fmtresult res; /* Compute the range the argument's length can be in. */ - int count_by = dir.specifier == 'S' || dir.modifier == FMT_LEN_l ? 4 : 1; + int count_by = 1; + if (dir.specifier == 'S' || dir.modifier == FMT_LEN_l) + { + /* Get a node for a C type that will be the same size + as a wchar_t on the target. */ + tree node = get_typenode_from_name (MODIFIED_WCHAR_TYPE); + + /* Now that we have a suitable node, get the number of + bytes it occupies. */ + count_by = int_size_in_bytes (node); + gcc_checking_assert (count_by == 2 || count_by == 4); + } + fmtresult slen = get_string_length (arg, count_by); if (slen.range.min == slen.range.max && slen.range.min < HOST_WIDE_INT_MAX) diff --git a/gcc/tree.c b/gcc/tree.c index 748ece690ea4..d7dca77d2b2a 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -14408,6 +14408,43 @@ expr_type_first_operand_type_p (tree_code code) } } +/* Return a typenode for the "standard" C type with a given name. */ +tree +get_typenode_from_name (const char *name) +{ + if (name == NULL || *name == '\0') + return NULL_TREE; + + if (strcmp (name, "char") == 0) + return char_type_node; + if (strcmp (name, "unsigned char") == 0) + return unsigned_char_type_node; + if (strcmp (name, "signed char") == 0) + return signed_char_type_node; + + if (strcmp (name, "short int") == 0) + return short_integer_type_node; + if (strcmp (name, "short unsigned int") == 0) + return short_unsigned_type_node; + + if (strcmp (name, "int") == 0) + return integer_type_node; + if (strcmp (name, "unsigned int") == 0) + return unsigned_type_node; + + if (strcmp (name, "long int") == 0) + return long_integer_type_node; + if (strcmp (name, "long unsigned int") == 0) + return long_unsigned_type_node; + + if (strcmp (name, "long long int") == 0) + return long_long_integer_type_node; + if (strcmp (name, "long long unsigned int") == 0) + return long_long_unsigned_type_node; + + gcc_unreachable (); +} + /* List of pointer types used to declare builtins before we have seen their real declaration. diff --git a/gcc/tree.h b/gcc/tree.h index a0f24b61ef18..1e59dd59cf39 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -4987,6 +4987,9 @@ extern tree get_base_address (tree t); of EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ extern tree array_ref_element_size (tree); +/* Return a typenode for the "standard" C type with a given name. */ +extern tree get_typenode_from_name (const char *); + /* Return a tree representing the upper bound of the array mentioned in EXP, an ARRAY_REF or an ARRAY_RANGE_REF. */ extern tree array_ref_up_bound (tree);