From d2c88645e88a85812331fbed8b2a1471c59b5b5b Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Wed, 4 Sep 2019 10:36:31 +0200 Subject: [PATCH] Support the "name_not_regexp" property in the [suppress_type] section When writting a suppression specification in which the user wants to keep a family of types (whose names set is specified by a regular expression) and suppress/drop all other types, one needs to write something like: [suppress_type] name_regexp = (?!the-regexp-of-the-types-to-keep) It would be nicer (like what is done for other properties that take regular expressions as value in suppression specifications) to be able to write: [suppress_type] name_not_regexp = the-regexp-of-types-to-keep This patch does just that. It augments the abigail::suppr::type_suppression type to make it carry the new 'name_not_regex' property. It updates the suppression engine to take the 'name_not_regex' property into account when interpreting instances of abigail::suppr::type_suppression. The parser for type suppression directives is updated to recognize the new name_not_regexp property. The manual has been updated accordingly to describe the new property. New regression tests have been added. * doc/manuals/libabigail-concepts.rst: Update this to document the new name_not_regexp property of the suppress_type directive. * include/abg-suppression.h (type_suppression::{g,s}et_type_name_not_regex_str): Declare new accessors. * src/abg-suppression-priv.h (type_suppression::priv::{type_name_not_regex_str_, type_name_not_regex_}): Define new data members. (type_suppression::priv::{get_type_name_not_regex, set_type_name_not_regex, get_type_name_not_regex_str, set_type_name_not_regex_str}): Define new member functions. * src/abg-suppression.cc (type_suppression::get_type_name_regex_str): Fix comments. (type_suppression::{set_type_name_not_regex_str, get_type_name_not_regex_str}): Define new data members. (suppression_matches_type_name): Adapt to support the new type_name_not_regex property. (read_type_suppression): Support parsing the type_name_not_regexp property. * tests/data/test-diff-suppr/test42-negative-suppr-type-report-0.txt: New test reference output. * tests/data/test-diff-suppr/test42-negative-suppr-type-report-1.txt: Likewise. * tests/data/test-diff-suppr/test42-negative-suppr-type-suppr-1.txt: New test input. * tests/data/test-diff-suppr/test42-negative-suppr-type-suppr-2.txt: Likewise. * tests/data/test-diff-suppr/test42-negative-suppr-type-v0.{cc, o}: Likewise. * tests/data/test-diff-suppr/test42-negative-suppr-type-v1.{cc, o}: Likewise. * tests/data/Makefile.am: Add the test files above to source distribution. * tests/test-diff-suppr.cc (int_out_specs): Add the new tests to the harness. Signed-off-by: Dodji Seketeli --- doc/manuals/libabigail-concepts.rst | 17 +++++- include/abg-suppression.h | 6 ++ src/abg-suppression-priv.h | 52 ++++++++++++++++ src/abg-suppression.cc | 66 +++++++++++++++++---- tests/data/Makefile.am | 8 +++ .../test42-negative-suppr-type-report-0.txt | 12 ++++ .../test42-negative-suppr-type-report-1.txt | 12 ++++ .../test42-negative-suppr-type-suppr-1.txt | 3 + .../test42-negative-suppr-type-suppr-2.txt | 2 + .../test42-negative-suppr-type-v0.cc | 20 +++++++ .../test42-negative-suppr-type-v0.o | Bin 0 -> 3200 bytes .../test42-negative-suppr-type-v1.cc | 22 +++++++ .../test42-negative-suppr-type-v1.o | Bin 0 -> 3272 bytes tests/test-diff-suppr.cc | 20 +++++++ 14 files changed, 228 insertions(+), 12 deletions(-) create mode 100644 tests/data/test-diff-suppr/test42-negative-suppr-type-report-0.txt create mode 100644 tests/data/test-diff-suppr/test42-negative-suppr-type-report-1.txt create mode 100644 tests/data/test-diff-suppr/test42-negative-suppr-type-suppr-1.txt create mode 100644 tests/data/test-diff-suppr/test42-negative-suppr-type-suppr-2.txt create mode 100644 tests/data/test-diff-suppr/test42-negative-suppr-type-v0.cc create mode 100644 tests/data/test-diff-suppr/test42-negative-suppr-type-v0.o create mode 100644 tests/data/test-diff-suppr/test42-negative-suppr-type-v1.cc create mode 100644 tests/data/test-diff-suppr/test42-negative-suppr-type-v1.o diff --git a/doc/manuals/libabigail-concepts.rst b/doc/manuals/libabigail-concepts.rst index aeb99aa..a1835d1 100644 --- a/doc/manuals/libabigail-concepts.rst +++ b/doc/manuals/libabigail-concepts.rst @@ -247,8 +247,9 @@ Note that for the ``[suppress_type]`` directive to work, at least one of the following properties must be provided: ``file_name_regexp``, ``file_name_not_regexp``, ``soname_regexp``, - ``soname_not_regexp``, ``name``, ``name_regexp``, ``type_kind``, - ``source_location_not_in``, ``source_location_not_regexp``. + ``soname_not_regexp``, ``name``, ``name_regexp``, + ``name_not_regexp``, ``type_kind``, ``source_location_not_in``, + ``source_location_not_regexp``. If none of the following properties are provided, then the ``[suppress_type]`` directive is simply ignored. @@ -305,6 +306,18 @@ The potential properties of this sections are listed below: Suppresses change reports involving types whose name matches the regular expression specified as value of this property. + +* ``name_not_regexp`` + + Usage: + + ``name_not_regexp`` ``=`` <:ref:`regular-expression `> + + Suppresses change reports involving types whose name does *NOT* match + the regular expression specified as value of this property. Said + otherwise, this property specifies which types to keep, rather than + types to suppress from reports. + * ``name`` Usage: diff --git a/include/abg-suppression.h b/include/abg-suppression.h index 415e74f..47dac5a 100644 --- a/include/abg-suppression.h +++ b/include/abg-suppression.h @@ -201,6 +201,12 @@ public: get_type_name_regex_str() const; void + set_type_name_not_regex_str(const string& name_regex_str); + + const string& + get_type_name_not_regex_str() const; + + void set_type_name(const string& name); const string& diff --git a/src/abg-suppression-priv.h b/src/abg-suppression-priv.h index f157c35..07e1718 100644 --- a/src/abg-suppression-priv.h +++ b/src/abg-suppression-priv.h @@ -675,6 +675,8 @@ class type_suppression::priv string type_name_regex_str_; mutable sptr_utils::regex_t_sptr type_name_regex_; string type_name_; + string type_name_not_regex_str_; + mutable sptr_utils::regex_t_sptr type_name_not_regex_; bool consider_type_kind_; type_suppression::type_kind type_kind_; bool consider_reach_kind_; @@ -734,6 +736,56 @@ public: set_type_name_regex(sptr_utils::regex_t_sptr r) {type_name_regex_ = r;} + /// Get the regular expression object associated to the + /// 'type_name_not_regex' property of @ref type_suppression. + /// + /// If the regular expression object is not created, this method + /// creates it and returns it. + /// + /// If the 'type_name_not_regex' property of @ref type_suppression is + /// empty then this method returns nil. + const sptr_utils::regex_t_sptr + get_type_name_not_regex() const + { + if (!type_name_not_regex_) + { + if (!type_name_not_regex_str_.empty()) + { + sptr_utils::regex_t_sptr r = sptr_utils::build_sptr(); + if (regcomp(r.get(), + type_name_not_regex_str_.c_str(), + REG_EXTENDED) == 0) + type_name_not_regex_ = r; + } + } + return type_name_not_regex_; + } + + /// Setter for the type_name_not_regex object. + /// + /// @param r the new type_name_not_regex object. + void + set_type_name_not_regex(sptr_utils::regex_t_sptr r) + {type_name_not_regex_ = r;} + + /// Getter for the string that denotes the 'type_name_not_regex' + /// property. + /// + /// @return the value of the string value of the + /// 'type_name_not_regex' property. + const string& + get_type_name_not_regex_str() const + {return type_name_not_regex_str_;} + + /// Setter for the string that denotes the 'type_name_not_regex' + /// property. + /// + /// @return the value of the string value of the + /// 'type_name_not_regex' property. + void + set_type_name_not_regex_str(const string regex_str) + {type_name_not_regex_str_ = regex_str;} + /// Getter for the source_location_to_keep_regex object. /// /// This function builds the regex if it's not yet built. diff --git a/src/abg-suppression.cc b/src/abg-suppression.cc index e410d36..1c10c8e 100644 --- a/src/abg-suppression.cc +++ b/src/abg-suppression.cc @@ -406,14 +406,36 @@ type_suppression::set_type_name_regex_str(const string& name_regex_str) /// Getter for the "type_name_regex" property of the type suppression /// specification. /// -/// This returns a regular expression that specifies the family of -/// types about which diff reports should be suppressed. +/// This returns a regular expression string that specifies the family +/// of types about which diff reports should be suppressed. /// -/// @return the regular expression. +/// @return the regular expression string. const string& type_suppression::get_type_name_regex_str() const {return priv_->type_name_regex_str_;} +/// Setter for the "type_name_not_regex_str" property of the type +/// suppression specification. +/// +/// This returns a regular expression string that specifies the family +/// of types that should be kept after suppression. +/// +/// @param r the new regexp string. +void +type_suppression::set_type_name_not_regex_str(const string& r) +{priv_->set_type_name_not_regex_str(r);} + +/// Getter for the "type_name_not_regex_str" property of the type +/// suppression specification. +/// +/// This returns a regular expression string that specifies the family +/// of types that should be kept after suppression. +/// +/// @return the new regexp string. +const string& +type_suppression::get_type_name_not_regex_str() const +{return priv_->get_type_name_not_regex_str();} + /// Setter for the name of the type about which diff reports should be /// suppressed. /// @@ -921,7 +943,9 @@ bool suppression_matches_type_name(const type_suppression& s, const string& type_name) { - if (!s.get_type_name().empty() || s.priv_->get_type_name_regex()) + if (!s.get_type_name().empty() + || s.priv_->get_type_name_regex() + || s.priv_->get_type_name_not_regex()) { // Check if there is an exact type name match. if (!s.get_type_name().empty()) @@ -936,12 +960,23 @@ suppression_matches_type_name(const type_suppression& s, // If the qualified name of the considered type doesn't match // the regular expression of the type name, then this // suppression doesn't apply. - const sptr_utils::regex_t_sptr& type_name_regex = - s.priv_->get_type_name_regex(); - if (type_name_regex && (regexec(type_name_regex.get(), - type_name.c_str(), - 0, NULL, 0) != 0)) - return false; + if (const sptr_utils::regex_t_sptr& type_name_regex = + s.priv_->get_type_name_regex()) + { + if (regexec(type_name_regex.get(), + type_name.c_str(), + 0, NULL, 0) != 0) + return false; + } + + if (const sptr_utils::regex_t_sptr type_name_not_regex = + s.priv_->get_type_name_not_regex()) + { + if (regexec(type_name_not_regex.get(), + type_name.c_str(), + 0, NULL, 0) == 0) + return false; + } } } @@ -1530,6 +1565,12 @@ read_type_suppression(const ini::config::section& section) ? name_regex_prop->get_value()->as_string() : ""; + ini::simple_property_sptr name_not_regex_prop = + is_simple_property(section.find_property("name_not_regexp")); + string name_not_regex_str = name_not_regex_prop + ? name_not_regex_prop->get_value()->as_string() + : ""; + ini::simple_property_sptr name_prop = is_simple_property(section.find_property("name")); string name_str = name_prop @@ -1774,6 +1815,8 @@ read_type_suppression(const ini::config::section& section) && soname_regex_str.empty() && soname_not_regex_str.empty() && (!name_regex_prop || name_regex_prop->get_value()->as_string().empty()) + && (!name_not_regex_prop + || name_not_regex_prop->get_value()->as_string().empty()) && (!name_prop || name_prop->get_value()->as_string().empty()) && !consider_type_kind && srcloc_not_regexp_str.empty() @@ -1798,6 +1841,9 @@ read_type_suppression(const ini::config::section& section) if (consider_data_member_insertion) suppr->set_data_member_insertion_ranges(insert_ranges); + if (!name_not_regex_str.empty()) + suppr->set_type_name_not_regex_str(name_not_regex_str); + if (!file_name_regex_str.empty()) suppr->set_file_name_regex_str(file_name_regex_str); diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 57551db..70b290a 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -1205,6 +1205,14 @@ test-diff-suppr/test41-enumerator-changes-0.suppr \ test-diff-suppr/test41-enumerator-changes-report-0.txt \ test-diff-suppr/test41-enumerator-changes-v0.cc \ test-diff-suppr/test41-enumerator-changes-v1.cc \ +test-diff-suppr/test42-negative-suppr-type-report-0.txt \ +test-diff-suppr/test42-negative-suppr-type-report-1.txt \ +test-diff-suppr/test42-negative-suppr-type-suppr-1.txt \ +test-diff-suppr/test42-negative-suppr-type-suppr-2.txt \ +test-diff-suppr/test42-negative-suppr-type-v0.cc \ +test-diff-suppr/test42-negative-suppr-type-v0.o \ +test-diff-suppr/test42-negative-suppr-type-v1.cc \ +test-diff-suppr/test42-negative-suppr-type-v1.o \ test-diff-suppr/test43-suppr-direct-fn-subtype-suppr-1.txt \ test-diff-suppr/test43-suppr-direct-fn-subtype-v0.cc \ test-diff-suppr/test43-suppr-direct-fn-subtype-v0.o \ diff --git a/tests/data/test-diff-suppr/test42-negative-suppr-type-report-0.txt b/tests/data/test-diff-suppr/test42-negative-suppr-type-report-0.txt new file mode 100644 index 0000000..a73ca07 --- /dev/null +++ b/tests/data/test-diff-suppr/test42-negative-suppr-type-report-0.txt @@ -0,0 +1,12 @@ +Functions changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added functions +Variables changes summary: 0 Removed, 0 Changed, 0 Added variable + +1 function with some indirect sub-type change: + + [C]'function void func0(type_to_keep)' at test42-negative-suppr-type-v1.cc:15:1 has some indirect sub-type changes: + parameter 1 of type 'struct type_to_keep' has sub-type changes: + type size changed from 32 to 64 (in bits) + 1 data member insertion: + 'char type_to_keep::m1', at offset 32 (in bits) at test42-negative-suppr-type-v1.cc:4:1 + + diff --git a/tests/data/test-diff-suppr/test42-negative-suppr-type-report-1.txt b/tests/data/test-diff-suppr/test42-negative-suppr-type-report-1.txt new file mode 100644 index 0000000..a73ca07 --- /dev/null +++ b/tests/data/test-diff-suppr/test42-negative-suppr-type-report-1.txt @@ -0,0 +1,12 @@ +Functions changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added functions +Variables changes summary: 0 Removed, 0 Changed, 0 Added variable + +1 function with some indirect sub-type change: + + [C]'function void func0(type_to_keep)' at test42-negative-suppr-type-v1.cc:15:1 has some indirect sub-type changes: + parameter 1 of type 'struct type_to_keep' has sub-type changes: + type size changed from 32 to 64 (in bits) + 1 data member insertion: + 'char type_to_keep::m1', at offset 32 (in bits) at test42-negative-suppr-type-v1.cc:4:1 + + diff --git a/tests/data/test-diff-suppr/test42-negative-suppr-type-suppr-1.txt b/tests/data/test-diff-suppr/test42-negative-suppr-type-suppr-1.txt new file mode 100644 index 0000000..93a8696 --- /dev/null +++ b/tests/data/test-diff-suppr/test42-negative-suppr-type-suppr-1.txt @@ -0,0 +1,3 @@ +[suppress_type] + name_not_regexp = type_to_keep + diff --git a/tests/data/test-diff-suppr/test42-negative-suppr-type-suppr-2.txt b/tests/data/test-diff-suppr/test42-negative-suppr-type-suppr-2.txt new file mode 100644 index 0000000..aa6f67a --- /dev/null +++ b/tests/data/test-diff-suppr/test42-negative-suppr-type-suppr-2.txt @@ -0,0 +1,2 @@ +[suppress_type] + name_regexp = type_to_suppress diff --git a/tests/data/test-diff-suppr/test42-negative-suppr-type-v0.cc b/tests/data/test-diff-suppr/test42-negative-suppr-type-v0.cc new file mode 100644 index 0000000..9469133 --- /dev/null +++ b/tests/data/test-diff-suppr/test42-negative-suppr-type-v0.cc @@ -0,0 +1,20 @@ +struct type_to_keep +{ + int m0; +}; + +struct type_to_suppress +{ + int m0; +}; + + +void +func0(struct type_to_keep) +{ +} + +void +func1(struct type_to_suppress) +{ +} diff --git a/tests/data/test-diff-suppr/test42-negative-suppr-type-v0.o b/tests/data/test-diff-suppr/test42-negative-suppr-type-v0.o new file mode 100644 index 0000000000000000000000000000000000000000..a40c62fa4e7503b0114f368ad25bc7c3cf44805e GIT binary patch literal 3200 zcmbVP&2Jl35TEBwYzNm?5`#z-4hDf}RCfK*Buxt`hP1R11x0}ZLPBP3Kif;<583M| z1)*LLQZG;t2#`1+@dqFd+>!VP_#2RrIKmBy1I)aAV?VzvDs-g0nfcAZ~Zh8zDMhv@<^*hk*t7dST^JY$#X(n zMdox%ARLkqnwt-LA!u{5$>wxqo+lrXrIBet3*zgKP)fQuBtCf?RNKNV2~*GH4ebSD zNj#CuXPn$xZb>Ys79Ymwyl`@v%%#lJ8Ii~Cvf!ji*~@Qdu))V6lewI6(g5?Gcy`sv zk*%kqt1DkTze+L5dDzP*Rsd45E?E32Y5@NLFp)ts4IB6?C@0_ojzavE%i^fk4kubb zC`aK&#qG(q9|p(L9gPQrp&Q;BNcXtpH5yTxg{T}VPF9R7<3s|Jw8p(g3COh;_G>Co zjz&;>b5mK$6*e78IbgV4-ePzX!GQ8BcKTgeZ1$V)1jTj`7LS6uUk}=Ta8y(QMe2A| zZ2Fh-nO?{sFcc^rLD^O!r24aEL``)2zSq4TrarY zaNLtSZP}B{d#>Uk7vyO(C@Y7Y{*g2lN^F2z-#ooU5T%s*XxJU!yCyRg?{5uCz737Yv^}* zp>+TE%hoWE=8)%^^HjB9KSbnf(xa#lX5T0WrjsGt@lT?S_Urw|moe7PN#(fy52P4m z`_cnUzfh`%4~hGFv+e5u+Hd5?XA2*7MLRg!ImwXH;ED2@4z}+;nrw``Z)>nL4ONou z`y!%o{ePnul;f#?`YmMl-$cyLi4c6J!PiMK$o8$FEw290x<1bn)u*#%*B>B8Ik`_1 z6(#i{b*zG{GJg-f2h8{tZ$L z;_qkZGZf~+^7CYO(DG+vB_wEKjn>! PU(x?Bd^?GZ1Uvp8a{mmy literal 0 HcmV?d00001 diff --git a/tests/data/test-diff-suppr/test42-negative-suppr-type-v1.cc b/tests/data/test-diff-suppr/test42-negative-suppr-type-v1.cc new file mode 100644 index 0000000..bd18e5d --- /dev/null +++ b/tests/data/test-diff-suppr/test42-negative-suppr-type-v1.cc @@ -0,0 +1,22 @@ +struct type_to_keep +{ + int m0; + char m1; +}; + +struct type_to_suppress +{ + int m0; + char m1; +}; + + +void +func0(struct type_to_keep) +{ +} + +void +func1(struct type_to_suppress) +{ +} diff --git a/tests/data/test-diff-suppr/test42-negative-suppr-type-v1.o b/tests/data/test-diff-suppr/test42-negative-suppr-type-v1.o new file mode 100644 index 0000000000000000000000000000000000000000..6769db888322b55d6d3cb92b11241dc3f9996a40 GIT binary patch literal 3272 zcmbtWO>7%g5T56?W2bK1BnFWv91P+oQM>D(CLt}P7(!_x5JH6lss!%Zezup!YiqrU zQV`-N2vLaxAS6KI))Rsg2hK>`IdJ2Ogy^xHdnhw+-_)Czt;)|x``*kqzdP?|_uaG4 zKbsN)m;{`GvBW4qE;r`uimgKtX5qr-)ju|`zH{UCpU2!Us81`KoC+233W$b#Vtk7D zoDeVKWc4c`EaH%@f=IuLTpH5pjOT}t5fh}*4%zpW6*^3g9gai}%1#_3Yo;Tb5#M}= zT-L@R_1Ps*ZzbaOz}PbThPDDRBOWdk^HyP@Fe7HO)AylwQCNk1{&fEFyeMM5Q()yt z*eb5&vFL{&pFfkgFn&g}1%L@hJUMR_$jn!P>T_Q{Jx}i03~UusbJ&SQ6RhI|)q)S2 zsF8;QwKItGOZcSVF&u@sS(w66tuii%fKZOY<(lowt{Zy0(jM&$hk+el8A^M%>a zn8_#|3f3{PU)xWmFi2;|Z&iRy8{wd#9OY;Pjf*QvQ?0S;vXn!HtJPJ8Z+kGH?8?1C zUzXd0_M2Y0>xJcQujw|uuIp`=l|z{-9+lf}=qlE3d!0^HHc;LwoO|IyY2*0u(z3JW ztdwe%>Pls`cCxg1Ubah{ZW!VA$x}-uyC3fOa=j~k8F(!e-JsQ5-&n67g{|x z_y-+2x3O`$w1{b!?w%7{$jc<&IuBxRS}YvR=03&6xF2=&5UHK_RAKs~)W+1rSu{Y5 zbWe~HDM=q`4v%#3((u=NH)VDb() zo}>h_U@8HnIC#bq$bzGX&<7EjjrD;~{V9#J%=6uM#J@iRR1|lL@-R<0S4=o{=PLq{ zW}->$1;YQ-^1TNBik9c~O#30ex=S(p_=V!caEiaB<% zx=ozJAewv3g>o+hhb}d6ns|vif!ubTwruWn8=l`8pic2_vl+|IcXw{i%oCXAW1_4Bvl@lWm+H zK!Gsxrg=GT6yr_*M^Q)n_`mvB(btSg={WzdB*e(HJ%Kv<&#A|3h<#6Qww`vN{YG|t z=J1oRXdOp0CMh1#;J&gN52h{s1DP0Ef2+aD*i~_+?Q@7G)qhtyw-GaA zA_Tu_kbcbKWZKd_l9Yc=e=@jFl%MV;Gyf1Vipg~%tEi$6Y4j(`=(tv{<84$W`LF2> z#rF$GU_YKe)c&mJxnpiftzbX4`x+U-;&%$^dfNXr5@N*f&(IghB=xVN`^SBu{?S*G y{kgA6xheKfIzR7U`u@<@*Yu|~NqW^qz5n?fp_wA{{V8se|0P}jHSNcf>Hjz79uw~X literal 0 HcmV?d00001 diff --git a/tests/test-diff-suppr.cc b/tests/test-diff-suppr.cc index dfc8288..55f8f85 100644 --- a/tests/test-diff-suppr.cc +++ b/tests/test-diff-suppr.cc @@ -1749,6 +1749,26 @@ InOutSpec in_out_specs[] = "output/test-diff-suppr/test41-enumerator-changes-report-0.txt" }, { + "data/test-diff-suppr/test42-negative-suppr-type-v0.o", + "data/test-diff-suppr/test42-negative-suppr-type-v1.o", + "", + "", + "data/test-diff-suppr/test42-negative-suppr-type-suppr-1.txt", + "--no-default-suppression", + "data/test-diff-suppr/test42-negative-suppr-type-report-0.txt", + "output/test-diff-suppr/test42-negative-suppr-type-report-0.txt" + }, + { + "data/test-diff-suppr/test42-negative-suppr-type-v0.o", + "data/test-diff-suppr/test42-negative-suppr-type-v1.o", + "", + "", + "data/test-diff-suppr/test42-negative-suppr-type-suppr-2.txt", + "--no-default-suppression", + "data/test-diff-suppr/test42-negative-suppr-type-report-1.txt", + "output/test-diff-suppr/test42-negative-suppr-type-report-1.txt" + }, + { "data/test-diff-suppr/test43-suppr-direct-fn-subtype-v0.o", "data/test-diff-suppr/test43-suppr-direct-fn-subtype-v1.o", "", -- 2.7.4