Hi!
This is an alternative approach in making STRING_CST semantics consistent. This means it makes STRING_CST used for literals and for initializers use exactly the same semantics. It makes sure that all STRING_CST have a TYPE_SIZE_UNIT, and that it is always larger than TREE_STRING_LENGTH, these and certain other properties are checked in varasm.c, so the currently observed consistency issues in the middle-end can be resolved. It depends on the following pre-condition patches: [PATCH] Use complete_array_type on flexible array member initializers https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01538.html PATCHv2] Call braced_list_to_string after array size is fixed https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01565.html [PATCHv2] Handle overlength strings in the C FE https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01566.html [PATCHv2] Handle overlength strings in C++ FE https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01567.html [PATCHv2] Handle overlength string literals in the fortan FE https://gcc.gnu.org/ml/gcc-patches/2018-08/msg01568.html The Ada and GO patches are no longer necessary. Bootstrapped and reg-tested on x86_64-pc-linux-gnu. Is it OK for trunk? Thanks Bernd.
2018-08-24 Bernd Edlinger <bernd.edlin...@hotmail.de> * varasm.c (compare_constant): Compare type size of STRING_CSTs. (get_constant_size): Don't make STRING_CSTs larger than they are. (check_string_literal): New check function for STRING_CSTs. (output_constant): Use it. Index: gcc/varasm.c =================================================================== --- gcc/varasm.c (revision 263807) +++ gcc/varasm.c (working copy) @@ -3146,7 +3146,9 @@ compare_constant (const tree t1, const tree t2) return FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1), TREE_FIXED_CST (t2)); case STRING_CST: - if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))) + if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)) + || int_size_in_bytes (TREE_TYPE (t1)) + != int_size_in_bytes (TREE_TYPE (t2))) return 0; return (TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2) @@ -3303,8 +3305,9 @@ get_constant_size (tree exp) HOST_WIDE_INT size; size = int_size_in_bytes (TREE_TYPE (exp)); - if (TREE_CODE (exp) == STRING_CST) - size = MAX (TREE_STRING_LENGTH (exp), size); + gcc_checking_assert (size >= 0); + gcc_checking_assert (TREE_CODE (exp) != STRING_CST + || size >= TREE_STRING_LENGTH (exp)); return size; } @@ -4774,6 +4777,30 @@ initializer_constant_valid_for_bitfield_p (tree va return false; } +/* Check if a STRING_CST fits into the field. + Tolerate only the case when the NUL termination + does not fit into the field. */ + +static bool +check_string_literal (tree string, unsigned HOST_WIDE_INT size) +{ + tree type = TREE_TYPE (string); + tree eltype = TREE_TYPE (type); + unsigned HOST_WIDE_INT elts = tree_to_uhwi (TYPE_SIZE_UNIT (eltype)); + unsigned HOST_WIDE_INT mem_size = tree_to_uhwi (TYPE_SIZE_UNIT (type)); + int len = TREE_STRING_LENGTH (string); + + if (elts != 1 && elts != 2 && elts != 4) + return false; + if (len < 0 || len % elts != 0) + return false; + if (size < (unsigned)len) + return false; + if (mem_size != size) + return false; + return true; +} + /* output_constructor outer state of relevance in recursive calls, typically for nested aggregate bitfields. */ @@ -4942,6 +4969,7 @@ output_constant (tree exp, unsigned HOST_WIDE_INT case STRING_CST: thissize = MIN ((unsigned HOST_WIDE_INT)TREE_STRING_LENGTH (exp), size); + gcc_checking_assert (check_string_literal (exp, size)); assemble_string (TREE_STRING_POINTER (exp), thissize); break; case VECTOR_CST: