@@ -433,7 +433,11 @@ The potential properties of this sections are listed below:
Suppresses change reports involving a type which has at least one
data member inserted at an offset specified by the property value
- ``offset-in-bit``. The value ``offset-in-bit`` is either:
+ ``offset-in-bit``. Please note that if a type has a change in which
+ at least one of its data members is removed or its size is reduced,
+ the type will *NOT* be suppressed by the evaluation of this property.
+
+ The value ``offset-in-bit`` is either:
- an integer value, expressed in bits, which denotes the
offset of the insertion point of the data member, starting
@@ -468,11 +472,14 @@ The potential properties of this sections are listed below:
``has_data_member_inserted_between`` ``=`` {<``range-begin``>, <``range-end``>}
Suppresses change reports involving a type which has at least one
- data mber inserted at an offset that is comprised in the range
- between range-begin`` and ``range-end``. Please note that each of
+ data member inserted at an offset that is comprised in the range
+ between ``range-begin`` and ``range-end``. Please note that each of
the values ``range-begin`` and ``range-end`` can be of the same form
as the :ref:`has_data_member_inserted_at
- <suppr_has_data_member_inserted_at_label>` property above.
+ <suppr_has_data_member_inserted_at_label>` property above. Please
+ also note that if a type has a change in which at least one of its
+ data members is removed or its size is reduced, the type will *NOT* be
+ suppressed by the evaluation of this property.
Usage examples of this properties are: ::
@@ -508,7 +515,10 @@ The potential properties of this sections are listed below:
long as the system can cope with. The values of the boundaries of
the ranges are of the same kind as for the
:ref:`has_data_member_inserted_at
- <suppr_has_data_member_inserted_at_label>` property above.
+ <suppr_has_data_member_inserted_at_label>` property above. Please
+ note that if a type has a change in which at least one of its data
+ members is removed or its size is reduced, the type will *NOT* be
+ suppressed by the evaluation of this property.
Another usage example of this property is thus: ::
@@ -639,6 +639,9 @@ is_data_member(const decl_base *);
const var_decl_sptr
get_next_data_member(const class_or_union_sptr&, const var_decl_sptr&);
+var_decl_sptr
+get_last_data_member(const class_or_union_sptr&);
+
bool
is_anonymous_data_member(const decl_base&);
@@ -721,6 +724,11 @@ get_data_member_offset(const decl_base_sptr);
uint64_t
get_absolute_data_member_offset(const var_decl&);
+bool
+get_next_data_member_offset(const class_or_union_sptr&,
+ const var_decl_sptr&,
+ uint64_t&);
+
uint64_t
get_var_size_in_bits(const var_decl_sptr&);
@@ -328,7 +328,10 @@ public:
static bool
eval_boundary(boundary_sptr boundary,
class_decl_sptr context,
- ssize_t& value);
+ uint64_t& value);
+
+ static bool
+ boundary_value_is_end(uint64_t value);
}; // end class insertion_range
type_suppression::insertion_range::integer_boundary_sptr
@@ -360,9 +363,9 @@ class type_suppression::insertion_range::integer_boundary
integer_boundary();
public:
- integer_boundary(int value);
- int as_integer() const;
- operator int() const;
+ integer_boundary(uint64_t value);
+ uint64_t as_integer() const;
+ operator uint64_t () const;
~integer_boundary();
}; //end class type_suppression::insertion_range::integer_boundary
@@ -5739,6 +5739,13 @@ get_next_data_member(const class_or_union_sptr &klass,
return var_decl_sptr();
}
+/// Get the last data member of a class type.
+///
+/// @param klass the class type to consider.
+var_decl_sptr
+get_last_data_member(const class_or_union_sptr &klass)
+{return klass->get_non_static_data_members().back();}
+
/// Test if a decl is an anonymous data member.
///
/// @param d the decl to consider.
@@ -6003,6 +6010,35 @@ uint64_t
get_data_member_offset(const decl_base_sptr d)
{return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
+/// Get the offset of the non-static data member that comes after a
+/// given one.
+///
+/// If there is no data member after after the one given to this
+/// function (maybe because the given one is the last data member of
+/// the class type) then the function return false.
+///
+/// @param klass the class to consider.
+///
+/// @param dm the data member before the one we want to retrieve.
+///
+/// @param offset out parameter. This parameter is set by the
+/// function to the offset of the data member that comes right after
+/// the data member @p dm, iff the function returns true.
+///
+/// @return true iff the data member coming right after @p dm was
+/// found.
+bool
+get_next_data_member_offset(const class_or_union_sptr& klass,
+ const var_decl_sptr& dm,
+ uint64_t& offset)
+{
+ var_decl_sptr next_dm = get_next_data_member(klass, dm);
+ if (!next_dm)
+ return false;
+ offset = get_data_member_offset(next_dm);
+ return true;
+}
+
/// Get the absolute offset of a data member.
///
/// If the data member is part of an anonymous data member then this
@@ -14,6 +14,7 @@
#include "abg-internal.h"
#include <memory>
+#include <limits>
// <headers defining libabigail's API go under here>
ABG_BEGIN_EXPORT_DECLARATIONS
@@ -773,67 +774,93 @@ type_suppression::suppresses_diff(const diff* diff) const
d = is_type_diff(get_typedef_diff_underlying_type_diff(d));
}
+ // Now let's consider class diffs in the context of a suppr spec
+ // that contains properties like "has_data_member_inserted_*".
+
const class_diff* klass_diff = dynamic_cast<const class_diff*>(d);
- if (// We are looking at a class diff ...
- klass_diff
- // ... that has inserted data members ...
- && !get_data_member_insertion_ranges().empty()
- // ... that has no deleted data members ...
- && klass_diff->deleted_data_members().empty()
- // ... and in which the class size hasn't shrunk (because, e.g,
- // the base classes have changed).
- && (klass_diff->first_class_decl()->get_size_in_bits()
- <= klass_diff->second_class_decl()->get_size_in_bits()))
+ if (klass_diff)
{
- const class_decl_sptr& first_type_decl = klass_diff->first_class_decl();
- const class_decl_sptr& second_type_decl = klass_diff->second_class_decl();
- size_t first_type_size = first_type_decl->get_size_in_bits();
- size_t second_type_size = second_type_decl->get_size_in_bits();
-
- for (string_decl_base_sptr_map::const_iterator m =
- klass_diff->inserted_data_members().begin();
- m != klass_diff->inserted_data_members().end();
- ++m)
+ // We are looking at a class diff ...
+ if (!get_data_member_insertion_ranges().empty())
{
- decl_base_sptr member = m->second;
- size_t dm_offset = get_data_member_offset(member);
- bool matched = false;
-
- for (insertion_ranges::const_iterator i =
- get_data_member_insertion_ranges().begin();
- i != get_data_member_insertion_ranges().end();
- ++i)
+ // ... and the suppr spec contains a
+ // "has_data_member_inserted_*" clause ...
+ if (klass_diff->deleted_data_members().empty()
+ && (klass_diff->first_class_decl()->get_size_in_bits()
+ <= klass_diff->second_class_decl()->get_size_in_bits()))
{
- type_suppression::insertion_range_sptr range = *i;
- ssize_t range_begin_val = 0,range_end_val = 0;
- if (!type_suppression::insertion_range::eval_boundary
- (range->begin(), first_type_decl, range_begin_val))
- break;
- if (!type_suppression::insertion_range::eval_boundary
- (range->end(), first_type_decl, range_end_val))
- break;
-
- unsigned range_begin =
- (range_begin_val < 0) ? first_type_size : range_begin_val;
-
- unsigned range_end =
- (range_end_val < 0) ? second_type_size : range_end_val;
-
- if (range_begin > range_end)
- continue;
-
- if (range_begin_val < 0 || range_end_val < 0)
+ // That "has_data_member_inserted_*" clause doesn't hold
+ // if the class has deleted data members or shrunk.
+
+ const class_decl_sptr& first_type_decl =
+ klass_diff->first_class_decl();
+ const class_decl_sptr& second_type_decl =
+ klass_diff->second_class_decl();
+
+ for (string_decl_base_sptr_map::const_iterator m =
+ klass_diff->inserted_data_members().begin();
+ m != klass_diff->inserted_data_members().end();
+ ++m)
{
- if (dm_offset < range_begin)
- continue;
+ decl_base_sptr member = m->second;
+ size_t dm_offset = get_data_member_offset(member);
+ bool matched = false;
+
+ for (insertion_ranges::const_iterator i =
+ get_data_member_insertion_ranges().begin();
+ i != get_data_member_insertion_ranges().end();
+ ++i)
+ {
+ type_suppression::insertion_range_sptr range = *i;
+ uint64_t range_begin_val = 0, range_end_val = 0;
+ if (!type_suppression::insertion_range::eval_boundary
+ (range->begin(), first_type_decl, range_begin_val))
+ break;
+ if (!type_suppression::insertion_range::eval_boundary
+ (range->end(), first_type_decl, range_end_val))
+ break;
+
+ uint64_t range_begin = range_begin_val;
+ uint64_t range_end = range_end_val;
+
+ if (insertion_range::boundary_value_is_end(range_begin)
+ && insertion_range::boundary_value_is_end(range_end))
+ {
+ // This idiom represents the predicate
+ // "has_data_member_inserted_at = end"
+ if (dm_offset >
+ get_data_member_offset(get_last_data_member
+ (first_type_decl)))
+ {
+ // So the data member was added after
+ // last data member of the klass. That
+ // matches the suppr spec
+ // "has_data_member_inserted_at = end".
+ matched = true;
+ continue;
+ }
+ }
+
+ if (range_begin > range_end)
+ // Wrong suppr spec. Ignore it.
+ continue;
+
+ if (dm_offset < range_begin || dm_offset > range_end)
+ // The offset of the added data member doesn't
+ // match the insertion range specified. So
+ // the diff object won't be suppressed.
+ continue;
+
+ // If we reached this point, then all the
+ // insertion range constraints have been
+ // satisfied. So
+ matched = true;
+ }
+ if (!matched)
+ return false;
}
- else
- if (dm_offset < range_begin || dm_offset > range_end)
- continue;
-
- matched = true;
}
- if (!matched)
+ else
return false;
}
}
@@ -1311,7 +1338,7 @@ type_suppression::insertion_range::create_fn_call_expr_boundary(const string& s)
bool
type_suppression::insertion_range::eval_boundary(boundary_sptr boundary,
class_decl_sptr context,
- ssize_t& value)
+ uint64_t& value)
{
if (integer_boundary_sptr b = is_integer_boundary(boundary))
{
@@ -1338,8 +1365,13 @@ type_suppression::insertion_range::eval_boundary(boundary_sptr boundary,
if (fn_call->get_name() == "offset_of")
value = get_data_member_offset(*it);
else if (fn_call->get_name() == "offset_after")
- value = get_data_member_offset(*it) +
- (*it)->get_type()->get_size_in_bits();
+ {
+ if (!get_next_data_member_offset(context, *it, value))
+ {
+ value = get_data_member_offset(*it) +
+ (*it)->get_type()->get_size_in_bits();
+ }
+ }
else
// We should not reach this point.
abort();
@@ -1351,6 +1383,19 @@ type_suppression::insertion_range::eval_boundary(boundary_sptr boundary,
return false;
}
+/// Test if a given value supposed to be inside an insertion range
+/// represents the end of the range.
+///
+/// @param value the value to test for.
+///
+/// @return true iff @p value represents the end of the insertion
+/// range.
+bool
+type_suppression::insertion_range::boundary_value_is_end(uint64_t value)
+{
+ return value == std::numeric_limits<uint64_t>::max();
+}
+
/// Tests if a given instance of @ref
/// type_suppression::insertion_range::boundary is actually an integer boundary.
///
@@ -1398,13 +1443,13 @@ type_suppression::insertion_range::boundary::~boundary()
/// type_suppression::insertion_range::integer_boundary.
struct type_suppression::insertion_range::integer_boundary::priv
{
- int value_;
+ uint64_t value_;
priv()
: value_()
{}
- priv(int value)
+ priv(uint64_t value)
: value_(value)
{}
}; // end type_suppression::insertion_range::integer_boundary::priv
@@ -1413,22 +1458,22 @@ struct type_suppression::insertion_range::integer_boundary::priv
/// type_suppression::insertion_range::integer_boundary.
///
/// @param value the integer value of the newly created integer boundary.
-type_suppression::insertion_range::integer_boundary::integer_boundary(int value)
+type_suppression::insertion_range::integer_boundary::integer_boundary(uint64_t value)
: priv_(new priv(value))
{}
-/// Return the integer value of the current inace of @ref
+/// Return the integer value of the current instance of @ref
/// type_suppression::insertion_range::integer_boundary.
///
/// @return the integer value of the current boundary.
-int
+uint64_t
type_suppression::insertion_range::integer_boundary::as_integer() const
{return priv_->value_;}
/// Converts the current boundary into an integer value.
///
/// @return the integer value of the current boundary.
-type_suppression::insertion_range::integer_boundary::operator int() const
+type_suppression::insertion_range::integer_boundary::operator uint64_t() const
{return as_integer();}
/// Destructor of @ref type_suppression::insertion_range::integer_boundary.
@@ -1550,6 +1550,17 @@ test-diff-suppr/PR27267/v1.c \
test-diff-suppr/PR27267/libtestpr27267-v0.so \
test-diff-suppr/PR27267/libtestpr27267-v1.so \
test-diff-suppr/PR27267/report-1.txt \
+test-diff-suppr/PR28073/PR28073-bitfield-removed.c \
+test-diff-suppr/PR28073/PR28073-bitfield-removed.o \
+test-diff-suppr/PR28073/PR28073-bitfield-removed.o.abi \
+test-diff-suppr/PR28073/PR28073-output-1.txt \
+test-diff-suppr/PR28073/PR28073-output-2.txt \
+test-diff-suppr/PR28073/PR28073.after.o \
+test-diff-suppr/PR28073/PR28073.after.o.abi \
+test-diff-suppr/PR28073/PR28073.before.o \
+test-diff-suppr/PR28073/PR28073.before.o.abi \
+test-diff-suppr/PR28073/PR28073.c \
+test-diff-suppr/PR28073/bitfield.suppr \
\
test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1 \
test-diff-dwarf-abixml/test0-pr19026-libvtkIOSQL-6.1.so.1.abi \
new file mode 100644
@@ -0,0 +1,14 @@
+/*
+ * Compile this with:
+ * gcc -g -c PR28073-bitfield-removed.c
+ */
+#include <inttypes.h>
+
+struct bigstruct {
+ char name[128];
+ uint8_t other;
+};
+
+void access_bigstruct(struct bigstruct *st __attribute__((unused)))
+{
+}
new file mode 100644
GIT binary patch
literal 3776
zcmbtX&2Jk;6rb_Nv6D^QBra`2KygrMn+mVv0BIVO)+i!PM2SjJkw74KZBOh4dmZhr
zt0bsuD@3J=13_>^q7pqI_ya(K15yR*0VIwb=n;X$0db4O0p6Q^V{fKz_<GXLyx(u$
z$9(Nu`^q!tmSUVUC7hjR9i&*suJ(2Gf>aCa0d|mGSibSo@{P;8JFnjU73etQNgVCL
z=3#82VnzTD4S6hqB<~5kWZ3auBxABUde}mPSR7HjC+@fbB$0?m?2OU$^I#wyukl3k
zQve3KB&8baedZQ0S6RY??h71Tgyss9i{k^*83?8(%0Ku8P`?iu2c}Ssy<1~u@-4LC
zN0@1zHjNaphnSI?H=i<3nJZ~XJBV<Shj<Qx^$hbzQ)$zf7@rvCBZ;BIuo7~I?dnZ)
zBW0Rl01g2XoUf!&NlvnrbPfXaS^UhH%5iKAgA_)$$Izxf&Wxl=9vg+pAApJBJlJD6
zW1K6Khaxp>)biQ{DKA1F2irO5Ip=?*2C>8I01qe=VKBfk&=1H%20$XO4Ucoy*ETZ-
z_?s~UTwAX1R9#WY;OW(yZZ)%qaqWg+#bOIa=ZXO<IaNRKTIGN#rfprW*&dUPjDq2s
zK}~qfuQk13Z&XStt<SDr$SmehX7YJ!#>!`Arf2f`>HMk8@imy#vK`Psc6KV0Z3Hb>
zEL4RnJf{rM_R6(|&AHj^>=T)6mD%O8@cm+El3{9`O0L#yh+L&vdCkdHogi0tN;cTp
zPCd8oYzjZO;RV7E{M`AqnYrnck2C7CB_~*SM7@&rM5B30RIKv9kCkirUe0mL^;SjX
zAfUfr^nDTsTN}c+YRnHRu%;{?feVnGU0j^c9EXjZ`UktHE(P9^3_SS0f-77{{#Eqe
zaKiHPfXzX8Q26#5<C{Z#d?1nBfx(A>!v{rP-=|YU*JF!=y-Q#a(p_7O+rxhUv)dqC
z%x*N4is%eGCPr9YIs|D(SU<Y(-Cs0=4cudkYa5Bor|r4VLEUo^A%@zEe$b<<7^IBI
zW0|`~cqGDO?adQDr11pVgQVcjwO@14PY{psWo;&`;;Fm^;<3b_D83Xzc7}Sz6J$#o
zuh#RN#<vKsY5Wnw7d8GaVOQf{Agto4`K%JZt=X&fT-SK~cA>l%cJ1{}5dKi(Um^UZ
z#(zurHud`ct4|lsQ-1cyZs<Ptj}VXcc<$#2AJzEFgr_zB9l}p){3nFxHU4YD(euT;
z-x0q;y}qst@p#vw_l;TpRwJ-W&<9@F*OV5B&45`IJFuBm@_lA`qHbFiQEF9-j=SE3
zF{#_7k|!?h8MZy!t%|)ab;lLT1yU##>7vBtW}_jX`de-@5EfLqtRL9r*9lkMmbKwE
zH-r~#Q7%y{u6y{&`~NZyA#l&s`KyQpQrdNdFxp0C5&&}1JA>oTV$(%*|6^c-HRr$j
zV|~zLVp^5|Hv|#UZSf}#*11B&2G#GW2<?&s);Y9O^$~t2Nm+nakBI~GM1CZ#I*o37
z9)@%dt?v@4-WwG`x5agKoBthrIY5*@&L1g#{uSW#m_V^XdRbmZ5E0$B2xHyy?^6Dc
z$rtnEuVg*{25=Zt%@b59Rm%UfBB)pSRsRO?-TYVSLjCwR{%_yM{{$`yBo}t=R^?Uw
z`!J&Pwh<^Vk$;p!UAMgj9B$Q~+64F_`Rn_l_76;?V4cU9y8jOOtM5u^-PwPIKLZ6#
z3yPrrCM8n$9M5kE9+hA5-Ew1yJCy$i1R(f#0)2IVyc7Dn4-~se?_U-{MD+a|hOut`
OpHrf5BEG2V{(k{M7*tCD
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,29 @@
+<abi-corpus version='2.1' path='PR28073-bitfield-removed.o' architecture='elf-amd-x86_64'>
+ <elf-function-symbols>
+ <elf-symbol name='access_bigstruct' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ </elf-function-symbols>
+ <abi-instr address-size='64' path='PR28073-bitfield-removed.c' comp-dir-path='/home/dodji/git/libabigail/fixes/prtests/PR28073' language='LANG_C11'>
+ <type-decl name='char' size-in-bits='8' id='type-id-1'/>
+ <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='1024' id='type-id-2'>
+ <subrange length='128' type-id='type-id-3' id='type-id-4'/>
+ </array-type-def>
+ <type-decl name='unsigned char' size-in-bits='8' id='type-id-5'/>
+ <type-decl name='unsigned long int' size-in-bits='64' id='type-id-3'/>
+ <class-decl name='bigstruct' size-in-bits='1032' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/PR28073-bitfield-removed.c' line='7' column='1' id='type-id-6'>
+ <data-member access='public' layout-offset-in-bits='0'>
+ <var-decl name='name' type-id='type-id-2' visibility='default' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/PR28073-bitfield-removed.c' line='8' column='1'/>
+ </data-member>
+ <data-member access='public' layout-offset-in-bits='1024'>
+ <var-decl name='other' type-id='type-id-7' visibility='default' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/PR28073-bitfield-removed.c' line='9' column='1'/>
+ </data-member>
+ </class-decl>
+ <typedef-decl name='uint8_t' type-id='type-id-8' filepath='/usr/include/bits/stdint-uintn.h' line='24' column='1' id='type-id-7'/>
+ <typedef-decl name='__uint8_t' type-id='type-id-5' filepath='/usr/include/bits/types.h' line='38' column='1' id='type-id-8'/>
+ <pointer-type-def type-id='type-id-6' size-in-bits='64' id='type-id-9'/>
+ <function-decl name='access_bigstruct' mangled-name='access_bigstruct' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/PR28073-bitfield-removed.c' line='12' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='access_bigstruct'>
+ <parameter type-id='type-id-9' name='st' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/PR28073-bitfield-removed.c' line='12' column='1'/>
+ <return type-id='type-id-10'/>
+ </function-decl>
+ <type-decl name='void' id='type-id-10'/>
+ </abi-instr>
+</abi-corpus>
new file mode 100644
@@ -0,0 +1,3 @@
+Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
+Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
new file mode 100644
@@ -0,0 +1,14 @@
+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 access_bigstruct(bigstruct*)' at PR28073-bitfield-removed.c:12:1 has some indirect sub-type changes:
+ parameter 1 of type 'bigstruct*' has sub-type changes:
+ in pointed to type 'struct bigstruct' at PR28073-bitfield-removed.c:7:1:
+ type size changed from 1040 to 1032 (in bits)
+ 1 data member deletion:
+ 'uint8_t bitfield0', at offset 1024 (in bits) at plop.c:5:1
+ 1 data member change:
+ 'uint8_t other' offset changed from 1032 to 1024 (in bits) (by -8 bits)
+
new file mode 100644
GIT binary patch
literal 3848
zcmbtXO>7%Q6n^8i6DN*SCoXM5L2(eY2_ow_K$@m%YKYn<{Ha7#LWs&;+Z%hSvyOJx
zC<%f9g(_7q1$shATsVN>zzK@P0SSRB?jSB45k1mdr5@nD**ErPY6L1z+IjDN^ZsV$
z?X10h;+c~%AwZFU1?XrB1-RbVk&99+!acAT&MaN}ed*Hcx0WuSxV7i2D{tb|g`Z+O
zQn+&V`vk^HfJl-@f`<EPh|*X@5uu@o^%5xJAxnl#^bi=6!@>O~8N_7Bo_NA>156?{
z5wSByvd^QP^nY9QC4WH0paA_+ggD8m)F!dGRMK%$L|j^B<jh-;^bq?QpT0#LwxJ(K
z5LsCdiE0VrqZlqX<zp?`NfKl4)nOp{t~7rT6D_2SK}7d~F*u((nmUqN&SF7nQpZK8
z&!w=GT}XOdoX3?VhQvdI*_1JMU~EVX_h$A3^l(hv-QKJ)22-gps=%m8A(pcw^o_%E
zHjh#JO>ulwB|bDtL5d?=qhymxfRR)c#YO-I_F%PC96W-L+;fm;NK28V)~s~JUq&H;
zwsXjZ5Vr@@#Hge2L18QmhI$O;J#y1gVIn&a*ff1@Gb1Y!L+>O+av^45fU*;;I(DO4
zfR^h!HP^1@=<pj&x0c(5xYn8trBVxL=Sl&Tothtbtx5n2X<Jw7mIrc>Q7Bw9sM{X+
z^`;l>j>;*e^{MC1<Q5BubA^IAV-|8V(=&y_bm2&DVg-v@vI3r%nw`u|tpzRDK320`
z+jA<YT3)4oY-4VAYWA_*R1K_3#rFMDr%1KTX)c0_I=wP8H+}d~vjX{gbIs0Io7GpG
ze9Z~+4X13OujMrItIme)=hwZ!_5(l9E_dP3^1Zy{RvN9UoyTJQNcK)0!RET{n|1Jm
zDi%0JJL{qfrxq9Ia}&5flmB6J!lS1~$l*ipFgjw-iSMG#Ay}6kf;M~cArf0FAT~1M
zz(8;E3QpdK7(GO?N1qtXT#PNIdtO3=5bios+&J9)tJ@^@T{jr7l4yk;69d{;LkC33
zfXF2pnK1xg&n{%Zz#S-A4oB)~zlWVuxucmVh*~?{UD2x3G>JqwRehNhq~VZBT;89o
z@6&L37b12q<Fr%lcNgV{87DhBTSWyHRNkjpr+b4);f+v*<IELKoaki8+V*%YN_tkq
zw^?7&aQcoAos(lH?@iWS4L{3zOT%AeeM`fiWc{Lst95>$;ghU?tl@vK{)L9K3g2k>
zD(k;!xYB=PTt6@B0V3L8`4N;FK!&+){{Z7;PknNf^@AF&&T(49-(dZ54c}pXUc=vK
zJ=zbH_d~{)nd^1t7^mKh_9vMB=2~Etkq2JL>q-jjjR4H56<A=FeIHEEZdhj3F1KnW
z$6amWoRqC{*|T5WHEns8TeEk&G#uAfE|@}z1ec^<X|Ao=c+s0~Gq6p(1*iPLs+?!N
z=C;grueok}!6xUj>!nqXzH|Sd4qyn{Gj;wdVv&V01u!SuD2<~+ShQzozC=S8()|yi
z4c$?9>reNI9+T3l{C(P_rpn(rbT1akDMB~+(wg9=p?i_+)O|X_w#Sg`F=?vK;5D{W
zOt(Fa6FNq=InJxzn}70u8YjBdpW#B4Kh;m~i(Y>fv2OWKbN+KUA0^$E_PJaBA}9Kk
zohd(k1@-*vh*3;cCyJ83<ovf4z+B~5{58b8`G3w0_1VAp(|50%{|mGzq<qNQqspuJ
zRh&_B+X#gV>>tHQ)@?sQjLwCZOD2+b*k9ilwSUU)TNEg!?thK_)%Ql(>;7Nk1eq3<
z0rMMdsQR4FFN2TrS9rJF6yi_L|0^j-^q+!!b${v!{oO|huJik+e$x>~r0?GlV%_}J
NPp%)OS7*@u{|4a1N=E<y
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,35 @@
+<abi-corpus version='2.1' path='PR28073.after.o' architecture='elf-amd-x86_64'>
+ <elf-function-symbols>
+ <elf-symbol name='access_bigstruct' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ </elf-function-symbols>
+ <abi-instr address-size='64' path='PR28073.c' comp-dir-path='/home/dodji/git/libabigail/fixes/prtests/PR28073' language='LANG_C11'>
+ <type-decl name='char' size-in-bits='8' id='type-id-1'/>
+ <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='1024' id='type-id-2'>
+ <subrange length='128' type-id='type-id-3' id='type-id-4'/>
+ </array-type-def>
+ <type-decl name='unsigned char' size-in-bits='8' id='type-id-5'/>
+ <type-decl name='unsigned long int' size-in-bits='64' id='type-id-3'/>
+ <class-decl name='bigstruct' size-in-bits='1040' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/PR28073.c' line='9' column='1' id='type-id-6'>
+ <data-member access='public' layout-offset-in-bits='0'>
+ <var-decl name='name' type-id='type-id-2' visibility='default' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/PR28073.c' line='10' column='1'/>
+ </data-member>
+ <data-member access='public' layout-offset-in-bits='1024'>
+ <var-decl name='bitfield0' type-id='type-id-7' visibility='default' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/PR28073.c' line='11' column='1'/>
+ </data-member>
+ <data-member access='public' layout-offset-in-bits='1025'>
+ <var-decl name='bitfield1' type-id='type-id-7' visibility='default' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/PR28073.c' line='13' column='1'/>
+ </data-member>
+ <data-member access='public' layout-offset-in-bits='1032'>
+ <var-decl name='other' type-id='type-id-7' visibility='default' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/PR28073.c' line='16' column='1'/>
+ </data-member>
+ </class-decl>
+ <typedef-decl name='uint8_t' type-id='type-id-8' filepath='/usr/include/bits/stdint-uintn.h' line='24' column='1' id='type-id-7'/>
+ <typedef-decl name='__uint8_t' type-id='type-id-5' filepath='/usr/include/bits/types.h' line='38' column='1' id='type-id-8'/>
+ <pointer-type-def type-id='type-id-6' size-in-bits='64' id='type-id-9'/>
+ <function-decl name='access_bigstruct' mangled-name='access_bigstruct' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/PR28073.c' line='19' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='access_bigstruct'>
+ <parameter type-id='type-id-9' name='st' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/PR28073.c' line='19' column='1'/>
+ <return type-id='type-id-10'/>
+ </function-decl>
+ <type-decl name='void' id='type-id-10'/>
+ </abi-instr>
+</abi-corpus>
new file mode 100644
GIT binary patch
literal 3768
zcmbtXO>7%Q6rS<giIa_8CoXN$fa0LiHVE&=0n#)mtx-f83#dX+IUtZ(+Z%hSy|#AO
z$O%HFm53B^Nd*TENO0i5sp<(3;!p{R190NRg(KohPau#e@6En(HiIirdD8B@@0<5G
zKl_|qedf8f80Sn1XXn`gk}PArkpsOb)FOL;9c7o-_kLdAd+Yc8SHJ!P=mg_QoQ>n_
zA$&zej{qJT^4KtvJRT0oaNt8o#>DH?aRUuv2}Fr_!f^vgA`p+*X_MI(z(6=&=UVbh
z02;c)h04Of34I$V&f;QfRG@1t=>hpIJR_^{y2?i3&3H=0LRHqyKl}}m4+W&=P>tPa
zu(9MjXv0r3T|cjDX<&~rExoKirJvJFS*Rj~aF&O734+DP`6KD9uFXu(jPr@%%yC#4
zxx?-aWx1Bt^)LX30K*~x#Y^c|VC_lHOIe&7nPsJ{2{A_veql<cJw1hSi<3K3Xrm{X
zmX!6xCK($$0<~gk>@i#fme0ho2@PLz#eIU5mtahQ?GlWf^FPxm9Pq-x1IkPo3~&te
zBjOqWAQ2afCpa7Fn`tS&8`HqG>-tXJwQD&%-)7sb=MFKh)v{T++=bbta=<E1-4DEO
zHDHqITUQ&F$HYrS!Eo)MVSCJPw7uYPR7xqVFJ8KwTP>W;6$-|JQOGUKFBA&%g>$(x
zn^4rc70^U}aW0o{1zp!(soSpYIaPp`S8c5HmKO7iPvr7-W>u@U@0SmXtT@4zV>fH_
zR0I~)X|_8?m6?rp%QkE6+Ut&4cLKBNR4j0`oTj<u^labkc!BK)zPYivurz=6@%wP-
z`kv{y)n>P5n^1`_Q&R=OcE|RO2J?d&)Ro5#bpf)AtE<boGq5dl|6xz$5#x#H;KA<`
zT;X!@+tFLV35%-$Hb>z>;X9j*_cDBXY&f|OlMe!i4~n>qPp31xvDMVj8W@E1z&FN?
zvpaVOO~N%BL_?d1R(N2dh27+UAWdVDW*C{(?(x}ZY%F3Gs<?)UNIm@zjt=D?SBN6W
zwPTBlR-K}G<gssEBRmn|MGGW+OyT9+3F2|5`X4Fik4Ef8?<HJ_@R+wq7#jqNtfvw}
zc7aC86J%=&FW2+D!gmR8D*Q>puPOX5gk6Pyk+6&>>$ybyj$$v@v#ap<+l2C7IP}*$
zL--?w|B3KTg@1+ccMAVK;U8#J&jt4!1?v~TX#z2pp;5Jen0U0uGneZ+rSJ~nd4+$I
z@RJIEo$#{4?-7okJLbJXe2GT2&K&VE81d<g;cvGBtHKQE|KZq>T447AX4I^}Vn)UH
znc>+@%c$9vZoTZdTWy#Vx>c!o_8W($Ezff6_F<Q%<J!^%Qb-l)vcT1Lt7StcH{5n$
z8_@0YeqdFv5U#sjqvN$Zwij$uF1u0Q^6-c3|I0Llz&(@aFC!L7>Gu=DXd9JT0LVq}
z49-7`uK}X^p9UN3MfdBEeM60jX=VPu5JW_^#XnrI{}m%PsNSOHl%Y$5{SWPA-<(7v
zkQI2;n8=ri{0u=vRND=hQ#mxhOQig6WC+z3*Ey*E+xT&SNPny!DYgC@aB57Tm`Uq?
z89_u;+cL}z%Kt0n|CD?&KmOXO`8&X2Oj#$WLiQ;C9ZAqA^UD$Y$RPh6x=<hgi~qa#
z@IQfz0x`p(|CV{>_&&@?y>A3ciTtA+>Z<K0z~NTWa?wP{2KlS|BKJ?)eFX}}RQ=y3
zf7zF%z3TrtOrU8|8qoLw8OnQ(=a+#;`b&OLZVd4S<^K@@2>z3RzN$ao3H93titW?)
YH-#V~>i&(x+#vs3l<1p?FRH5l-+ZY+KmY&$
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,32 @@
+<abi-corpus version='2.1' path='PR28073.before.o' architecture='elf-amd-x86_64'>
+ <elf-function-symbols>
+ <elf-symbol name='access_bigstruct' type='func-type' binding='global-binding' visibility='default-visibility' is-defined='yes'/>
+ </elf-function-symbols>
+ <abi-instr address-size='64' path='plop.c' comp-dir-path='/home/dodji/git/libabigail/fixes/prtests/PR28073' language='LANG_C11'>
+ <type-decl name='char' size-in-bits='8' id='type-id-1'/>
+ <array-type-def dimensions='1' type-id='type-id-1' size-in-bits='1024' id='type-id-2'>
+ <subrange length='128' type-id='type-id-3' id='type-id-4'/>
+ </array-type-def>
+ <type-decl name='unsigned char' size-in-bits='8' id='type-id-5'/>
+ <type-decl name='unsigned long int' size-in-bits='64' id='type-id-3'/>
+ <class-decl name='bigstruct' size-in-bits='1040' is-struct='yes' visibility='default' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/plop.c' line='3' column='1' id='type-id-6'>
+ <data-member access='public' layout-offset-in-bits='0'>
+ <var-decl name='name' type-id='type-id-2' visibility='default' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/plop.c' line='4' column='1'/>
+ </data-member>
+ <data-member access='public' layout-offset-in-bits='1024'>
+ <var-decl name='bitfield0' type-id='type-id-7' visibility='default' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/plop.c' line='5' column='1'/>
+ </data-member>
+ <data-member access='public' layout-offset-in-bits='1032'>
+ <var-decl name='other' type-id='type-id-7' visibility='default' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/plop.c' line='10' column='1'/>
+ </data-member>
+ </class-decl>
+ <typedef-decl name='uint8_t' type-id='type-id-8' filepath='/usr/include/bits/stdint-uintn.h' line='24' column='1' id='type-id-7'/>
+ <typedef-decl name='__uint8_t' type-id='type-id-5' filepath='/usr/include/bits/types.h' line='38' column='1' id='type-id-8'/>
+ <pointer-type-def type-id='type-id-6' size-in-bits='64' id='type-id-9'/>
+ <function-decl name='access_bigstruct' mangled-name='access_bigstruct' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/plop.c' line='13' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='access_bigstruct'>
+ <parameter type-id='type-id-9' name='st' filepath='/home/dodji/git/libabigail/fixes/prtests/PR28073/plop.c' line='13' column='1'/>
+ <return type-id='type-id-10'/>
+ </function-decl>
+ <type-decl name='void' id='type-id-10'/>
+ </abi-instr>
+</abi-corpus>
new file mode 100644
@@ -0,0 +1,24 @@
+/*
+ * Compile this twice:
+ * gcc -g -c -DBEFORE -o PR28073.before.o PR28073.c
+ * gcc -g -c -o PR28073.after.o PR28073.c
+ */
+
+#include <inttypes.h>
+
+struct bigstruct {
+ char name[128];
+ uint8_t bitfield0:1
+ #ifndef BEFORE
+ ,bitfield1:1
+ #endif
+ ;
+ uint8_t other;
+};
+
+void access_bigstruct(struct bigstruct *st)
+{
+ #ifndef BEFORE
+ st->bitfield1 = 1;
+ #endif
+}
new file mode 100644
@@ -0,0 +1,4 @@
+[suppress_type]
+ name = bigstruct
+ type_kind = struct
+ has_data_member_inserted_between = {offset_of(bitfield0), offset_of(other)}
@@ -2036,6 +2036,26 @@ InOutSpec in_out_specs[] =
"data/test-diff-suppr/PR27267/report-1.txt",
"output/test-diff-suppr/PR27267/report-1.txt"
},
+ {
+ "data/test-diff-suppr/PR28073/PR28073.before.o.abi",
+ "data/test-diff-suppr/PR28073/PR28073.after.o.abi",
+ "",
+ "",
+ "data/test-diff-suppr/PR28073/bitfield.suppr",
+ "--drop-private-types --no-default-suppression",
+ "data/test-diff-suppr/PR28073/PR28073-output-1.txt",
+ "output/test-diff-suppr/PR28073/PR28073-output-1.txt"
+ },
+ {
+ "data/test-diff-suppr/PR28073/PR28073.before.o.abi",
+ "data/test-diff-suppr/PR28073/PR28073-bitfield-removed.o.abi",
+ "",
+ "",
+ "data/test-diff-suppr/PR28073/bitfield.suppr",
+ "--drop-private-types --no-default-suppression",
+ "data/test-diff-suppr/PR28073/PR28073-output-2.txt",
+ "output/test-diff-suppr/PR28073/PR28073-output-2.txt"
+ },
// This should be the last entry
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}
};