aboutsummaryrefslogtreecommitdiff
path: root/gold/symtab.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2011-02-05 01:52:40 +0000
committerIan Lance Taylor <ian@airs.com>2011-02-05 01:52:40 +0000
commit55382fb77a791c87165d4a3f65a53dc00c80959c (patch)
treef91a1fb585be2a513643fe6e70b0da6bd7a87fa9 /gold/symtab.cc
parent4d0fd3f682f44c4e80faae2ed5c8904d0bf784d2 (diff)
downloadfsf-binutils-gdb-55382fb77a791c87165d4a3f65a53dc00c80959c.zip
fsf-binutils-gdb-55382fb77a791c87165d4a3f65a53dc00c80959c.tar.gz
fsf-binutils-gdb-55382fb77a791c87165d4a3f65a53dc00c80959c.tar.bz2
* symtab.cc (Odr_violation_compare::operator()): Sort by just the
filename.
Diffstat (limited to 'gold/symtab.cc')
-rw-r--r--gold/symtab.cc40
1 files changed, 28 insertions, 12 deletions
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 8531911..cb650fb 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -3012,11 +3012,12 @@ Symbol_table::print_stats() const
// We check for ODR violations by looking for symbols with the same
// name for which the debugging information reports that they were
// defined in different source locations. When comparing the source
-// location, we consider instances with the same base filename and
-// line number to be the same. This is because different object
-// files/shared libraries can include the same header file using
-// different paths, and we don't want to report an ODR violation in
-// that case.
+// location, we consider instances with the same base filename to be
+// the same. This is because different object files/shared libraries
+// can include the same header file using different paths, and
+// different optimization settings can make the line number appear to
+// be a couple lines off, and we don't want to report an ODR violation
+// in those cases.
// This struct is used to compare line information, as returned by
// Dwarf_line_info::one_addr2line. It implements a < comparison
@@ -3027,13 +3028,28 @@ struct Odr_violation_compare
bool
operator()(const std::string& s1, const std::string& s2) const
{
- std::string::size_type pos1 = s1.rfind('/');
- std::string::size_type pos2 = s2.rfind('/');
- if (pos1 == std::string::npos
- || pos2 == std::string::npos)
- return s1 < s2;
- return s1.compare(pos1, std::string::npos,
- s2, pos2, std::string::npos) < 0;
+ // Inputs should be of the form "dirname/filename:linenum" where
+ // "dirname/" is optional. We want to compare just the filename.
+
+ // Find the last '/' and ':' in each string.
+ std::string::size_type s1begin = s1.rfind('/');
+ std::string::size_type s2begin = s2.rfind('/');
+ std::string::size_type s1end = s1.rfind(':');
+ std::string::size_type s2end = s2.rfind(':');
+ // If there was no '/' in a string, start at the beginning.
+ if (s1begin == std::string::npos)
+ s1begin = 0;
+ if (s2begin == std::string::npos)
+ s2begin = 0;
+ // If the ':' appeared in the directory name, compare to the end
+ // of the string.
+ if (s1end < s1begin)
+ s1end = s1.size();
+ if (s2end < s2begin)
+ s2end = s2.size();
+ // Compare takes lengths, not end indices.
+ return s1.compare(s1begin, s1end - s1begin,
+ s2, s2begin, s2end - s2begin) < 0;
}
};