From 0863decda9aef33b8073c13f6d27826b881e6280 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Wed, 3 Oct 2018 20:55:10 -0600 Subject: [PATCH] gimple-ssa-sprintf.c (format_string): Do not hardcode size of target's wchar_t. * 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. From-SVN: r264833 --- gcc/ChangeLog | 7 +++++++ gcc/fortran/ChangeLog | 4 ++++ gcc/fortran/trans-types.c | 37 ------------------------------------- gcc/gimple-ssa-sprintf.c | 14 +++++++++++++- gcc/tree.c | 37 +++++++++++++++++++++++++++++++++++++ gcc/tree.h | 3 +++ 6 files changed, 64 insertions(+), 38 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f365b249aef..03bc5727c23 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 d513f2a0c6a..521247c2dcc 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 46f6d8c03a6..1a813eaf4d4 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 88e952828e1..471bfc45eb8 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 748ece690ea..d7dca77d2b2 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 a0f24b61ef1..1e59dd59cf3 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); -- 2.11.4.GIT