static void output_constant_def_contents (rtx);
static void output_addressed_constants (tree);
static unsigned HOST_WIDE_INT output_constant (tree, unsigned HOST_WIDE_INT,
- unsigned int, bool);
+ unsigned int, bool, bool);
static void globalize_decl (tree);
static bool decl_readonly_section_1 (enum section_category);
#ifdef BSS_SECTION_ASM_OP
&& TREE_CODE (decl) == STRING_CST
&& TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
&& align <= 256
- && (len = int_size_in_bytes (TREE_TYPE (decl))) > 0
- && TREE_STRING_LENGTH (decl) >= len)
+ && (len = int_size_in_bytes (TREE_TYPE (decl))) >= 0
+ && TREE_STRING_LENGTH (decl) == len)
{
scalar_int_mode mode;
unsigned int modesize;
if (j == unit)
break;
}
- if (i == len - unit)
+ if (i == len - unit || (unit == 1 && i == len))
{
sprintf (name, "%s.str%d.%d", prefix,
modesize / 8, (int) (align / 8));
static void
assemble_variable_contents (tree decl, const char *name,
- bool dont_output_data)
+ bool dont_output_data, bool merge_strings)
{
/* Do any machine/system dependent processing of the object. */
#ifdef ASM_DECLARE_OBJECT_NAME
output_constant (DECL_INITIAL (decl),
tree_to_uhwi (DECL_SIZE_UNIT (decl)),
get_variable_align (decl),
- false);
+ false, merge_strings);
else
/* Leave space for it. */
assemble_zeros (tree_to_uhwi (DECL_SIZE_UNIT (decl)));
switch_to_section (sect);
if (align > BITS_PER_UNIT)
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
- assemble_variable_contents (decl, name, dont_output_data);
+ assemble_variable_contents (decl, name, dont_output_data,
+ (sect->common.flags & SECTION_MERGE)
+ && (sect->common.flags & SECTION_STRINGS));
if (asan_protected)
{
unsigned HOST_WIDE_INT int size
constant's alignment in bits. */
static void
-assemble_constant_contents (tree exp, const char *label, unsigned int align)
+assemble_constant_contents (tree exp, const char *label, unsigned int align,
+ bool merge_strings)
{
HOST_WIDE_INT size;
targetm.asm_out.declare_constant_name (asm_out_file, label, exp, size);
/* Output the value of EXP. */
- output_constant (exp, size, align, false);
+ output_constant (exp, size, align, false, merge_strings);
targetm.asm_out.decl_end ();
}
|| (VAR_P (decl) && DECL_IN_CONSTANT_POOL (decl))
? DECL_ALIGN (decl)
: symtab_node::get (decl)->definition_alignment ());
- switch_to_section (get_constant_section (exp, align));
+ section *sect = get_constant_section (exp, align);
+ switch_to_section (sect);
if (align > BITS_PER_UNIT)
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
- assemble_constant_contents (exp, XSTR (symbol, 0), align);
+ assemble_constant_contents (exp, XSTR (symbol, 0), align,
+ (sect->common.flags & SECTION_MERGE)
+ && (sect->common.flags & SECTION_STRINGS));
if (asan_protected)
{
HOST_WIDE_INT size = get_constant_size (exp);
static unsigned HOST_WIDE_INT
output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align,
- bool reverse)
+ bool reverse, bool merge_strings)
{
enum tree_code code;
unsigned HOST_WIDE_INT thissize;
break;
case COMPLEX_TYPE:
- output_constant (TREE_REALPART (exp), thissize / 2, align, reverse);
+ output_constant (TREE_REALPART (exp), thissize / 2, align,
+ reverse, false);
output_constant (TREE_IMAGPART (exp), thissize / 2,
min_align (align, BITS_PER_UNIT * (thissize / 2)),
- reverse);
+ reverse, false);
break;
case ARRAY_TYPE:
case CONSTRUCTOR:
return output_constructor (exp, size, align, reverse, NULL);
case STRING_CST:
- thissize
- = MIN ((unsigned HOST_WIDE_INT)TREE_STRING_LENGTH (exp), size);
+ thissize = (unsigned HOST_WIDE_INT)TREE_STRING_LENGTH (exp);
+ if (merge_strings
+ && (thissize == 0
+ || TREE_STRING_POINTER (exp) [thissize - 1] != '\0'))
+ thissize++;
gcc_checking_assert (check_string_literal (exp, size));
assemble_string (TREE_STRING_POINTER (exp), thissize);
break;
unsigned int nalign = MIN (align, GET_MODE_ALIGNMENT (inner));
int elt_size = GET_MODE_SIZE (inner);
output_constant (VECTOR_CST_ELT (exp, 0), elt_size, align,
- reverse);
+ reverse, false);
thissize = elt_size;
/* Static constants must have a fixed size. */
unsigned int nunits = VECTOR_CST_NELTS (exp).to_constant ();
for (unsigned int i = 1; i < nunits; i++)
{
output_constant (VECTOR_CST_ELT (exp, i), elt_size, nalign,
- reverse);
+ reverse, false);
thissize += elt_size;
}
break;
if (local->val == NULL_TREE)
assemble_zeros (fieldsize);
else
- fieldsize
- = output_constant (local->val, fieldsize, align2, local->reverse);
+ fieldsize = output_constant (local->val, fieldsize, align2,
+ local->reverse, false);
/* Count its size. */
local->total_bytes += fieldsize;
if (local->val == NULL_TREE)
assemble_zeros (fieldsize);
else
- fieldsize
- = output_constant (local->val, fieldsize, align2, local->reverse);
+ fieldsize = output_constant (local->val, fieldsize, align2,
+ local->reverse, false);
/* Count its size. */
local->total_bytes += fieldsize;
{
HOST_WIDE_INT size;
decl = SYMBOL_REF_DECL (symbol);
- assemble_constant_contents
- (DECL_INITIAL (decl), XSTR (symbol, 0), DECL_ALIGN (decl));
+ assemble_constant_contents (DECL_INITIAL (decl), XSTR (symbol, 0),
+ DECL_ALIGN (decl), false);
size = get_constant_size (DECL_INITIAL (decl));
offset += size;
{
HOST_WIDE_INT size;
decl = SYMBOL_REF_DECL (symbol);
- assemble_variable_contents (decl, XSTR (symbol, 0), false);
+ assemble_variable_contents (decl, XSTR (symbol, 0), false, false);
size = tree_to_uhwi (DECL_SIZE_UNIT (decl));
offset += size;
if ((flag_sanitize & SANITIZE_ADDRESS)