[gcc] 2014-04-22 Rohit PR target/60158 * varasm.c (output_constant_pool_1): Remove unrequired ALIGN argument. Use actual alignment value in output_constant_pool_1 to emit ".fixup" section. [gcc/testsuite] 2014-04-22 Rohit PR target/60158 * gcc.target/powerpc/pr60158.c: New test. Check if ".fixup" section gets emitted for ".data.rel.ro.local" section. Index: gcc/testsuite/gcc.target/powerpc/pr60158.c =================================================================== --- gcc/testsuite/gcc.target/powerpc/pr60158.c (revision 0) +++ gcc/testsuite/gcc.target/powerpc/pr60158.c (revision 0) @@ -0,0 +1,91 @@ +/* { dg-do compile } */ +/* { dg-skip-if "not an SPE target" { ! powerpc_spe_nocache } { "*" } { "" } } */ +/* { dg-options "-mcpu=8548 -mno-spe -mfloat-gprs=double -Os -fdata-sections -fpic -mrelocatable" } */ + +#define NULL 0 +int func (int val); +void *func2 (void *ptr); + +static const char *ifs; +static char map[256]; + +typedef struct { +/* + * None of these fields are used, but removing any + * of them makes the problem go away. + */ + char *data; + int length; + int maxlen; + int quote; +} o_string; + +#define NULL_O_STRING {NULL,0,0,0} + +static int parse_stream (void *dest, void *ctx) +{ + int ch = func (0), m; + + while (ch != -1) { + m = map[ch]; + if (ch != '\n') + func2(dest); + + ctx = func2 (ctx); + if (!func (0)) + return 0; + if (m != ch) { + func2 ("htns"); + break; + } + } + return -1; +} + +static void mapset (const char *set, int code) +{ + const char *s; + for (s=set; *s; s++) map[(int)*s] = code; +} + +static void update_ifs_map(void) +{ + /* char *ifs and char map[256] are both globals. */ + ifs = func2 ("abc"); + if (ifs == NULL) ifs="def"; + + func2 (map); + { + char subst[2] = {4, 0}; + mapset (subst, 3); + } + mapset (";&|#", 1); +} + +int parse_stream_outer (int flag) +{ + int blah; + o_string temp=NULL_O_STRING; + int rcode; + + do { + update_ifs_map (); + func2 (&blah); /* a memory clobber works as well */ + rcode = parse_stream (&temp, NULL); + func2 ("aoeu"); + if (func (0) != 0) { + func2 (NULL); + } + } while (rcode != -1); + return 0; +} + +/* { dg-final { if ![file exists pr60158.s] { fail "pr60158.c (compile)"; return; } } } */ + +/* { dg-final { set c_rel [llength [grep pr60158.s \\.data\\.rel\\.ro\\.local]] } } */ +/* { dg-final { set c_fix [llength [grep pr60158.s \\.fixup]] } } */ +/* { dg-final { if [string match $c_rel $c_fix] \{ } } */ +/* { dg-final { pass "pr60158.c (passed)" } } */ +/* { dg-final { \} else \{ } } */ +/* { dg-final { fail "pr60158.c (.fixup table entries not generated for .data.rel.ro.local section)" } } */ +/* { dg-final { \} } } */ Index: gcc/varasm.c =================================================================== --- gcc/varasm.c (revision 209534) +++ gcc/varasm.c (working copy) @@ -3723,8 +3723,7 @@ output_constant_pool_2 (enum machine_mod giving it ALIGN bits of alignment. */ static void -output_constant_pool_1 (struct constant_descriptor_rtx *desc, - unsigned int align) +output_constant_pool_1 (struct constant_descriptor_rtx *desc) { rtx x, tmp; @@ -3762,23 +3761,23 @@ output_constant_pool_1 (struct constant_ #ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY ASM_OUTPUT_SPECIAL_POOL_ENTRY (asm_out_file, x, desc->mode, - align, desc->labelno, done); + desc->align, desc->labelno, done); #endif - assemble_align (align); + assemble_align (desc->align); /* Output the label. */ targetm.asm_out.internal_label (asm_out_file, "LC", desc->labelno); /* Output the data. */ - output_constant_pool_2 (desc->mode, x, align); + output_constant_pool_2 (desc->mode, x, desc->align); /* Make sure all constants in SECTION_MERGE and not SECTION_STRINGS sections have proper size. */ - if (align > GET_MODE_BITSIZE (desc->mode) + if (desc->align > GET_MODE_BITSIZE (desc->mode) && in_section && (in_section->common.flags & SECTION_MERGE)) - assemble_align (align); + assemble_align (desc->align); #ifdef ASM_OUTPUT_SPECIAL_POOL_ENTRY done: @@ -3886,7 +3885,7 @@ output_constant_pool_contents (struct rt { switch_to_section (targetm.asm_out.select_rtx_section (desc->mode, desc->constant, desc->align)); - output_constant_pool_1 (desc, desc->align); + output_constant_pool_1 (desc); } } } @@ -7120,7 +7119,7 @@ output_object_block (struct object_block if (CONSTANT_POOL_ADDRESS_P (symbol)) { desc = SYMBOL_REF_CONSTANT (symbol); - output_constant_pool_1 (desc, 1); + output_constant_pool_1 (desc); offset += GET_MODE_SIZE (desc->mode); } else if (TREE_CONSTANT_POOL_ADDRESS_P (symbol))