[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bug default/19082] New: Make abipkgdiff recognize suppression specifications to apply to comparisons



Hey, here's my take on this issue.
I went a little nuts with testing, but I guess it can't hurt ;).

minor patch comment:
I realize taking suppression_paths out of opts isn't very forward-looking
if we're gonna roll in with pthreads soon, but it makes sense for this patch
and I didn't want to feed every function with every single local object (yet).

On 07.10.2015 11:54, dodji at redhat dot com wrote:
https://sourceware.org/bugzilla/show_bug.cgi?id=19082

             Bug ID: 19082
            Summary: Make abipkgdiff recognize suppression specifications
                     to apply to comparisons
            Product: libabigail
            Version: unspecified
             Status: NEW
           Severity: enhancement
           Priority: P2
          Component: default
           Assignee: dodji at redhat dot com
           Reporter: dodji at redhat dot com
                 CC: libabigail at sourceware dot org
   Target Milestone: ---

When abipkgdiff encounters files with the name pattern *.abignore inside the
package it's analyzing, it should consider that as a suppression specification
and apply it to all the comparisons that happens inside that package.


Thanks,
  Ondrej

>From a9317b8c79305cb066f4c7c94b02065b2b197bf2 Mon Sep 17 00:00:00 2001
From: Ondrej Oprala <ooprala@redhat.com>
Date: Thu, 8 Oct 2015 10:43:20 +0200
Subject: [PATCH] Bug 19082 - Recognize suppression spec files

When abipkgdiff is invoked on a set of packages, the newer (second) one is also
inspected for files matching the pattern '*.abignore', whose contents are read
and interpreted as suppression specifications.

	* tests/data/Makefile.am: Add new test material to the build system.
	* tests/data/test-diff-pkg/dirpkg-{0-dir1,{1,2}-dir2}/dir.abignore:
	A test suppression specification.
	* tests/data/test-diff-pkg/dirpkg-{2,3}-dir2/.abignore: Likewise.
	* tests/data/test-diff-pkg/dirpkg-3.suppr: Likewise.
	* tests/data/test-diff-pkg/dirpkg-{1,2,3}-dir{1,2}/libobj-v0.so: New
	binary test inputs.
	* tests/data/test-diff-pkg/dirpkg-{1,2,3}-dir{1,2}/obj-v0.cc: New test
	source files
	* tests/data/test-diff-pkg/dirpkg-{1,2,3}-report-{0,1}.txt: New
	reference outputs
	* tests/test-diff-pkg.cc: Adjust to run the new tests.
	* tools/abipkgdiff.cc (file_tree_walker_callback_fn): Rename to
	file_tree_walker_elf_callback_fn.
	(file_tree_walker_suppr_callback_fn): Check for ELF files just
	like the previous function but additionally check for files
	ending with ".abignore".
	({create_maps_of_package,extract_package_and_map_its}_content):
	Add a callback as a new argument.
	(main) handle the new "--no-abignore" option, which turns off
	the search for suppression files within the new package.

Signed-off-by: Ondrej Oprala <ooprala@redhat.com>
---
 tests/data/Makefile.am                             |  28 +++++-
 .../data/test-diff-pkg/dirpkg-0-dir1/dir.abignore  |   4 +
 .../data/test-diff-pkg/dirpkg-1-dir1/libobj-v0.so  | Bin 0 -> 8951 bytes
 tests/data/test-diff-pkg/dirpkg-1-dir1/obj-v0.cc   |  15 ++++
 .../data/test-diff-pkg/dirpkg-1-dir2/dir.abignore  |   4 +
 .../data/test-diff-pkg/dirpkg-1-dir2/libobj-v0.so  | Bin 0 -> 8991 bytes
 tests/data/test-diff-pkg/dirpkg-1-dir2/obj-v0.cc   |  17 ++++
 tests/data/test-diff-pkg/dirpkg-1-report-0.txt     |   0
 tests/data/test-diff-pkg/dirpkg-1-report-1.txt     |  16 ++++
 .../data/test-diff-pkg/dirpkg-2-dir1/libobj-v0.so  | Bin 0 -> 9088 bytes
 tests/data/test-diff-pkg/dirpkg-2-dir1/obj-v0.cc   |  22 +++++
 tests/data/test-diff-pkg/dirpkg-2-dir2/.abignore   |   2 +
 .../data/test-diff-pkg/dirpkg-2-dir2/dir.abignore  |   2 +
 .../data/test-diff-pkg/dirpkg-2-dir2/libobj-v0.so  | Bin 0 -> 9136 bytes
 tests/data/test-diff-pkg/dirpkg-2-dir2/obj-v0.cc   |  25 ++++++
 tests/data/test-diff-pkg/dirpkg-2-report-0.txt     |   0
 tests/data/test-diff-pkg/dirpkg-2-report-1.txt     |  16 ++++
 .../data/test-diff-pkg/dirpkg-3-dir1/libobj-v0.so  | Bin 0 -> 9088 bytes
 tests/data/test-diff-pkg/dirpkg-3-dir1/obj-v0.cc   |  22 +++++
 tests/data/test-diff-pkg/dirpkg-3-dir2/.abignore   |   2 +
 .../data/test-diff-pkg/dirpkg-3-dir2/libobj-v0.so  | Bin 0 -> 9136 bytes
 tests/data/test-diff-pkg/dirpkg-3-dir2/obj-v0.cc   |  25 ++++++
 tests/data/test-diff-pkg/dirpkg-3-report-0.txt     |   0
 tests/data/test-diff-pkg/dirpkg-3-report-1.txt     |  16 ++++
 tests/data/test-diff-pkg/dirpkg-3.suppr            |   2 +
 tests/test-diff-pkg.cc                             |  94 ++++++++++++++++++++-
 tools/abipkgdiff.cc                                |  74 ++++++++++++----
 27 files changed, 364 insertions(+), 22 deletions(-)
 create mode 100644 tests/data/test-diff-pkg/dirpkg-0-dir1/dir.abignore
 create mode 100755 tests/data/test-diff-pkg/dirpkg-1-dir1/libobj-v0.so
 create mode 100644 tests/data/test-diff-pkg/dirpkg-1-dir1/obj-v0.cc
 create mode 100644 tests/data/test-diff-pkg/dirpkg-1-dir2/dir.abignore
 create mode 100755 tests/data/test-diff-pkg/dirpkg-1-dir2/libobj-v0.so
 create mode 100644 tests/data/test-diff-pkg/dirpkg-1-dir2/obj-v0.cc
 create mode 100644 tests/data/test-diff-pkg/dirpkg-1-report-0.txt
 create mode 100644 tests/data/test-diff-pkg/dirpkg-1-report-1.txt
 create mode 100755 tests/data/test-diff-pkg/dirpkg-2-dir1/libobj-v0.so
 create mode 100644 tests/data/test-diff-pkg/dirpkg-2-dir1/obj-v0.cc
 create mode 100644 tests/data/test-diff-pkg/dirpkg-2-dir2/.abignore
 create mode 100644 tests/data/test-diff-pkg/dirpkg-2-dir2/dir.abignore
 create mode 100755 tests/data/test-diff-pkg/dirpkg-2-dir2/libobj-v0.so
 create mode 100644 tests/data/test-diff-pkg/dirpkg-2-dir2/obj-v0.cc
 create mode 100644 tests/data/test-diff-pkg/dirpkg-2-report-0.txt
 create mode 100644 tests/data/test-diff-pkg/dirpkg-2-report-1.txt
 create mode 100755 tests/data/test-diff-pkg/dirpkg-3-dir1/libobj-v0.so
 create mode 100644 tests/data/test-diff-pkg/dirpkg-3-dir1/obj-v0.cc
 create mode 100644 tests/data/test-diff-pkg/dirpkg-3-dir2/.abignore
 create mode 100755 tests/data/test-diff-pkg/dirpkg-3-dir2/libobj-v0.so
 create mode 100644 tests/data/test-diff-pkg/dirpkg-3-dir2/obj-v0.cc
 create mode 100644 tests/data/test-diff-pkg/dirpkg-3-report-0.txt
 create mode 100644 tests/data/test-diff-pkg/dirpkg-3-report-1.txt
 create mode 100644 tests/data/test-diff-pkg/dirpkg-3.suppr

diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
index 73d02e1..967e225 100644
--- a/tests/data/Makefile.am
+++ b/tests/data/Makefile.am
@@ -892,11 +892,35 @@ test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2
 test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb \
 test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb \
 test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb \
+test-diff-pkg/dirpkg-0-dir1/dir.abignore \
 test-diff-pkg/dirpkg-0-dir1/libobj-v0.so \
-test-diff-pkg/dirpkg-0-dir2/libobj-v0.so \
-test-diff-pkg/dirpkg-0-report-0.txt \
 test-diff-pkg/dirpkg-0-dir1/obj-v0.cc \
+test-diff-pkg/dirpkg-0-dir2/libobj-v0.so \
 test-diff-pkg/dirpkg-0-dir2/obj-v0.cc \
+test-diff-pkg/dirpkg-0-report-0.txt \
+test-diff-pkg/dirpkg-1-dir1/libobj-v0.so \
+test-diff-pkg/dirpkg-1-dir1/obj-v0.cc \
+test-diff-pkg/dirpkg-1-dir2/dir.abignore \
+test-diff-pkg/dirpkg-1-dir2/libobj-v0.so \
+test-diff-pkg/dirpkg-1-dir2/obj-v0.cc \
+test-diff-pkg/dirpkg-1-report-0.txt \
+test-diff-pkg/dirpkg-1-report-1.txt \
+test-diff-pkg/dirpkg-2-dir1/libobj-v0.so \
+test-diff-pkg/dirpkg-2-dir1/obj-v0.cc \
+test-diff-pkg/dirpkg-2-dir2/.abignore \
+test-diff-pkg/dirpkg-2-dir2/dir.abignore \
+test-diff-pkg/dirpkg-2-dir2/libobj-v0.so \
+test-diff-pkg/dirpkg-2-dir2/obj-v0.cc \
+test-diff-pkg/dirpkg-2-report-0.txt \
+test-diff-pkg/dirpkg-2-report-1.txt \
+test-diff-pkg/dirpkg-3-dir1/libobj-v0.so \
+test-diff-pkg/dirpkg-3-dir1/obj-v0.cc \
+test-diff-pkg/dirpkg-3-dir2/.abignore \
+test-diff-pkg/dirpkg-3-dir2/libobj-v0.so \
+test-diff-pkg/dirpkg-3-dir2/obj-v0.cc \
+test-diff-pkg/dirpkg-3-report-0.txt \
+test-diff-pkg/dirpkg-3-report-1.txt \
+test-diff-pkg/dirpkg-3.suppr \
 test-diff-pkg/tarpkg-0-dir1.tar \
 test-diff-pkg/tarpkg-0-dir1.ta \
 test-diff-pkg/tarpkg-0-dir1.tar.bz2 \
diff --git a/tests/data/test-diff-pkg/dirpkg-0-dir1/dir.abignore b/tests/data/test-diff-pkg/dirpkg-0-dir1/dir.abignore
new file mode 100644
index 0000000..d03917d
--- /dev/null
+++ b/tests/data/test-diff-pkg/dirpkg-0-dir1/dir.abignore
@@ -0,0 +1,4 @@
+#taken from test5-fn-supprt-0.suppr
+[suppress_function]
+  # suppress change reports for a function which name is 'bar' ...
+  name = bar
diff --git a/tests/data/test-diff-pkg/dirpkg-1-dir1/libobj-v0.so b/tests/data/test-diff-pkg/dirpkg-1-dir1/libobj-v0.so
new file mode 100755
index 0000000000000000000000000000000000000000..7373521ef7c791bf631ef74c0fb45ba841aa46b4
GIT binary patch
literal 8951
zcmeHMYit}>6~43M$2x1TH+B+YyC_4O1gD9|cATariIa64JL}-2)N#}{$ePUVjCVKe
zBh1XEc2#IZ(u#mWLy(}A5I>NJ0Er3&B2XdWHdT}#NH{>G2q9rnRdQ%0k^+@^#hi2J
zp7rePZc_;ae|%Om=brDL@4n{leLgolHWH8|Mk2Gl46WH(7m139xmFPX6=nUb9^MN3
zF!vR%%MPB<fqK^<&47i1dDOvky$LPUN{K!Z;3i86O*}M_w;*^6f=BueCJaJ4=$fns
zG(OiwykBn=ex%VC<r8l?28L%b(+c_l7iOf1_c-tbMR>fwqH>Ol{HnD}zi1EAqB^{8
zYak05o`Xk@u~&LGz0le5-rqZJ-27MH8#jKx?b^0~VhJ!FKMA$}=VukErY72k*eZA$
z;rUtTy=Py2^U||J!#Cf#_30-c`00ha;kSSNr!YjlugI){rF@+M^HD0W^eQ;EV<rFo
zD)>0y55nV@0st*6#J(*)0@e-XDm)Rkj`c(oG>h_m2u0Xh*6G8qaC}`E9s#_iLVee9
zypjFL|M4{~na$@k+tDpY)0mddr5&bCfnwU|#9_@aEi;+69n+dPJe0}j%n3c7G2OVz
zF<N3;#{~3D`WbLMbXpr1DGX(F+cs^c9q)_l)_CtxmPyBL$4G45s@i#VCz{z}D49rT
zHd?)iCtO@J4c*b1rp0aBEi}{2oWTx`jqV@PwyWFKN1&$55`Z4H{KNhwvC9yR?SxWj
zPd6|YVAox<_<yH<e@e91ocKQz-XrjNA5QkIW`(DSZpEPj!t)*+`#i~l2dDok#@+GY
z-Y&f8!9`JcQtL%O!T*gnU&Vua{bOg}3C6xyYpzmQ?D<)zcHto)#?HPG#183^rAI7q
zS=!{lyLm$tLTIPZ<M#X#$flEM<KOD`9GI~SwJ88%7Y2@lIu_fq7(4$~?CfIr>A>Vw
z$gl<@A;Whkm*z1&@b7i~ANKgawkXHWzaD$-kNaZMT<peTfs@z%vH{7z0&?v9wWU8G
z|IEN$09oOqv9kkLFmw#^a~dK4OZ5s{n1muNq~JAqt@b)ZOMkvPg`zfZI0r>$Q00LW
z;K-cKP&kdJKkKv~1O6d^A+4pk$=gpr0?ixFp#SZU^DxgQcK$PqlUJuM^0pLBCw0iX
zam>JPFn4ch3CD>Apqv1Wf@30z^vpPurXx~EV}0-<wBAO*karO{J?IdQjD*)8Y7RXe
zJj3?2?|!&%BOg}K=KwrsAWc4o42B~w1csXGh9M#3t;k9XthB&N3#_!jN(=lSTY%P2
zv|gg3&^ieh3@FdJ3RY*Xe933O<g+ge8}|h$w7wVHui`ql&5bUu>pFx@b7Z@)X?=(D
zDhkE__1;n*ZQ8fd8Z0FiZ*>?6(jyjIw4VQs3&Tp^mGwdw*L-3<Mr$-a*MkqO3&i%6
zeMs>7MaG0ri$x-pb5{7lVwMZ#2g?Xv{wIY$EEl*<?R-brdqn)-gk3DBNbi5GXy5G5
z_p)e*9}9hOXlR$x2|LRz$_}+(?Nhe*^zP{SSZ}Y=Ic^$COm|$o>(MQ28zknox7%v|
zJ(xeQO8~gd5|mD0_&dU*5;1U;)krl*!9)Heyren|G61CD7zApMqsi)OYSTG~)d#!4
z2*M_aN#VyK=uc7l`WFCgz*peQDYoiG2!uF^Nvowz;nt8G?g+1zTIwUvLjtXm91Mka
zg?5J|I1iDVm>fo9w6!1lUyUm5Ym<Wr>}fL~zP6T)w(fv`M%_jh3hfQa&>Z#65FCZb
z;Iem)XAoWgwf$|FYy;8)(6Lr+h5(c&A}DMZ7LzIPmZX1#o8Zk)ZlI4zEFVAFb-G7Q
zBp?=~AwX4?!_wyhusxHyQ~9jfZRCxU>F#9O>4wdo9#1FrbVfxJ!lyo!G}2R3-HvHH
zb~kPSd9Vw?E{G({0>tX|Y%jBBwg-<Ll%cI#@7q6=uB=nYnFC2PXIkk5n7Wln4NUj%
z?Ap0Q=}LO5qS`ZAM~^erb}Uz?D3r@PrkczZ)OaDCF}l(Q<5o(yQ%p5xa=>)8W4SS>
zP0LQ_b0vlbah93Uksv~+G7eMu?p$@uX$bQ@x@xAhDNE0qTFL+pS+1w1Tb4fKdQ$jg
z0^G0(F@4p_^RnpKbOQ3vL#psnc~-E&W@;jz&6?0*Rl|%Il8}a;OTq?TnCaXU^4+L-
z+%iv-l}YDJ3PZ!V-~K;&<GAhJ(^fktqddfLMkZ4s^d5|DG~Uv9PI`~<q;ZeNRZ5^A
z0yvfvpT>LA{bE4He9?#aG!91r!?cM{^9N~~FTjNhjn8DqAb?{x@oBs!P4gI)pZrK4
z13u0LWYc^=S`isx`7v)Qzkrzm0je8fH2;vEMG%DYCqC6b2XS6L&1a-({zE>_p?>}}
zU|24iZ)v_KP4x#CE|`~BY%sk1i(>vDP5BciA_Am8>*LcoH0i$((Z?hBoR3fEaHMJ8
zCVzkVaVEg>)A#eA`_j6l8vi99e_k{sX@iJDQ~MMAO$dbHq3^qVF7A5x{r&bU;MVNn
z(|T)8EZF@1e*0D6V*M%qTTKdBjNSTx{GWrbmrv`@`47nd1@N)SD1Ta?(0M<NBlO*<
z{M3JL`tqmq!CTlUAf2u%zKKuzw-DnkKNIUmI>@{q|4rayT2y{IPwo^2q<p9VR1dNj
zAb|Pz5Fj-1ac$)l^hF_k*AwOu;x!@i_oqv|qAvht7(|{E{I3=r-GJY>u?oL^wd?<t
z`|#VV@V_Vcd+)>FEcpI<zAgAatiq>ypc{QVuj@BjT&tHHMWoN<ZAW8=mp>;qM5n}f
zxB()&;i3LO<2Q~^mGX~%#7*srFGHW{I#qegP&%5=y)H70cJ#k0#pU9Ds}!$cG@q8@
zwT$M;QoN4Q{8x(C7w5N9JjiIiD#gq1moQ$2nT+O_QvXo#9<vm$a6iM-X)50HmHLMn
zjo+nsb8)|0iboiYyQTPQ7)KQ^#KSV&B+)qOjg(m{+;dj)U&ClzEA?Ls7cQ0j%kQs{
zCl`0U-c%5$-ss0^m+!~@s{%J(W^@YR_xI1D?wC`<?k<&jy7!S1D{nU}NdQ)gv@ReX
zu0IjKBmQTE4+`9WKJo<M65I#UI8FbjDUO$a#|t7II&T4!%ggYVVCJRyTEOfl5U5ly
z%%>9mI!`CeqI3Wu5}M<9c{^ZqrF4GB{mc8qy8@^BA|K@*JW_>z7=nUI75d>Cz!fC=
z<e@6~qky-t^8ejH75}HI;5Oh7`tn5cMV@~7eecVF<9)BczTXnK{~q|e9525I{sB+F
z!uXT09NQ_t4Oap#OAif=Yh$BFC*Xp2`94>3vRVRfbZtf#xgJQ<jJ%f2<l}lqGn~9-
zYkFat!G7>m#&k?W-PzaI4=Go0;+Mznb`!2<9czZU8&so^&CUSDWAWSO64&M90!<qk
zA3Qv)4Iepx_tLx$B7AV{vHgQ%+G8UlM~5f0iNXD2!{`AQ)J1Q@&TA<>XW&)!fv1iP
j9v&S6kJ78|N;lL0wTtg))O#hpeB)hqb4@qed~5%2At@;U

literal 0
HcmV?d00001

diff --git a/tests/data/test-diff-pkg/dirpkg-1-dir1/obj-v0.cc b/tests/data/test-diff-pkg/dirpkg-1-dir1/obj-v0.cc
new file mode 100644
index 0000000..5a016dd
--- /dev/null
+++ b/tests/data/test-diff-pkg/dirpkg-1-dir1/obj-v0.cc
@@ -0,0 +1,15 @@
+// Compile with:
+// g++ -g -shared -o libobj-v0.so obj-v0.cc
+
+struct S
+{
+  int mem0;
+
+  S()
+    : mem0()
+  {}
+};
+
+void
+bar(S&)
+{}
diff --git a/tests/data/test-diff-pkg/dirpkg-1-dir2/dir.abignore b/tests/data/test-diff-pkg/dirpkg-1-dir2/dir.abignore
new file mode 100644
index 0000000..d03917d
--- /dev/null
+++ b/tests/data/test-diff-pkg/dirpkg-1-dir2/dir.abignore
@@ -0,0 +1,4 @@
+#taken from test5-fn-supprt-0.suppr
+[suppress_function]
+  # suppress change reports for a function which name is 'bar' ...
+  name = bar
diff --git a/tests/data/test-diff-pkg/dirpkg-1-dir2/libobj-v0.so b/tests/data/test-diff-pkg/dirpkg-1-dir2/libobj-v0.so
new file mode 100755
index 0000000000000000000000000000000000000000..0032f73fb7c5b6cfbcb254c896089d10962a826d
GIT binary patch
literal 8991
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
LH{X2At^L0N){!i+

literal 0
HcmV?d00001

diff --git a/tests/data/test-diff-pkg/dirpkg-1-dir2/obj-v0.cc b/tests/data/test-diff-pkg/dirpkg-1-dir2/obj-v0.cc
new file mode 100644
index 0000000..65f6bab
--- /dev/null
+++ b/tests/data/test-diff-pkg/dirpkg-1-dir2/obj-v0.cc
@@ -0,0 +1,17 @@
+// Compile with:
+// g++ -g -shared -o libobj-v0.so obj-v0.cc
+
+struct S
+{
+  int  mem0;
+  char mem1;
+
+  S()
+    : mem0(),
+      mem1()
+  {}
+};
+
+void
+bar(S&)
+{}
diff --git a/tests/data/test-diff-pkg/dirpkg-1-report-0.txt b/tests/data/test-diff-pkg/dirpkg-1-report-0.txt
new file mode 100644
index 0000000..e69de29
diff --git a/tests/data/test-diff-pkg/dirpkg-1-report-1.txt b/tests/data/test-diff-pkg/dirpkg-1-report-1.txt
new file mode 100644
index 0000000..c7c9226
--- /dev/null
+++ b/tests/data/test-diff-pkg/dirpkg-1-report-1.txt
@@ -0,0 +1,16 @@
+================ changes of 'libobj-v0.so'===============
+  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 bar(S&)' has some indirect sub-type changes:
+      parameter 1 of type 'S&' has sub-type changes:
+        in referenced type 'struct S':
+          type size changed from 32 to 64 bits
+          1 data member insertion:
+            'char S::mem1', at offset 32 (in bits)
+
+
+================ end of changes of 'libobj-v0.so'===============
+
diff --git a/tests/data/test-diff-pkg/dirpkg-2-dir1/libobj-v0.so b/tests/data/test-diff-pkg/dirpkg-2-dir1/libobj-v0.so
new file mode 100755
index 0000000000000000000000000000000000000000..327577dc2e9a41bf33616b98398b6dbb7c05e40d
GIT binary patch
literal 9088
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
JQXDF*_z%jLSP}pL

literal 0
HcmV?d00001

diff --git a/tests/data/test-diff-pkg/dirpkg-2-dir1/obj-v0.cc b/tests/data/test-diff-pkg/dirpkg-2-dir1/obj-v0.cc
new file mode 100644
index 0000000..206a265
--- /dev/null
+++ b/tests/data/test-diff-pkg/dirpkg-2-dir1/obj-v0.cc
@@ -0,0 +1,22 @@
+// Compile with:
+// g++ -g -shared -o libobj-v0.so obj-v0.cc
+
+struct S0
+{
+  int mem0;
+
+  S0()
+    : mem0()
+  {}
+};
+
+struct S1
+{
+};
+void
+bar(S0&)
+{}
+
+void
+foo(S1&)
+{}
diff --git a/tests/data/test-diff-pkg/dirpkg-2-dir2/.abignore b/tests/data/test-diff-pkg/dirpkg-2-dir2/.abignore
new file mode 100644
index 0000000..b8f8197
--- /dev/null
+++ b/tests/data/test-diff-pkg/dirpkg-2-dir2/.abignore
@@ -0,0 +1,2 @@
+[suppress_function]
+  name = foo
diff --git a/tests/data/test-diff-pkg/dirpkg-2-dir2/dir.abignore b/tests/data/test-diff-pkg/dirpkg-2-dir2/dir.abignore
new file mode 100644
index 0000000..c06dd56
--- /dev/null
+++ b/tests/data/test-diff-pkg/dirpkg-2-dir2/dir.abignore
@@ -0,0 +1,2 @@
+[suppress_function]
+  name = bar
diff --git a/tests/data/test-diff-pkg/dirpkg-2-dir2/libobj-v0.so b/tests/data/test-diff-pkg/dirpkg-2-dir2/libobj-v0.so
new file mode 100755
index 0000000000000000000000000000000000000000..de46f91bef99b1871dc16acecf5e314b2f500df6
GIT binary patch
literal 9136
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

literal 0
HcmV?d00001

diff --git a/tests/data/test-diff-pkg/dirpkg-2-dir2/obj-v0.cc b/tests/data/test-diff-pkg/dirpkg-2-dir2/obj-v0.cc
new file mode 100644
index 0000000..b96530e
--- /dev/null
+++ b/tests/data/test-diff-pkg/dirpkg-2-dir2/obj-v0.cc
@@ -0,0 +1,25 @@
+// Compile with:
+// g++ -g -shared -o libobj-v0.so obj-v0.cc
+
+struct S0
+{
+  int  mem0;
+  char mem1;
+
+  S0()
+    : mem0(),
+      mem1()
+  {}
+};
+
+struct S1
+{
+  int mem2;
+};
+void
+bar(S0&)
+{}
+
+void
+foo(S1&)
+{}
diff --git a/tests/data/test-diff-pkg/dirpkg-2-report-0.txt b/tests/data/test-diff-pkg/dirpkg-2-report-0.txt
new file mode 100644
index 0000000..e69de29
diff --git a/tests/data/test-diff-pkg/dirpkg-2-report-1.txt b/tests/data/test-diff-pkg/dirpkg-2-report-1.txt
new file mode 100644
index 0000000..c7c9226
--- /dev/null
+++ b/tests/data/test-diff-pkg/dirpkg-2-report-1.txt
@@ -0,0 +1,16 @@
+================ changes of 'libobj-v0.so'===============
+  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 bar(S&)' has some indirect sub-type changes:
+      parameter 1 of type 'S&' has sub-type changes:
+        in referenced type 'struct S':
+          type size changed from 32 to 64 bits
+          1 data member insertion:
+            'char S::mem1', at offset 32 (in bits)
+
+
+================ end of changes of 'libobj-v0.so'===============
+
diff --git a/tests/data/test-diff-pkg/dirpkg-3-dir1/libobj-v0.so b/tests/data/test-diff-pkg/dirpkg-3-dir1/libobj-v0.so
new file mode 100755
index 0000000000000000000000000000000000000000..327577dc2e9a41bf33616b98398b6dbb7c05e40d
GIT binary patch
literal 9088
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
JQXDF*_z%jLSP}pL

literal 0
HcmV?d00001

diff --git a/tests/data/test-diff-pkg/dirpkg-3-dir1/obj-v0.cc b/tests/data/test-diff-pkg/dirpkg-3-dir1/obj-v0.cc
new file mode 100644
index 0000000..206a265
--- /dev/null
+++ b/tests/data/test-diff-pkg/dirpkg-3-dir1/obj-v0.cc
@@ -0,0 +1,22 @@
+// Compile with:
+// g++ -g -shared -o libobj-v0.so obj-v0.cc
+
+struct S0
+{
+  int mem0;
+
+  S0()
+    : mem0()
+  {}
+};
+
+struct S1
+{
+};
+void
+bar(S0&)
+{}
+
+void
+foo(S1&)
+{}
diff --git a/tests/data/test-diff-pkg/dirpkg-3-dir2/.abignore b/tests/data/test-diff-pkg/dirpkg-3-dir2/.abignore
new file mode 100644
index 0000000..b8f8197
--- /dev/null
+++ b/tests/data/test-diff-pkg/dirpkg-3-dir2/.abignore
@@ -0,0 +1,2 @@
+[suppress_function]
+  name = foo
diff --git a/tests/data/test-diff-pkg/dirpkg-3-dir2/libobj-v0.so b/tests/data/test-diff-pkg/dirpkg-3-dir2/libobj-v0.so
new file mode 100755
index 0000000000000000000000000000000000000000..de46f91bef99b1871dc16acecf5e314b2f500df6
GIT binary patch
literal 9136
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

literal 0
HcmV?d00001

diff --git a/tests/data/test-diff-pkg/dirpkg-3-dir2/obj-v0.cc b/tests/data/test-diff-pkg/dirpkg-3-dir2/obj-v0.cc
new file mode 100644
index 0000000..b96530e
--- /dev/null
+++ b/tests/data/test-diff-pkg/dirpkg-3-dir2/obj-v0.cc
@@ -0,0 +1,25 @@
+// Compile with:
+// g++ -g -shared -o libobj-v0.so obj-v0.cc
+
+struct S0
+{
+  int  mem0;
+  char mem1;
+
+  S0()
+    : mem0(),
+      mem1()
+  {}
+};
+
+struct S1
+{
+  int mem2;
+};
+void
+bar(S0&)
+{}
+
+void
+foo(S1&)
+{}
diff --git a/tests/data/test-diff-pkg/dirpkg-3-report-0.txt b/tests/data/test-diff-pkg/dirpkg-3-report-0.txt
new file mode 100644
index 0000000..e69de29
diff --git a/tests/data/test-diff-pkg/dirpkg-3-report-1.txt b/tests/data/test-diff-pkg/dirpkg-3-report-1.txt
new file mode 100644
index 0000000..d0135b4
--- /dev/null
+++ b/tests/data/test-diff-pkg/dirpkg-3-report-1.txt
@@ -0,0 +1,16 @@
+================ changes of 'libobj-v0.so'===============
+  Functions changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added function
+  Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
+
+  1 function with some indirect sub-type change:
+
+    [C]'function void foo(S1&)' has some indirect sub-type changes:
+      parameter 1 of type 'S1&' has sub-type changes:
+        in referenced type 'struct S1':
+          type size changed from 8 to 32 bits
+          1 data member insertion:
+            'int S1::mem2', at offset 0 (in bits)
+
+
+================ end of changes of 'libobj-v0.so'===============
+
diff --git a/tests/data/test-diff-pkg/dirpkg-3.suppr b/tests/data/test-diff-pkg/dirpkg-3.suppr
new file mode 100644
index 0000000..c06dd56
--- /dev/null
+++ b/tests/data/test-diff-pkg/dirpkg-3.suppr
@@ -0,0 +1,2 @@
+[suppress_function]
+  name = bar
diff --git a/tests/test-diff-pkg.cc b/tests/test-diff-pkg.cc
index 2e56d31..f788282 100644
--- a/tests/test-diff-pkg.cc
+++ b/tests/test-diff-pkg.cc
@@ -40,12 +40,14 @@
 
 using std::string;
 using std::cerr;
+using abigail::tests::get_src_dir;
 
 struct InOutSpec
 {
   const char* first_in_package_path;
   const char* second_in_package_path;
   const char* prog_options;
+  const char* suppression_path;
   const char* first_in_debug_package_path;
   const char* second_in_debug_package_path;
   const char* ref_report_path;
@@ -54,15 +56,79 @@ struct InOutSpec
 
 static InOutSpec in_out_specs[] =
 {
+  // dir1 contains a suppr spec - it should be ignored.
   {
     "data/test-diff-pkg/dirpkg-0-dir1",
     "data/test-diff-pkg/dirpkg-0-dir2",
     "",
     "",
     "",
+    "",
     "data/test-diff-pkg/dirpkg-0-report-0.txt",
     "output/test-diff-pkg/dirpkg-0-report-0.txt"
   },
+  // dir2 contains a suppr spec - it should be recognized.
+  {
+    "data/test-diff-pkg/dirpkg-1-dir1",
+    "data/test-diff-pkg/dirpkg-1-dir2",
+    "",
+    "",
+    "",
+    "",
+    "data/test-diff-pkg/dirpkg-1-report-0.txt",
+    "output/test-diff-pkg/dirpkg-1-report-0.txt"
+  },
+  // dir2 contains a suppr spec but --no-abignore is specified,
+  // the file should be ignored.
+  {
+    "data/test-diff-pkg/dirpkg-1-dir1",
+    "data/test-diff-pkg/dirpkg-1-dir2",
+    "--no-abignore",
+    "",
+    "",
+    "",
+    "data/test-diff-pkg/dirpkg-1-report-1.txt",
+    "output/test-diff-pkg/dirpkg-1-report-1.txt"
+  },
+  // dir2 contains several suppr spec files, ".abignore" and
+  // "dir.abignore", so the specs should be merged.
+  {
+    "data/test-diff-pkg/dirpkg-2-dir1",
+    "data/test-diff-pkg/dirpkg-2-dir2",
+    "",
+    "",
+    "",
+    "",
+    "data/test-diff-pkg/dirpkg-2-report-0.txt",
+    "output/test-diff-pkg/dirpkg-2-report-0.txt"
+  },
+  // dir2 contains a suppr spec file, ".abignore" and
+  // an additional suppr file is specified on the command line,
+  // so the specs should be merged.
+  {
+    "data/test-diff-pkg/dirpkg-3-dir1",
+    "data/test-diff-pkg/dirpkg-3-dir2",
+    "",
+    "data/test-diff-pkg/dirpkg-3.suppr",
+    "",
+    "",
+    "data/test-diff-pkg/dirpkg-3-report-0.txt",
+    "output/test-diff-pkg/dirpkg-3-report-0.txt"
+  },
+  // dir2 contains a suppr spec file, ".abignore", which should
+  // be ignored because of the program options  and
+  // an additional suppr file is specified on the command line,
+  // which should be recognized.
+  {
+    "data/test-diff-pkg/dirpkg-3-dir1",
+    "data/test-diff-pkg/dirpkg-3-dir2",
+    "--no-abignore",
+    "data/test-diff-pkg/dirpkg-3.suppr",
+    "",
+    "",
+    "data/test-diff-pkg/dirpkg-3-report-1.txt",
+    "output/test-diff-pkg/dirpkg-3-report-1.txt"
+  },
 
 #if WITH_TAR
   {
@@ -71,6 +137,7 @@ static InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
     "data/test-diff-pkg/tarpkg-0-report-0.txt",
     "output/test-diff-pkg/tarpkg-0-report-0.txt"
   },
@@ -80,6 +147,7 @@ static InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
     "data/test-diff-pkg/tarpkg-0-report-0.txt",
     "output/test-diff-pkg/tarpkg-0-report-0.txt"
   },
@@ -89,6 +157,7 @@ static InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
     "data/test-diff-pkg/tarpkg-0-report-0.txt",
     "output/test-diff-pkg/tarpkg-0-report-0.txt"
   },
@@ -98,6 +167,7 @@ static InOutSpec in_out_specs[] =
     "",
     "",
     "",
+    "",
     "data/test-diff-pkg/tarpkg-0-report-0.txt",
     "output/test-diff-pkg/tarpkg-0-report-0.txt"
   },
@@ -109,6 +179,7 @@ static InOutSpec in_out_specs[] =
     "data/test-diff-pkg/dbus-glib-0.80-3.fc12.x86_64.rpm",
     "data/test-diff-pkg/dbus-glib-0.104-3.fc23.x86_64.rpm",
     "",
+    "",
     "data/test-diff-pkg/dbus-glib-debuginfo-0.80-3.fc12.x86_64.rpm",
     "data/test-diff-pkg/dbus-glib-debuginfo-0.104-3.fc23.x86_64.rpm",
     "data/test-diff-pkg/test-rpm-report-0.txt",
@@ -119,6 +190,7 @@ static InOutSpec in_out_specs[] =
   "data/test-diff-pkg/dbus-glib-0.80-3.fc12.x86_64.rpm",
   "data/test-diff-pkg/dbus-glib-0.104-3.fc23.x86_64.rpm",
   "",
+  "",
   "data/test-diff-pkg/dbus-glib-debuginfo-0.80-3.fc12.x86_64.rpm",
   "",
   "data/test-diff-pkg/test-rpm-report-1.txt",
@@ -131,6 +203,7 @@ static InOutSpec in_out_specs[] =
   "data/test-diff-pkg/dbus-glib-0.104-3.fc23.x86_64.rpm",
   "",
   "",
+  "",
   "data/test-diff-pkg/dbus-glib-debuginfo-0.104-3.fc23.x86_64.rpm",
   "data/test-diff-pkg/test-rpm-report-2.txt",
   "output/test-diff-pkg/test-rpm-report-2.txt"
@@ -143,6 +216,7 @@ static InOutSpec in_out_specs[] =
   "",
   "",
   "",
+  "",
   "data/test-diff-pkg/test-rpm-report-3.txt",
   "output/test-diff-pkg/test-rpm-report-3.txt"
   },
@@ -152,6 +226,7 @@ static InOutSpec in_out_specs[] =
   "data/test-diff-pkg/dbus-glib-0.80-3.fc12.x86_64.rpm",
   "data/test-diff-pkg/dbus-glib-0.80-3.fc12.x86_64.rpm",
   "",
+  "",
   "data/test-diff-pkg/dbus-glib-debuginfo-0.80-3.fc12.x86_64.rpm",
   "data/test-diff-pkg/dbus-glib-debuginfo-0.80-3.fc12.x86_64.rpm",
   "data/test-diff-pkg/test-rpm-report-4.txt",
@@ -163,6 +238,7 @@ static InOutSpec in_out_specs[] =
     "data/test-diff-pkg/dbus-glib-0.80-3.fc12.x86_64.rpm",
     "data/test-diff-pkg/dbus-glib-0.104-3.fc23.x86_64.rpm",
     "--no-added-syms",
+    "",
     "data/test-diff-pkg/dbus-glib-debuginfo-0.80-3.fc12.x86_64.rpm",
     "data/test-diff-pkg/dbus-glib-debuginfo-0.104-3.fc23.x86_64.rpm",
     "data/test-diff-pkg/test-rpm-report-5.txt",
@@ -176,6 +252,7 @@ static InOutSpec in_out_specs[] =
     "data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64.deb",
     "data/test-diff-pkg/libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64.deb",
     "--fail-no-dbg",
+    "",
     "data/test-diff-pkg/libsigc++-2.0-0c2a-dbgsym_2.4.0-1_amd64.ddeb",
     "data/test-diff-pkg/libsigc++-2.0-0v5-dbgsym_2.4.1-1ubuntu2_amd64.ddeb",
     "data/test-diff-pkg/libsigc++-2.0-0c2a_2.4.0-1_amd64--libsigc++-2.0-0v5_2.4.1-1ubuntu2_amd64-report-0.txt",
@@ -183,13 +260,12 @@ static InOutSpec in_out_specs[] =
   },
 #endif // WITH_DEB
   // This should be the last entry.
-  {0, 0, 0, 0, 0, 0, 0}
+  {0, 0, 0, 0, 0, 0, 0, 0}
 };
 
 int
 main()
 {
-  using abigail::tests::get_src_dir;
   using abigail::tests::get_build_dir;
   using abigail::tools_utils::ensure_parent_dir_created;
 
@@ -197,7 +273,8 @@ main()
   string first_in_package_path, second_in_package_path,
     prog_options,
     ref_abi_diff_report_path, out_abi_diff_report_path, cmd, abipkgdiff,
-    first_in_debug_package_path, second_in_debug_package_path;
+    first_in_debug_package_path, second_in_debug_package_path,
+    suppression_path;
   for (InOutSpec *s = in_out_specs; s->first_in_package_path; ++s)
     {
       first_in_package_path =
@@ -220,6 +297,14 @@ main()
           get_src_dir() + "/tests/" + s->second_in_debug_package_path;
       else
         second_in_debug_package_path.clear();
+
+      if (s->suppression_path
+          && strcmp(s->suppression_path, ""))
+        suppression_path =
+          get_src_dir() + "/tests/" + s->suppression_path;
+      else
+        suppression_path.clear();
+
       ref_abi_diff_report_path = get_src_dir() + "/tests/" + s->ref_report_path;
       out_abi_diff_report_path =
         get_build_dir() + "/tests/" + s->out_report_path;
@@ -242,6 +327,9 @@ main()
       if (!second_in_debug_package_path.empty())
         abipkgdiff += " --d2 " + second_in_debug_package_path;
 
+      if (!suppression_path.empty())
+        abipkgdiff += " --suppressions " + suppression_path;
+
       cmd =
         abipkgdiff + " " + first_in_package_path + " " + second_in_package_path;
       cmd += " > " + out_abi_diff_report_path;
diff --git a/tools/abipkgdiff.cc b/tools/abipkgdiff.cc
index 8dd8997..4e7acda 100644
--- a/tools/abipkgdiff.cc
+++ b/tools/abipkgdiff.cc
@@ -60,6 +60,7 @@ using std::vector;
 using std::map;
 using std::tr1::shared_ptr;
 using abigail::tools_utils::guess_file_type;
+using abigail::tools_utils::string_ends_with;
 using abigail::tools_utils::file_type;
 using abigail::tools_utils::make_path_absolute;
 using abigail::tools_utils::abidiff_status;
@@ -82,16 +83,18 @@ static bool verbose;
 /// This contains the set of files of a given package.  It's populated
 /// by a worker function that is invoked on each file contained in the
 /// package.  So this global variable is filled by the
-/// file_tree_walker_callback_fn() function.  Its content is relevant
-/// only during the time after which the current package has been
+/// file_tree_walker_callback_{elf,suppr}_fn() functions.  Its content is
+/// relevant only during the time after which the current package has been
 /// analyzed and before we start analyzing the next package.
 static vector<string> elf_file_paths;
+static vector<string> suppression_paths;
 
 /// The options passed to the current program.
 struct options
 {
   bool		display_usage;
   bool		missing_operand;
+  bool		abignore;
   string	package1;
   string	package2;
   string	debug_package1;
@@ -103,11 +106,11 @@ struct options
   bool		show_added_syms;
   bool		show_added_binaries;
   bool		fail_if_no_debug_info;
-  vector<string> suppression_paths;
 
   options()
     : display_usage(),
       missing_operand(),
+      abignore(true),
       keep_tmp_files(),
       compare_dso_only(),
       show_linkage_names(true),
@@ -146,6 +149,10 @@ public:
 /// A convenience typedef for a shared pointer to elf_file.
 typedef shared_ptr<elf_file> elf_file_sptr;
 
+/// A convenience typedef for a pointer to a function type that
+/// the ftw() function accepts.
+typedef int (*ftw_cb_type)(const char *, const struct stat*, int);
+
 /// Abstract the result of comparing two packages.
 ///
 /// This contains the the paths of the set of added binaries, removed
@@ -653,9 +660,9 @@ extract_package(const package& package)
 ///
 /// @param stat the stat struct of the file.
 static int
-file_tree_walker_callback_fn(const char *fpath,
-			     const struct stat *,
-			     int /*flag*/)
+file_tree_walker_elf_callback_fn(const char *fpath,
+				 const struct stat *,
+				 int /*flag*/)
 {
   struct stat s;
   lstat(fpath, &s);
@@ -668,6 +675,30 @@ file_tree_walker_callback_fn(const char *fpath,
   return 0;
 }
 
+/// A callback function invoked by the ftw() function while walking
+/// the directory of files extracted from the second package, unless
+/// "--no-abignore" is specified on the command line.
+///
+/// @param fpath the path to the file being considered.
+///
+/// @param stat the stat struct of the file.
+static int
+file_tree_walker_suppr_callback_fn(const char *fpath,
+				   const struct stat *,
+				   int /*flag*/)
+{
+  struct stat s;
+  lstat(fpath, &s);
+
+  if (!S_ISLNK(s.st_mode))
+    {
+      if (guess_file_type(fpath) == abigail::tools_utils::FILE_TYPE_ELF)
+	elf_file_paths.push_back(fpath);
+      else if (string_ends_with(fpath, ".abignore"))
+	suppression_paths.push_back(fpath);
+    }
+  return 0;
+}
 /// Update the diff context from the @ref options data structure.
 ///
 /// @param ctxt the diff context to update.
@@ -696,8 +727,8 @@ set_diff_context_from_opts(diff_context_sptr ctxt,
      | abigail::comparison::HARMLESS_SYMBOL_ALIAS_CHANGE_CATEORY);
 
   suppressions_type supprs;
-  for (vector<string>::const_iterator i = opts.suppression_paths.begin();
-       i != opts.suppression_paths.end();
+  for (vector<string>::const_iterator i = suppression_paths.begin();
+       i != suppression_paths.end();
        ++i)
     read_suppressions(*i, supprs);
   ctxt->add_suppressions(supprs);
@@ -858,9 +889,11 @@ compare(const elf_file& elf1,
 /// @param opts the options the current program has been called with.
 ///
 /// @param true upon successful completion, false otherwise.
+
 static bool
 create_maps_of_package_content(package& package,
-			       const options& opts)
+			       const options& opts,
+			       ftw_cb_type callback)
 {
   elf_file_paths.clear();
   if (verbose)
@@ -870,9 +903,7 @@ create_maps_of_package_content(package& package,
 	 << package.extracted_dir_path()
 	 << " ...";
 
-  if (ftw(package.extracted_dir_path().c_str(),
-	  file_tree_walker_callback_fn,
-	  16))
+  if (ftw(package.extracted_dir_path().c_str(), callback, 16))
     {
       cerr << "Error while inspecting files in package"
 	   << package.extracted_dir_path() << "\n";
@@ -919,14 +950,15 @@ create_maps_of_package_content(package& package,
 /// @return true upon successful completion, false otherwise.
 static bool
 extract_package_and_map_its_content(package& package,
-				    const options& opts)
+				    const options& opts,
+				    ftw_cb_type callback)
 {
   if (!extract_package(package))
     return false;
 
   bool result = true;
   if (!package.is_debug_info())
-    result |= create_maps_of_package_content(package, opts);
+    result |= create_maps_of_package_content(package, opts, callback);
 
   return result;
 }
@@ -947,8 +979,14 @@ prepare_packages(package&	first_package,
 		 package&	second_package,
 		 const options& opts)
 {
-  if (!extract_package_and_map_its_content(first_package, opts)
-      || !extract_package_and_map_its_content(second_package, opts))
+  if (!extract_package_and_map_its_content(first_package, opts,
+					   file_tree_walker_elf_callback_fn)
+  /// We go through the files of the newer (second) pkg to look for suppression
+  /// specifications, matching the "*.abignore" name pattern.
+      || !extract_package_and_map_its_content(second_package, opts,
+					      opts.abignore ?
+					      file_tree_walker_suppr_callback_fn
+					      : file_tree_walker_elf_callback_fn))
     return false;
 
   if ((first_package.debug_info_package()
@@ -1142,13 +1180,15 @@ parse_command_line(int argc, char* argv[], options& opts)
 	opts.fail_if_no_debug_info = true;
       else if (!strcmp(argv[i], "--verbose"))
 	verbose = true;
+      else if (!strcmp(argv[i], "--no-abignore"))
+	opts.abignore = false;
       else if (!strcmp(argv[i], "--suppressions")
 	       || !strcmp(argv[i], "--suppr"))
 	{
 	  int j = i + 1;
 	  if (j >= argc)
 	    return false;
-	  opts.suppression_paths.push_back(argv[j]);
+	  suppression_paths.push_back(argv[j]);
 	  ++i;
 	}
       else if (!strcmp(argv[i], "--help")
-- 
2.4.0