libabigail/tests/test-annotate.cc
Dodji Seketeli d4ca1088e4 Bug 30260 - Support pointer-to-member type
This adds support for C++ pointer-to-member types.

Here is a screenshot of what this patch enables libabigail to do:

    $ cat -n test-ptr-to-mbr-v0.cc
	 1	struct X
	 2	{
	 3	  void f(int);
	 4	  int a;
	 5	};
	 6
	 7	int X::* pmi = &X::a;
	 8	void (X::* pmf)(int) = &X::f;
	 9

    $ diff -u test-ptr-to-mbr-v0.cc test-ptr-to-mbr-v1.cc
    --- test-ptr-to-mbr-v0.cc	2023-11-22 15:22:04.258260701 +0100
    +++ test-ptr-to-mbr-v1.cc	2023-11-22 15:23:02.482621214 +0100
    @@ -1,9 +1,8 @@
     struct X
     {
    -  void f(int);
    -  int a;
    +  void f(int, char);
    +  char a;
     };

    -int X::* pmi = &X::a;
    -void (X::* pmf)(int) = &X::f;
    -
    +auto pmi = &X::a;
    +auto pmf = &X::f;

    $ abidiff test-ptr-to-mbr-v0.o test-ptr-to-mbr-v1.o
    Functions changes summary: 0 Removed, 0 Changed, 0 Added function
    Variables changes summary: 0 Removed, 2 Changed, 0 Added variables

    2 Changed variables:

      [C] 'void (X::* pmf)(int)' was changed to 'void (X::* pmf)(int, char)' at test-ptr-to-mbr-v1.cc:8:1:
	type of variable changed:
	  pointer-to-member type changed from: 'void (X::*)(int) to: 'void (X::*)(int, char)'
	  in containing type 'struct X' of pointed-to-member type 'void (X::*)(int)' at test-ptr-to-mbr-v1.cc:1:1:
	    type size changed from 32 to 8 (in bits)
	    1 data member change:
	      type of 'int a' changed:
		type name changed from 'int' to 'char'
		type size changed from 32 to 8 (in bits)

      [C] 'int X::* pmi' was changed to 'char X::* pmi' at test-ptr-to-mbr-v1.cc:7:1:
	type of variable changed:
	  pointer-to-member type changed from: 'int X::* to: 'char X::*'
	  in data member type 'int' of pointed-to-member type 'int X::*':
	    type name changed from 'int' to 'char'
	    type size changed from 32 to 8 (in bits)
	  containing type of pointer-to-member 'struct X' changed at test-ptr-to-mbr-v0.cc:1:1, as reported earlier

    $

	* include/abg-comparison.h (class ptr_to_mbr_diff): Declare new
	class.
	(ptr_to_mbr_diff_sptr): Declare new typedef.
	(compute_diff): Declare new overload for ptr_to_mbr_diff.
	(ptr_to_mbr_type_sptr): Declare new typedef.
	* src/abg-comparison-priv.h (struct ptr_to_mbr_diff::priv): Define
	* src/abg-comparison.cc (compute_diff_for_types): Support new
	ptr_to_mbr_type type.
	(ptr_to_mbr_diff::{ptr_to_mbr_diff, first_ptr_to_mbr_type,
	second_ptr_to_mbr_type, member_type_diff, containing_type_diff,
	has_changes, has_local_changes, get_pretty_representation, report,
	chain_into_hierarchy, ~ptr_to_mbr_diff}): Define member functions
	of class ptr_to_mbr_diff.
	(compute_diff): Define overload for ptr_to_mbr_type_sptr.
	* include/abg-fwd.h (ptr_to_mbr_type_sptr): Declare new typedef.
	(is_ptr_to_mbr_type, is_pointer_to_ptr_to_mbr_type)
	(is_typedef_of_maybe_qualified_class_or_union_type): Declare new
	functions.
	* include/abg-ir.h (type_maps::ptr_to_mbr_types): Declare new
	accessor.
	(POINTER_TO_MEMBER_TYPE): Add new enumerator to enum
	type_or_decl_base::type_or_decl_kind.
	(class ptr_to_mbr_type): Declare new class.
	(equals): Declare new overload for ptr_to_mbr_type.
	(ir_node_visitor::visit_{begin,end}): Declare new member
	functions.
	* src/abg-ir.cc (ptr_to_mbr_declaration_name)
	(ptr_to_mbr_declaration_name, add_outer_ptr_to_mbr_type_expr)
	(add_outer_pointer_to_ptr_to_mbr_type_expr): Define new static
	functions.
	(type_maps::priv::ptr_to_mbr_types_): Define new
	data member.
	(type_maps::ptr_to_mbr_types): Define new accessor.
	(is_ptr_to_mbr_type, is_pointer_to_ptr_to_mbr_type)
	(is_typedef_of_maybe_qualified_class_or_union_type): Define new
	functions.
	(maybe_update_types_lookup_map, equals): Define new overloads for
	ptr_to_mbr_type_sptr.
	(is_npaf_type): Use is_ptr_to_mbr_type.
	(maybe_update_types_lookup_map): In the overload for
	decl_base_sptr, call the new overload for ptr_to_mbr_type_sptr
	above.
	(struct ptr_to_mbr_type::priv): Define new struct.
	(ptr_to_mbr_type::{ptr_to_mbr_type, get_member_type,
	get_containing_type, operator==, get_qualified_name, traverse,
	~ptr_to_mbr_type}): Define member functions of ptr_to_mbr_type.
	(types_have_similar_structure): Support the new ptr_to_mbr_type
	type.
	(ir_node_visitor::visit_{begin,end}): Add new member functions.
	(var_decl::get_pretty_representation): Support pretty-printing
	pointer-to-member types.
	(pointer_declaration_name, array_declaration_name): Likewise.
	* include/abg-reporter.h ({reporter_base, default_reporter,
	leaf_reporter}::report): Add an overload for ptr_to_mbr_diff.
	(default_reporter::report_local_ptr_to_mbr_type_changes): Declare
	a member function.
	private data class of ptr_to_mbr_diff.
	* src/abg-default-reporter.cc
	(default_reporter::report_local_ptr_to_mbr_type_changes): Define
	member functions.
	(default_reporter::report): Define an overload for
	ptr_to_mbr_diff.
	* src/abg-leaf-reporter.cc (leaf_reporter::report): Likewise.
	* src/abg-dwarf-reader.cc (build_ptr_to_mbr_type): Define new
	function.
	(build_ir_node_from_die): Use the new build_ptr_to_mbr_type
	function.
	* src/abg-reader.cc (build_ptr_to_mbr_type): Define new function.
	(build_type): Use the new build_ptr_to_mbr_type above.
	* src/abg-writer.cc (write_ptr_to_mbr_type): Define new function.
	(write_type, write_decl, write_member_type): Use the new
	write_ptr_to_mbr_type above.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr1-output-1.txt:
	Add new test material.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr1-v0.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr1-v0.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr1-v1.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr1-v1.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr2-output-1.txt:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr2-v0.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr2-v0.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr2-v1.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr2-v1.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr3-output-1.txt:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr3-v0.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr3-v0.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr3-v1.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr3-v1.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr4-output-1.txt:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr4-v0.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr4-v0.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr4-v1.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr4-v1.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr5-output-1.txt:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr5-v0.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr5-v0.o:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr5-v1.cc:
	Likewise.
	* tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr5-v1.o:
	Likewise.
	* tests/data/test-read-dwarf/test-pointer-to-member-1.cc:
	Likewise.
	* tests/data/test-read-dwarf/test-pointer-to-member-1.o: Likewise.
	* tests/data/test-read-dwarf/test-pointer-to-member-1.o.abi:
	Likewise.
	* tests/data/Makefile.am: Add the new test material above to
	source distribution.
	* tests/test-abidiff-exit.cc (in_out_specs): Add the test material
	above to this test harness.
	* tests/test-annotate.cc (in_out_specs): Likewise.
	* tests/test-read-dwarf.cc: Likewise.
	* tests/data/test-read-dwarf/PR22015-libboost_iostreams.so.abi: Adjust.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2023-12-01 15:43:53 +01:00

203 lines
5.6 KiB
C++

// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// -*- Mode: C++ -*-
//
// Author: Ondrej Oprala
/// @file
///
/// This program tests the annotation capabilities of the library.
#include <iostream>
#include <cstdlib>
#include "abg-tools-utils.h"
#include "test-utils.h"
using std::cerr;
using std::string;
using abigail::tests::emit_test_status_and_update_counters;
using abigail::tests::emit_test_summary;
struct InOutSpec
{
const char* in_elf_path;
const char* in_report_path;
const char* out_report_path;
};
InOutSpec in_out_specs[] =
{
{
"data/test-read-dwarf/test0",
"data/test-annotate/test0.abi",
"output/test-annotate/test0.abi"
},
{
"data/test-read-dwarf/test1",
"data/test-annotate/test1.abi",
"output/test-annotate/test1.abi"
},
{
"data/test-read-dwarf/test2.so",
"data/test-annotate/test2.so.abi",
"output/test-annotate/test2.so.abi"
},
{
"data/test-read-common/test3.so",
"data/test-annotate/test3.so.abi",
"output/test-annotate/test3.so.abi"
},
{
"data/test-read-common/test4.so",
"data/test-annotate/test4.so.abi",
"output/test-annotate/test4.so.abi"
},
{
"data/test-read-dwarf/test5.o",
"data/test-annotate/test5.o.abi",
"output/test-annotate/test5.o.abi"
},
{
"data/test-read-dwarf/test6.so",
"data/test-annotate/test6.so.abi",
"output/test-annotate/test6.so.abi"
},
{
"data/test-read-dwarf/test7.so",
"data/test-annotate/test7.so.abi",
"output/test-annotate/test7.so.abi"
},
{
"data/test-read-dwarf/test8-qualified-this-pointer.so",
"data/test-annotate/test8-qualified-this-pointer.so.abi",
"output/test-annotate/test8-qualified-this-pointer.so.abi"
},
{
"data/test-read-dwarf/test13-pr18894.so",
"data/test-annotate/test13-pr18894.so.abi",
"output/test-annotate/test13-pr18894.so.abi",
},
{
"data/test-read-dwarf/test14-pr18893.so",
"data/test-annotate/test14-pr18893.so.abi",
"output/test-annotate/test14-pr18893.so.abi",
},
{
"data/test-read-dwarf/test15-pr18892.so",
"data/test-annotate/test15-pr18892.so.abi",
"output/test-annotate/test15-pr18892.so.abi",
},
{
"data/test-read-dwarf/test17-pr19027.so",
"data/test-annotate/test17-pr19027.so.abi",
"output/test-annotate/test17-pr19027.so.abi",
},
{
"data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so",
"data/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi",
"output/test-annotate/test18-pr19037-libvtkRenderingLIC-6.1.so.abi",
},
{
"data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so",
"data/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi",
"output/test-annotate/test19-pr19023-libtcmalloc_and_profiler.so.abi",
},
{
"data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so",
"data/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi",
"output/test-annotate/test20-pr19025-libvtkParallelCore-6.1.so.abi",
},
{
"data/test-read-dwarf/test21-pr19092.so",
"data/test-annotate/test21-pr19092.so.abi",
"output/test-annotate/test21-pr19092.so.abi",
},
{
"data/test-read-dwarf/libtest23.so",
"data/test-annotate/libtest23.so.abi",
"output/test-annotate/libtest23.so.abi",
},
{
"data/test-read-dwarf/libtest24-drop-fns.so",
"data/test-annotate/libtest24-drop-fns.so.abi",
"output/test-annotate/libtest24-drop-fns.so.abi",
},
{
"data/test-read-dwarf/libtest24-drop-fns.so",
"data/test-annotate/libtest24-drop-fns-2.so.abi",
"output/test-annotate/libtest24-drop-fns-2.so.abi",
},
{
"data/test-annotate/test-anonymous-members-0.o",
"data/test-annotate/test-anonymous-members-0.o.abi",
"output/test-annotate/test-anonymous-members-0.o.abi",
},
{
"data/test-read-dwarf/PR29443-missing-xx.o",
"data/test-annotate/PR29443-missing-xx.o.annotated.abi",
"output/test-annotate/PR29443-missing-xx.o.annotated.abi",
},
{
"data/test-read-dwarf/test-pointer-to-member-1.o",
"data/test-annotate/test-pointer-to-member-1.o.annotated.abi",
"output/test-annotate/test-pointer-to-member-1.o.annotated.abi",
},
// This should be the last entry.
{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;
unsigned int total_count = 0, passed_count = 0, failed_count = 0;
string in_elf_path, ref_report_path, out_report_path;
string abidw;
abidw = string(get_build_dir()) + "/tools/abidw "
"--annotate --no-corpus-path --no-architecture";
for (InOutSpec* s = in_out_specs; s->in_elf_path; ++s)
{
bool is_ok = true;
in_elf_path = string(get_src_dir()) + "/tests/" + s->in_elf_path;
ref_report_path = string(get_src_dir()) + "/tests/" + s->in_report_path;
out_report_path =
string(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 + " " + in_elf_path + " > " + out_report_path;
bool abidw_ok = true;
if (system(cmd.c_str()))
abidw_ok = false;
if (abidw_ok)
{
string diff_cmd =
"diff -w -u " + ref_report_path + " " + out_report_path;
if (system(diff_cmd.c_str()))
is_ok &=false;
}
else
{
is_ok &= false;
}
emit_test_status_and_update_counters(is_ok, cmd, passed_count,
failed_count, total_count);
}
emit_test_summary(total_count, passed_count, failed_count);
return failed_count;
}