2010-12-16 Andi Kleen H.J. Lu * varasm.c (section_flags_string): New. (get_section): Print more details on conflicting section flags. diff --git a/gcc/varasm.c b/gcc/varasm.c index ed44610..d91497c 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -268,6 +268,47 @@ get_noswitch_section (unsigned int flags, noswitch_section_callback callback) return sect; } +/* Return a string for section flags F. */ + +static char * +section_flags_string (unsigned int f) +{ + static const struct section_flag + { + const char *name; + unsigned int flag; + } + section_flags[] = + { + { "code", SECTION_CODE }, + { "write", SECTION_WRITE }, + { "debug", SECTION_DEBUG }, + { "linkonce", SECTION_LINKONCE }, + { "small", SECTION_SMALL }, + { "bss", SECTION_BSS }, + { "forget", SECTION_FORGET }, + { "merge", SECTION_MERGE }, + { "strings", SECTION_STRINGS }, + { "override", SECTION_OVERRIDE }, + { "tls", SECTION_TLS }, + { "common", SECTION_COMMON }, + { "unnamed", SECTION_UNNAMED}, + { "named", SECTION_NAMED }, + { "noswitch", SECTION_NOSWITCH } + }; + unsigned int i; + char *flag = NULL; + for (i = 0; i < ARRAY_SIZE (section_flags); i++) + if ((f & section_flags[i].flag) != 0) + { + if (flag) + flag = concat (flag, " ", section_flags[i].name, NULL); + else + flag = concat (section_flags[i].name, NULL); + } + return flag; +} + /* Return the named section structure associated with NAME. Create a new section with the given fields if no such structure exists. */ @@ -290,15 +331,24 @@ get_section (const char *name, unsigned int flags, tree decl) } else { + unsigned int oflags; + sect = *slot; - if ((sect->common.flags & ~SECTION_DECLARED) != flags + oflags = sect->common.flags & ~SECTION_DECLARED; + if (oflags != flags && ((sect->common.flags | flags) & SECTION_OVERRIDE) == 0) { + char *str; /* Sanity check user variables for flag changes. */ if (decl == 0) decl = sect->named.decl; gcc_assert (decl); error ("%+D causes a section type conflict", decl); + flags = (oflags ^ flags) & ~SECTION_OVERRIDE; + str = section_flags_string (flags); + inform (DECL_SOURCE_LOCATION (decl), + "new section declaration differs in: %s", str); + free (str); } } return sect;