mirror of
git://sourceware.org/git/libabigail.git
synced 2024-12-18 07:54:36 +00:00
43c908ed15
Sometimes we can see const references in DWARF. But then, a reference is always const, so that qualified reference is redundant. Furthermore, having that construct make its way into the internal representation can cause awkward diagnostics. The DWARF reader was thus eliding such redundant qualifiers in the function "maybe_strip_qualification". It was doing so by stripping the qualifier from the qualified type. So const reference, for instance, becomes a (non-qualified) reference. In that case, we are turning a qualified type into a non-qualified one. But as the accompanying problem report suggests, this can cause issues during the DWARF parsing. This is because a given Debug Information Entry (DIE) of qualified type kind can be referenced elsewhere, by another type. That other type expects that DIE to be a qualified type. And libabigail's DWARF reader code enforces that. So the internal representation of a type resulting from a qualified type DIE must be a qualified type itself. So the way the function "maybe_strip_qualification" was doing the redundancy elision was wrong. This patch fixes that by keeping the type qualified, but introducing a "no-op" qualifier. Actually, the IR already has that "no-op" qualifier: abigail::ir::qualified_type_def::CV_NONE. So now "maybe_strip_qualification" just turns the CV_CONST qualifier into a CV_NONE one when the former is redundant. Now that the libabigail type system actually *has* types qualified with this no-op qualifier, we need to handle things like printing the name of such qualified types. When we are printing the name of the type for internal reasons (i.e, for type canonicalization purposes) we need to make a difference between the name of a no-op qualified type and the name of the underlying type of the qualified type, otherwise, the canonicalizer wrongly considers the two types as being equal. But then when we are printing the name of the no-op qualified type for diagnostics reasons, then the name is the same as the name of its underlying unqualified type. * src/abg-dwarf-reader.cc (maybe_strip_qualification): Do not nuke the qualified type. Rather, just turn the redundant const qualifier into a no-op one. * src/abg-comparison.cc (compute_diff_for_types): Look through no-op qualified types. * include/abg-ir.h (decl_base::{peek,set}_temporary_qualified_name): Declare new accessors. * src/abg-ir.cc (decl_base::priv::temporary_qualified_name_): New data member. (decl_base::{peek,set}_temporary_qualified_name): Define new accessors. (qualified_type_def::priv::{temporary_internal_name_, internal_name}): New data members. (qualified_type_def::build_name): For a no-op qualified type, the internal name (which contains the 'none' qualifier) is different from the non-internal name. (qualified_type_def::get_qualified_name): Handle temporary names and non-temporary names in two different caches. Also handle internal and non-internal names in two different caches. This makes four different caches. (qualified_name_setter::do_update): Do not touch the non-internal, non-temporary qualified name cache if the qualified parent name is empty. * tools/abidw.cc (main): change --check-alternate-debug-info to make it *not* display the name/path to the alternate debug info, when it's found. Rather, only --check-alternate-debug-info-base-name keeps displaying the base name of the alternate debug info. * tests/data/test-alt-dwarf-file/test1-libgromacs-debug-dir/*: New test material. * tests/data/Makefile.am: Add the new test material to the build system. * tests/test-alt-dwarf-file.cc (in_out_specs): Take the new test input into account. * tests/data/test-read-dwarf/test1.abi: Adjust. * tests/data/test-read-dwarf/test7.so.abi: Likewise. * tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise. * tests/data/test-read-dwarf/test11-pr18828.so.abi: Likewise. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise. * tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise. * tests/data/test-read-dwarf/test17-pr19027.so.abi: Likewise. * tests/data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi: Likewise. * tests/data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi: Likewise. * tests/data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi: Likewise. Signed-off-by: Dodji Seketeli <dodji@redhat.com>
123 lines
3.5 KiB
C++
123 lines
3.5 KiB
C++
// -*- Mode: C++ -*-
|
|
//
|
|
// Copyright (C) 2013-2015 Red Hat, Inc.
|
|
//
|
|
// This file is part of the GNU Application Binary Interface Generic
|
|
// Analysis and Instrumentation Library (libabigail). This library is
|
|
// free software; you can redistribute it and/or modify it under the
|
|
// terms of the GNU Lesser General Public License as published by the
|
|
// Free Software Foundation; either version 3, or (at your option) any
|
|
// later version.
|
|
|
|
// This library 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 Lesser Public License for more details.
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this program; see the file COPYING-LGPLV3. If
|
|
// not, see <http://www.gnu.org/licenses/>.
|
|
|
|
// Author: Dodji Seketeli
|
|
|
|
/// @file
|
|
///
|
|
/// This program tests that libabigail can handle alternate debug info
|
|
/// files as specified by http://www.dwarfstd.org/ShowIssue.php?issue=120604.1.
|
|
|
|
#include <iostream>
|
|
#include <cstdlib>
|
|
#include "abg-tools-utils.h"
|
|
#include "test-utils.h"
|
|
|
|
using std::cerr;
|
|
using std::string;
|
|
|
|
struct InOutSpec
|
|
{
|
|
const char* in_elf_path;
|
|
const char* debug_info_dir_path;
|
|
const char* abidw_options;
|
|
const char* in_report_path;
|
|
const char* out_report_path;
|
|
};
|
|
|
|
|
|
InOutSpec in_out_specs[] =
|
|
{
|
|
{
|
|
"data/test-alt-dwarf-file/libtest0.so",
|
|
"data/test-alt-dwarf-file/test0-debug-dir",
|
|
"--check-alternate-debug-info-base-name",
|
|
"data/test-alt-dwarf-file/test0-report.txt",
|
|
"output/test-alt-dwarf-file/test0-report.txt"
|
|
},
|
|
{
|
|
"data/test-alt-dwarf-file/libtest0-common.so",
|
|
"data/test-alt-dwarf-file/test0-debug-dir",
|
|
"--check-alternate-debug-info-base-name",
|
|
"data/test-alt-dwarf-file/test0-report.txt",
|
|
"output/test-alt-dwarf-file/test0-report.txt"
|
|
},
|
|
{
|
|
"data/test-alt-dwarf-file/test1-libgromacs_d.so.0.0.0",
|
|
"data/test-alt-dwarf-file/test1-libgromacs-debug-dir",
|
|
"--noout --check-alternate-debug-info",
|
|
"data/test-alt-dwarf-file/test1-report-0.txt",
|
|
"output/test-alt-dwarf-file/test1-report-0.txt"
|
|
},
|
|
|
|
// This should always be the last entry
|
|
{NULL, NULL, NULL, NULL, NULL}
|
|
};
|
|
|
|
int
|
|
main()
|
|
{
|
|
using abigail::tests::get_src_dir;
|
|
using abigail::tests::get_build_dir;
|
|
using abigail::tools_utils::ensure_parent_dir_created;
|
|
|
|
bool is_ok = true;
|
|
string in_elf_path, ref_report_path, out_report_path, debug_info_dir;
|
|
string abidw, abidw_options;
|
|
|
|
abidw = get_build_dir() + "/tools/abidw";
|
|
for (InOutSpec* s = in_out_specs; s->in_elf_path; ++s)
|
|
{
|
|
abidw_options = s->abidw_options;
|
|
in_elf_path = get_src_dir() + "/tests/" + s->in_elf_path;
|
|
debug_info_dir = get_src_dir() + "/tests/" + s->debug_info_dir_path;
|
|
ref_report_path = get_src_dir() + "/tests/" + s->in_report_path;
|
|
out_report_path = get_build_dir() + "/tests/" + s->out_report_path;
|
|
if (!ensure_parent_dir_created(out_report_path))
|
|
{
|
|
cerr << "could not create parent directory for "
|
|
<< out_report_path;
|
|
is_ok = false;
|
|
continue;
|
|
}
|
|
|
|
string cmd = abidw + " --debug-info-dir " + debug_info_dir
|
|
+ " " + abidw_options + " " + in_elf_path + " > " + out_report_path;
|
|
|
|
bool abidw_ok = true;
|
|
if (system(cmd.c_str()))
|
|
abidw_ok = false;
|
|
|
|
if (abidw_ok)
|
|
{
|
|
cmd = "diff -u " + ref_report_path + " " + out_report_path;
|
|
if (system(cmd.c_str()))
|
|
is_ok &=false;
|
|
}
|
|
else
|
|
{
|
|
cerr << "command failed: " << cmd << "\n";
|
|
is_ok &= false;
|
|
}
|
|
}
|
|
|
|
return !is_ok;
|
|
}
|