Bug 25986 - Wrong name of function type used in change report

We have introduced type name caching long ago to speed up operations
involving type names.

Then last year, I was looking at some speed optimization in the
xml-writer and I started playing with the caching to quantify the
speed impact that early caching could have on emitting writting out
the abixml, independantly from the potential accuracy issues that
could have.

And somehow I accidentally committed one of those experimental
patches:
https://sourceware.org/git/?p=libabigail.git;a=commit;h=7699dfc921d248fa6d5cbdbeab9d501b17ef3f52.

This commit reverts that bogus patch.  There should be no speed impact
because the writter now de-duplicates types at writting time by
"simply" writting out the canonical types, as opposed to the naive
approach we were using then.

This fixes the bug reported at
https://sourceware.org/bugzilla/show_bug.cgi?id=25986 which shows the
impact of caching the wrong name of the type, which happens when
caching occurs before the type is canonicalized.

	* src/abg-ir.cc (function_type::get_cached_name): Don't cache
	names for non-canonicalized types.
	* tests/data/test-abidiff-exit/test-fun-param-report.txt: Add
	reference output for new test.
	* tests/data/test-abidiff-exit/test-fun-param-v{0,1}.abi: Add new test
	input files.
	* tests/data/test-abidiff-exit/test-fun-param-v{0,1}.c: Add source
	files for the above.
	* tests/data/test-abidiff-exit/test-fun-param-v{0,1}.o: Add
	binaries for the above.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2020-05-13 16:22:01 +02:00
parent 66e5e36469
commit e2341a939c
10 changed files with 137 additions and 2 deletions

View File

@ -16411,13 +16411,13 @@ function_type::get_cached_name(bool internal) const
{
if (internal)
{
if (priv_->internal_cached_name_.empty())
if (!get_naked_canonical_type() || priv_->internal_cached_name_.empty())
priv_->internal_cached_name_ = get_function_type_name(this, internal);
return priv_->internal_cached_name_;
}
if (priv_->cached_name_.empty())
if (!get_naked_canonical_type() || priv_->cached_name_.empty())
priv_->cached_name_ = get_function_type_name(this, internal);
return priv_->cached_name_;

View File

@ -151,6 +151,13 @@ test-abidiff-exit/test-decl-struct-v0.o \
test-abidiff-exit/test-decl-struct-v1.c \
test-abidiff-exit/test-decl-struct-v1.o \
test-abidiff-exit/test-decl-struct-report.txt \
test-abidiff-exit/test-fun-param-report.txt \
test-abidiff-exit/test-fun-param-v0.abi \
test-abidiff-exit/test-fun-param-v0.c \
test-abidiff-exit/test-fun-param-v0.o \
test-abidiff-exit/test-fun-param-v1.abi \
test-abidiff-exit/test-fun-param-v1.c \
test-abidiff-exit/test-fun-param-v1.o \
\
test-diff-dwarf/test0-v0.cc \
test-diff-dwarf/test0-v0.o \

View File

@ -0,0 +1,15 @@
Functions changes summary: 0 Removed, 1 Changed, 0 Added function
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1 function with some indirect sub-type change:
[C] 'function void reg(ops*)' at test-fun-param-v1.c:7:1 has some indirect sub-type changes:
parameter 1 of type 'ops*' has sub-type changes:
in pointed to type 'struct ops' at test-fun-param-v1.c:1:1:
type size hasn't changed
1 data member change:
type of 'void (void*, unsigned int, unsigned long int)* ops::bind_class' changed:
in pointed to type 'function type void (void*, unsigned int, unsigned long int)':
parameter 4 of type 'void*' was added
parameter 5 of type 'unsigned long int' was added

View File

@ -0,0 +1,44 @@
<abi-corpus path='test-fun-param-v0.o' architecture='elf-amd-x86_64'>
<elf-function-symbols>
<elf-symbol name='reg' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
</elf-function-symbols>
<abi-instr version='1.0' address-size='64' path='test-fun-param-v0.c' comp-dir-path='/usr/local/google/home/gprocida/dev/libabigail' language='LANG_C99'>
<type-decl name='int' size-in-bits='32' id='type-id-1'/>
<type-decl name='unsigned int' size-in-bits='32' id='type-id-2'/>
<type-decl name='unsigned long int' size-in-bits='64' id='type-id-3'/>
<type-decl name='void' id='type-id-4'/>
<class-decl name='ops' size-in-bits='192' is-struct='yes' visibility='default' filepath='/usr/local/google/home/gprocida/dev/libabigail/test-fun-param-v0.c' line='1' column='1' id='type-id-5'>
<data-member access='public' layout-offset-in-bits='0'>
<var-decl name='foo' type-id='type-id-6' visibility='default' filepath='/usr/local/google/home/gprocida/dev/libabigail/test-fun-param-v0.c' line='2' column='1'/>
</data-member>
<data-member access='public' layout-offset-in-bits='64'>
<var-decl name='bind_class' type-id='type-id-7' visibility='default' filepath='/usr/local/google/home/gprocida/dev/libabigail/test-fun-param-v0.c' line='3' column='1'/>
</data-member>
<data-member access='public' layout-offset-in-bits='128'>
<var-decl name='bar' type-id='type-id-8' visibility='default' filepath='/usr/local/google/home/gprocida/dev/libabigail/test-fun-param-v0.c' line='4' column='1'/>
</data-member>
</class-decl>
<pointer-type-def type-id='type-id-9' size-in-bits='64' id='type-id-8'/>
<pointer-type-def type-id='type-id-5' size-in-bits='64' id='type-id-10'/>
<pointer-type-def type-id='type-id-11' size-in-bits='64' id='type-id-6'/>
<pointer-type-def type-id='type-id-12' size-in-bits='64' id='type-id-7'/>
<pointer-type-def type-id='type-id-4' size-in-bits='64' id='type-id-13'/>
<function-decl name='reg' mangled-name='reg' filepath='/usr/local/google/home/gprocida/dev/libabigail/test-fun-param-v0.c' line='7' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='reg'>
<parameter type-id='type-id-10' name='o' filepath='/usr/local/google/home/gprocida/dev/libabigail/test-fun-param-v0.c' line='7' column='1'/>
<return type-id='type-id-4'/>
</function-decl>
<function-type size-in-bits='64' id='type-id-9'>
<parameter type-id='type-id-1'/>
<return type-id='type-id-1'/>
</function-type>
<function-type size-in-bits='64' id='type-id-11'>
<return type-id='type-id-4'/>
</function-type>
<function-type size-in-bits='64' id='type-id-12'>
<parameter type-id='type-id-13'/>
<parameter type-id='type-id-2'/>
<parameter type-id='type-id-3'/>
<return type-id='type-id-4'/>
</function-type>
</abi-instr>
</abi-corpus>

View File

@ -0,0 +1,7 @@
struct ops {
void(*foo)(void);
void(*bind_class)(void *, unsigned int, unsigned long);
int(*bar)(int);
};
void reg(struct ops* o) { (void)o; }

Binary file not shown.

View File

@ -0,0 +1,46 @@
<abi-corpus path='test-fun-param-v1.o' architecture='elf-amd-x86_64'>
<elf-function-symbols>
<elf-symbol name='reg' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
</elf-function-symbols>
<abi-instr version='1.0' address-size='64' path='test-fun-param-v1.c' comp-dir-path='/usr/local/google/home/gprocida/dev/libabigail' language='LANG_C99'>
<type-decl name='int' size-in-bits='32' id='type-id-1'/>
<type-decl name='unsigned int' size-in-bits='32' id='type-id-2'/>
<type-decl name='unsigned long int' size-in-bits='64' id='type-id-3'/>
<type-decl name='void' id='type-id-4'/>
<class-decl name='ops' size-in-bits='192' is-struct='yes' visibility='default' filepath='/usr/local/google/home/gprocida/dev/libabigail/test-fun-param-v1.c' line='1' column='1' id='type-id-5'>
<data-member access='public' layout-offset-in-bits='0'>
<var-decl name='foo' type-id='type-id-6' visibility='default' filepath='/usr/local/google/home/gprocida/dev/libabigail/test-fun-param-v1.c' line='2' column='1'/>
</data-member>
<data-member access='public' layout-offset-in-bits='64'>
<var-decl name='bind_class' type-id='type-id-7' visibility='default' filepath='/usr/local/google/home/gprocida/dev/libabigail/test-fun-param-v1.c' line='3' column='1'/>
</data-member>
<data-member access='public' layout-offset-in-bits='128'>
<var-decl name='bar' type-id='type-id-8' visibility='default' filepath='/usr/local/google/home/gprocida/dev/libabigail/test-fun-param-v1.c' line='4' column='1'/>
</data-member>
</class-decl>
<pointer-type-def type-id='type-id-9' size-in-bits='64' id='type-id-8'/>
<pointer-type-def type-id='type-id-5' size-in-bits='64' id='type-id-10'/>
<pointer-type-def type-id='type-id-11' size-in-bits='64' id='type-id-6'/>
<pointer-type-def type-id='type-id-12' size-in-bits='64' id='type-id-7'/>
<pointer-type-def type-id='type-id-4' size-in-bits='64' id='type-id-13'/>
<function-decl name='reg' mangled-name='reg' filepath='/usr/local/google/home/gprocida/dev/libabigail/test-fun-param-v1.c' line='7' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='reg'>
<parameter type-id='type-id-10' name='o' filepath='/usr/local/google/home/gprocida/dev/libabigail/test-fun-param-v1.c' line='7' column='1'/>
<return type-id='type-id-4'/>
</function-decl>
<function-type size-in-bits='64' id='type-id-9'>
<parameter type-id='type-id-1'/>
<return type-id='type-id-1'/>
</function-type>
<function-type size-in-bits='64' id='type-id-11'>
<return type-id='type-id-4'/>
</function-type>
<function-type size-in-bits='64' id='type-id-12'>
<parameter type-id='type-id-13'/>
<parameter type-id='type-id-2'/>
<parameter type-id='type-id-3'/>
<parameter type-id='type-id-13'/>
<parameter type-id='type-id-3'/>
<return type-id='type-id-4'/>
</function-type>
</abi-instr>
</abi-corpus>

View File

@ -0,0 +1,7 @@
struct ops {
void(*foo)(void);
void(*bind_class)(void *, unsigned int, unsigned long, void *, unsigned long);
int(*bar)(int);
};
void reg(struct ops* o) { (void) o; }

Binary file not shown.

View File

@ -203,6 +203,15 @@ InOutSpec in_out_specs[] =
"data/test-abidiff-exit/test-decl-struct-report.txt",
"output/test-abidiff-exit/test-decl-struct-report.txt"
},
{
"data/test-abidiff-exit/test-fun-param-v0.abi",
"data/test-abidiff-exit/test-fun-param-v1.abi",
"",
"",
abigail::tools_utils::ABIDIFF_ABI_CHANGE,
"data/test-abidiff-exit/test-fun-param-report.txt",
"output/test-abidiff-exit/test-fun-param-report.txt"
},
{0, 0, 0 ,0, abigail::tools_utils::ABIDIFF_OK, 0, 0}
};