From: Petr Machata Date: Fri, 27 Aug 2010 14:31:57 +0000 (+0200) Subject: dwarflint: Add a check for duplicate DW_TAG_variable entries X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b9cff913a06e20bf4bce76fd79aa5a4ac1ec25ea;p=thirdparty%2Felfutils.git dwarflint: Add a check for duplicate DW_TAG_variable entries - and a test case --- diff --git a/dwarflint/Makefile.am b/dwarflint/Makefile.am index cfdd308a1..f9bbefb7a 100644 --- a/dwarflint/Makefile.am +++ b/dwarflint/Makefile.am @@ -66,9 +66,11 @@ dwarflint_SOURCES = \ check_range_out_of_scope.cc \ check_expected_trees.cc \ check_dups_abstract_origin.cc \ + check_duplicate_DW_tag_variable.cc \ ../src/dwarfstrings.c -TESTS = tests/run-debug_abbrev-duplicate-attribute.sh +TESTS = tests/run-debug_abbrev-duplicate-attribute.sh \ + tests/run-check_duplicate_DW_tag_variable.sh EXTRA_DIST = tests/run-debug_abbrev-duplicate-attribute.sh tests/run-debug_abbrev-duplicate-attribute.bz2 diff --git a/dwarflint/check_duplicate_DW_tag_variable.cc b/dwarflint/check_duplicate_DW_tag_variable.cc new file mode 100644 index 000000000..799aa1b2e --- /dev/null +++ b/dwarflint/check_duplicate_DW_tag_variable.cc @@ -0,0 +1,143 @@ +/* + Copyright (C) 2010 Red Hat, Inc. + This file is part of Red Hat elfutils. + + Red Hat elfutils is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by the + Free Software Foundation; version 2 of the License. + + Red Hat elfutils is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License along + with Red Hat elfutils; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. + + Red Hat elfutils is an included package of the Open Invention Network. + An included package of the Open Invention Network is a package for which + Open Invention Network licensees cross-license their patents. No patent + license is granted, either expressly or impliedly, by designation as an + included package. Should you wish to participate in the Open Invention + Network licensing program, please visit www.openinventionnetwork.com + . */ + +// Implements a check for: +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39524 +// (duplicate variable declaration) +// And for: +// https://fedorahosted.org/pipermail/elfutils-devel/2010-July/001497.html +// (variable having both decl and defn in one scope) + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "highlevel_check.hh" +#include "../src/dwarfstrings.h" +#include "all-dies-it.hh" +#include "pri.hh" +#include "messages.h" +#include + +using elfutils::dwarf; + +namespace +{ + class check_duplicate_DW_tag_variable + : public highlevel_check + { + struct varinfo + { + dwarf::debug_info_entry::children_type::const_iterator decl, def; + + explicit varinfo (dwarf::debug_info_entry::children_type const &children) + : decl (children.end ()) + , def (children.end ()) + {} + + varinfo (varinfo const &other) + : decl (other.decl) + , def (other.def) + {} + }; + + public: + static checkdescriptor descriptor () { + static checkdescriptor cd ("check_duplicate_DW_tag_variable"); + return cd; + } + + check_duplicate_DW_tag_variable (checkstack &stack, dwarflint &lint); + }; + + reg reg_duplicate_DW_tag_variable; +} + +check_duplicate_DW_tag_variable +::check_duplicate_DW_tag_variable (checkstack &stack, dwarflint &lint) + : highlevel_check (stack, lint) +{ + for (all_dies_iterator it = all_dies_iterator (dw); + it != all_dies_iterator (); ++it) + { + dwarf::debug_info_entry::children_type const &children + = it->children (); + + typedef std::map variables_map; + variables_map variables; + + for (dwarf::debug_info_entry::children_type::const_iterator + jt = children.begin (); jt != children.end (); ++jt) + { + if (jt->tag () == DW_TAG_variable) + { + dwarf::debug_info_entry::attributes_type const & + attrs = jt->attributes (); + dwarf::debug_info_entry::attributes_type::const_iterator + at, et = attrs.end (); + if ((at = attrs.find (DW_AT_name)) == et) + continue; + char const *cname = (*at).second.identifier (); + + bool declaration = false; + if ((at = attrs.find (DW_AT_declaration)) != et) + declaration = (*at).second.flag (); + + std::string name (cname); + variables_map::iterator old = variables.find (name); + if (old == variables.end ()) + { + varinfo i (children); + if (declaration) + i.decl = jt; + else + i.def = jt; + variables.insert (std::make_pair (name, i)); + } + else + { + varinfo &i = old->second; + if ((declaration && i.decl != children.end ()) + || (!declaration && i.def != children.end ())) + wr_error (to_where (*jt)) + << "Re" << (declaration ? "declaration" : "definition") + << " of variable '" << name << "', originally seen at " + << pri::ref (declaration ? *i.decl : *i.def) + << '.' << std::endl; + else + wr_error (to_where (*jt)) + << "Found " + << (declaration ? "declaration" : "definition") + << " of variable '" << name + << "' whose " + << (declaration ? "definition" : "declaration") + << " was seen at " + << pri::ref (declaration ? *i.def : *i.decl) + << '.' << std::endl; + } + } + } + } +} diff --git a/dwarflint/tests/crc7.ko.debug.bz2 b/dwarflint/tests/crc7.ko.debug.bz2 new file mode 100644 index 000000000..be66966e2 Binary files /dev/null and b/dwarflint/tests/crc7.ko.debug.bz2 differ diff --git a/dwarflint/tests/run-check_duplicate_DW_tag_variable.sh b/dwarflint/tests/run-check_duplicate_DW_tag_variable.sh new file mode 100755 index 000000000..6c47b02ef --- /dev/null +++ b/dwarflint/tests/run-check_duplicate_DW_tag_variable.sh @@ -0,0 +1,172 @@ +#! /bin/sh +# Copyright (C) 2010 Red Hat, Inc. +# This file is part of Red Hat elfutils. +# +# Red Hat elfutils is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by the +# Free Software Foundation; version 2 of the License. +# +# Red Hat elfutils is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Red Hat elfutils; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. +# +# Red Hat elfutils is an included package of the Open Invention Network. +# An included package of the Open Invention Network is a package for which +# Open Invention Network licensees cross-license their patents. No patent +# license is granted, either expressly or impliedly, by designation as an +# included package. Should you wish to participate in the Open Invention +# Network licensing program, please visit www.openinventionnetwork.com +# . + +. $srcdir/../tests/test-subr.sh + +srcdir=$srcdir/tests + +testfiles crc7.ko.debug + +testrun_compare ./dwarflint --check check_duplicate_DW_tag_variable crc7.ko.debug <