This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 2/2] Improve reporting of section conflict errors
- From: Andi Kleen <andi at firstfloor dot org>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Andi Kleen <ak at linux dot intel dot com>
- Date: Thu, 16 Dec 2010 13:41:48 +0100
- Subject: [PATCH 2/2] Improve reporting of section conflict errors
- References: <1292503308-11258-1-git-send-email-andi@firstfloor.org>
From: Andi Kleen <ak@linux.intel.com>
When making large projects LTO clean section conflicts can be surprisingly
common. Currently they are hard to debug. This patch improves the error
reporting a bit by printing out what flags actually differ.
It's still not great -- better would be to print the other locations
that actually conflict too. But that would be more complicated.
Passes bootstrap and full test on x86_64-linux. Ok?
gcc/
2010-12-15 Andi Kleen <ak@linux.intel.com>
* varasm.c (section_print_flags): Add.
(get_section): Print more details on conflicting flags.
---
gcc/varasm.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 62 insertions(+), 1 deletions(-)
diff --git a/gcc/varasm.c b/gcc/varasm.c
index ed44610..f676255 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -268,6 +268,59 @@ get_noswitch_section (unsigned int flags, noswitch_section_callback callback)
return sect;
}
+/* Print section flags F into BUF */
+
+static char *
+section_print_flags (char *buf, unsigned f)
+{
+ static struct flag
+ {
+ const char *name;
+ unsigned flag;
+ unsigned mask;
+ } flags[] =
+ {
+ { "code", SECTION_CODE, 0 },
+ { "write", SECTION_WRITE, 0 },
+ { "debug", SECTION_DEBUG, 0},
+ { "linkonce", SECTION_LINKONCE, 0 },
+ { "small", SECTION_SMALL, 0 },
+ { "bss", SECTION_BSS, 0 },
+ { "forget", SECTION_FORGET, 0 },
+ { "merge", SECTION_MERGE, 0 },
+ { "strings", SECTION_STRINGS, 0 },
+ { "override", SECTION_OVERRIDE, 0 },
+ { "tls", SECTION_TLS, 0 },
+ { "common", SECTION_COMMON, 0 },
+ { "unnamed", SECTION_UNNAMED, SECTION_STYLE_MASK },
+ { "named", SECTION_NAMED, SECTION_STYLE_MASK },
+ { "noswitch", SECTION_NOSWITCH, SECTION_STYLE_MASK },
+ { NULL, 0, 0 }
+ };
+ struct flag *fl;
+ char *start = buf;
+
+ f &= ~SECTION_OVERRIDE;
+ buf[0] = 0;
+ for (fl = &flags[0]; fl->name; fl++)
+ {
+ unsigned mask = fl->mask;
+
+ if (mask == 0)
+ mask = 0xffffffff;
+ if ((f & mask) & fl->flag)
+ {
+ strcpy (buf, fl->name);
+ strcat (buf, " ");
+ buf += strlen (buf);
+ f &= ~fl->flag;
+ }
+ }
+ if (f)
+ sprintf (buf, "rest %x", f);
+ return start;
+}
+
/* Return the named section structure associated with NAME. Create
a new section with the given fields if no such structure exists. */
@@ -290,15 +343,23 @@ get_section (const char *name, unsigned int flags, tree decl)
}
else
{
+ unsigned 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 buf[1024];
+
/* 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);
+ inform (DECL_SOURCE_LOCATION (decl),
+ "New section declaration differs in: %s",
+ section_print_flags (buf, oflags ^ flags));
}
}
return sect;
--
1.7.1