diff options
author | Martin Liska <mliska@suse.cz> | 2016-10-14 11:54:32 +0200 |
---|---|---|
committer | Martin Liska <marxin@gcc.gnu.org> | 2016-10-14 09:54:32 +0000 |
commit | a766d4d74da96bb308f22fd5c9a607740f76c2b9 (patch) | |
tree | 648929aa753753d3f27c6630f7000ed2b5d5e34d /gcc | |
parent | 57c4fbc64b6c15c43b60a7943422c9ff7010694d (diff) | |
download | gcc-a766d4d74da96bb308f22fd5c9a607740f76c2b9.zip gcc-a766d4d74da96bb308f22fd5c9a607740f76c2b9.tar.gz gcc-a766d4d74da96bb308f22fd5c9a607740f76c2b9.tar.bz2 |
Support only \0-terminated string in c_getstr and return
* fold-const.c (c_getstr): Support of properly \0-terminated
string constants. New argument is added.
* fold-const.h: New argument is added.
From-SVN: r241152
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/fold-const.c | 38 | ||||
-rw-r--r-- | gcc/fold-const.h | 2 |
3 files changed, 36 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fad5f2a..b907c66 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-10-14 Martin Liska <mliska@suse.cz> + + * fold-const.c (c_getstr): Support of properly \0-terminated + string constants. New argument is added. + * fold-const.h: New argument is added. + 2016-10-14 Kyrylo Tkachov <kyrylo.tkachov@arm.com> * config/aarch64/aarch64.c (aarch64_print_hint_for_core_or_arch): diff --git a/gcc/fold-const.c b/gcc/fold-const.c index e2e0554..89ed89d 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -14441,24 +14441,44 @@ fold_build_pointer_plus_hwi_loc (location_t loc, tree ptr, HOST_WIDE_INT off) } /* Return a char pointer for a C string if it is a string constant - or sum of string constant and integer constant. */ + or sum of string constant and integer constant. We only support + string constants properly terminated with '\0' character. + If STRLEN is a valid pointer, length (including terminating character) + of returned string is stored to the argument. */ const char * -c_getstr (tree src) +c_getstr (tree src, unsigned HOST_WIDE_INT *strlen) { tree offset_node; + if (strlen) + *strlen = 0; + src = string_constant (src, &offset_node); if (src == 0) - return 0; + return NULL; - if (offset_node == 0) - return TREE_STRING_POINTER (src); - else if (!tree_fits_uhwi_p (offset_node) - || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0) - return 0; + unsigned HOST_WIDE_INT offset = 0; + if (offset_node != NULL_TREE) + { + if (!tree_fits_uhwi_p (offset_node)) + return NULL; + else + offset = tree_to_uhwi (offset_node); + } + + unsigned HOST_WIDE_INT string_length = TREE_STRING_LENGTH (src); + const char *string = TREE_STRING_POINTER (src); + + /* Support only properly null-terminated strings. */ + if (string_length == 0 + || string[string_length - 1] != '\0' + || offset >= string_length) + return NULL; - return TREE_STRING_POINTER (src) + tree_to_uhwi (offset_node); + if (strlen) + *strlen = string_length - offset; + return string + offset; } #if CHECKING_P diff --git a/gcc/fold-const.h b/gcc/fold-const.h index 637e46b..bc22c88 100644 --- a/gcc/fold-const.h +++ b/gcc/fold-const.h @@ -182,7 +182,7 @@ extern bool expr_not_equal_to (tree t, const wide_int &); extern tree const_unop (enum tree_code, tree, tree); extern tree const_binop (enum tree_code, tree, tree, tree); extern bool negate_mathfn_p (combined_fn); -extern const char *c_getstr (tree); +extern const char *c_getstr (tree, unsigned HOST_WIDE_INT *strlen = NULL); /* Return OFF converted to a pointer offset type suitable as offset for POINTER_PLUS_EXPR. Use location LOC for this conversion. */ |