Bug PR26739 - Handle qualified typedef array types
Commit Message
Hello,
CV-qualifiers of a typedef of an array type apply to the elements of
the array. So this can be transformed into a typedef of array type
which element type is similarly CV-qualified.
That transformation helps avoiding spurious changes that might occur
when comparing the latter form against the former even though both are
equivalent.
This patch performs that transformation, just like we already do for
CV-qualified array types which are transformed into an array of
similarly CV-qualified elements.
* include/abg-fwd.h (is_typedef_of_array): Declare new function.
(peel_qualified_or_typedef_type): Declare new overload.
* src/abg-dwarf-reader.cc (maybe_strip_qualification): Handle
qualified typedef of arrays.
* src/abg-ir.cc (peel_qualified_or_typedef_type): Define new
overload for type_base_sptr.
* tests/data/test-diff-filter/test-PR26739-report-0.txt: New
reference test output.
* tests/data/test-diff-filter/test-PR26739-v{0,1}.c: Source code
of new binary test input.
* tests/data/test-diff-filter/test-PR26739-v{0,1}.o: New binary
test inputs.
* tests/data/Makefile.am: Add the new test material above to
source distribution.
* tests/test-diff-filter.cc (in_out_specs): Add the test inputs
above to this harness.
Signed-off-by: Dodji Seketeli <dodji@redhat.com>
---
include/abg-fwd.h | 6 ++
src/abg-dwarf-reader.cc | 27 +++++++++
src/abg-ir.cc | 57 ++++++++++++++++++
tests/data/Makefile.am | 5 ++
.../test-PR26739-report-0.txt | 3 +
tests/data/test-diff-filter/test-PR26739-v0.c | 8 +++
tests/data/test-diff-filter/test-PR26739-v0.o | Bin 0 -> 2976 bytes
tests/data/test-diff-filter/test-PR26739-v1.c | 12 ++++
tests/data/test-diff-filter/test-PR26739-v1.o | Bin 0 -> 2920 bytes
tests/test-diff-filter.cc | 7 +++
10 files changed, 125 insertions(+)
create mode 100644 tests/data/test-diff-filter/test-PR26739-report-0.txt
create mode 100644 tests/data/test-diff-filter/test-PR26739-v0.c
create mode 100644 tests/data/test-diff-filter/test-PR26739-v0.o
create mode 100644 tests/data/test-diff-filter/test-PR26739-v1.c
create mode 100644 tests/data/test-diff-filter/test-PR26739-v1.o
@@ -708,6 +708,9 @@ is_array_of_qualified_element(type_base_sptr&);
qualified_type_def_sptr
is_array_of_qualified_element(const array_type_def_sptr&);
+array_type_def_sptr
+is_typedef_of_array(const type_base_sptr&);
+
void
set_data_member_offset(var_decl_sptr, uint64_t);
@@ -848,6 +851,9 @@ peel_qualified_type(const type_base_sptr&);
type_base*
peel_qualified_or_typedef_type(const type_base* type);
+type_base_sptr
+peel_qualified_or_typedef_type(const type_base_sptr &type);
+
type_base_sptr
peel_typedef_pointer_or_reference_type(const type_base_sptr);
@@ -14342,6 +14342,33 @@ maybe_strip_qualification(const qualified_type_def_sptr t,
// delayed until after all editing is done.
ABG_ASSERT_NOT_REACHED;
}
+ else if (array_type_def_sptr array = is_typedef_of_array(u))
+ {
+ // We should not be editing types that are already canonicalized.
+ ABG_ASSERT(!array->get_canonical_type());
+ type_base_sptr element_type = array->get_element_type();
+
+ if (qualified_type_def_sptr qualified = is_qualified_type(element_type))
+ {
+ // We should not be editing types that are already canonicalized.
+ ABG_ASSERT(!qualified->get_canonical_type());
+ qualified_type_def::CV quals = qualified->get_cv_quals();
+ quals |= t->get_cv_quals();
+ qualified->set_cv_quals(quals);
+ result = is_decl(u);
+ }
+ else
+ {
+ qualified_type_def_sptr qual_type
+ (new qualified_type_def(element_type,
+ t->get_cv_quals(),
+ t->get_location()));
+ add_decl_to_scope(qual_type, is_decl(element_type)->get_scope());
+ array->set_element_type(qual_type);
+ ctxt.schedule_type_for_late_canonicalization(is_type(qual_type));
+ result = is_decl(u);
+ }
+ }
return result;
}
@@ -5813,6 +5813,35 @@ peel_qualified_or_typedef_type(const type_base* type)
return const_cast<type_base*>(type);
}
+/// Return the leaf underlying type of a qualified or typedef type.
+///
+/// If the underlying type is itself a qualified or typedef type, then
+/// recursively return the first underlying type of that qualified or
+/// typedef type to return the first underlying type that is not a
+/// qualified or typedef type.
+///
+/// If the underlying type is NOT a qualified nor a typedef type, then
+/// just return that underlying type.
+///
+/// @param type the qualified or typedef type to consider.
+///
+/// @return the leaf underlying type.
+type_base_sptr
+peel_qualified_or_typedef_type(const type_base_sptr &t)
+{
+ type_base_sptr type = t;
+ while (is_typedef(type) || is_qualified_type(type))
+ {
+ if (typedef_decl_sptr t = is_typedef(type))
+ type = peel_typedef_type(t);
+
+ if (qualified_type_def_sptr t = is_qualified_type(type))
+ type = peel_qualified_type(t);
+ }
+
+ return type;
+}
+
/// Return the leaf underlying or pointed-to type node of a @ref
/// typedef_decl, @ref pointer_type_def or @ref reference_type_def
/// node.
@@ -8646,6 +8675,34 @@ is_array_of_qualified_element(type_base_sptr& type)
return array_type_def_sptr();
}
+/// Test if a type is a typedef of an array.
+///
+/// Note that the function looks through qualified and typedefs types
+/// of the underlying type of the current typedef. In other words, if
+/// we are looking at a typedef of a CV-qualified array, or at a
+/// typedef of a CV-qualified typedef of an array, this function will
+/// still return TRUE.
+///
+/// @param t the type to consider.
+///
+/// @return true if t is a typedef which underlying type is an array.
+/// That array might be either cv-qualified array or a typedef'ed
+/// array, or a combination of both.
+array_type_def_sptr
+is_typedef_of_array(const type_base_sptr& t)
+{
+ array_type_def_sptr result;
+
+ if (typedef_decl_sptr typdef = is_typedef(t))
+ {
+ type_base_sptr u =
+ peel_qualified_or_typedef_type(typdef->get_underlying_type());
+ result = is_array_type(u);
+ }
+
+ return result;
+}
+
/// Test if a type is an array_type_def::subrange_type.
///
/// @param type the type to consider.
@@ -888,6 +888,11 @@ test-diff-filter/test-PR26309-v1.c \
test-diff-filter/test-PR26309-v0.o \
test-diff-filter/test-PR26309-v1.o \
test-diff-filter/test-PR26309-report-0.txt \
+test-diff-filter/test-PR26739-v0.c \
+test-diff-filter/test-PR26739-v1.c \
+test-diff-filter/test-PR26739-v0.o \
+test-diff-filter/test-PR26739-v1.o \
+test-diff-filter/test-PR26739-report-0.txt \
\
test-diff-suppr/test0-type-suppr-v0.cc \
test-diff-suppr/test0-type-suppr-v1.cc \
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,8 @@
+typedef const int immutable[7];
+typedef immutable monster;
+
+struct A {
+ monster q;
+};
+
+void fun(struct A * a) { (void) a; }
new file mode 100644
GIT binary patch
literal 2976
zcmbVO&2Jk;6o2Ej<4ra(NlYOoJ#0mxjnrM+X`4DlDJ~IBA}SO`RB)h**7n$5@UDZs
zt`ZPJLKUbIhgL#DNZhy~4oDohBJmG!<iLRo636z2!~x#hopC1PMXmZI&%F7)@0oeC
z{^a$WH!_TYBnH>ucqLJQKc<fPdd$|L2#auQ``(}1_dfpn{_S6WL^vCZ%-F+h%qxSX
z@EPJ6E3V^Yyp6*S{<1VoLC(zM3{%;hA4ZVhMLto_6dmOA@8V!yhtn);-bHr$17JC;
ziyXjAdlUjQ$H~f&?3*7@YI!I-MO@}V7iP_XOxOZ@sZg|x!g67OE#~K+N9l856s}sY
zSnJkK5%Xhgr^t}Wo`IcW8GYu?f@NJp8_ZI$CMNbWiZQh!Gfc}$?8$6;4h&PetD*Uf
z%U&%>=v;}y)|b9|twhRJPEpP*0n9#wvB)o6pu{O<z+ei=A{8iR-@?&=8jg(pQ<%ds
zK4?4~2D^K!YgaC=JHaUO!pMn^4tR^V9d9u3j+{Fcw;6lLEx~jW5tpUh*-tYDdg=AU
zjy(#8ekbHDo6acchr@^uVC&6W_Ga~pU9GsQZq;6`tX8U(%4Pff9x85okq|hSS8OMU
zMj_wm@Q@GuCN8}}v%7IvTXWVf*-qyP67&N~zR}}Q?)C#-ZuML5`Q?rum3w}}Yxo_{
z@0CTJ<%kcXVY%f+Ud%czzuk7)evh(-t<BA=_IXTx<q0y6HwK<fCSV`#0Xv*$%d>g&
zKJM&k#OX&ApUd^a{AZcXxv3kdkie-Ubxal>{hKDlJx_!2Y{zGFLT;cWjSSJAy3D|y
zOCtl~KAaF4Fg<}0U?de!$PAd9z!H7zpA<4+;^}}FQEyS%hw+_%{6(fGVO-%1`cbQu
zkqD=%UcevGLNbBGxmcgl@CRaD5;L8YdMYc5zIy(yf>Yej#rmd(izVFF@I|ryLd<$x
zStI426FM}_3trdX`XAgDIMt-q1@7=D!0y928YFX9auGj_z@=UTw=o=oJK#OfZSlsa
zv+sxPKFVU=YcvM@&Iz$M@WKv1Y0~pUE=@25xXpeLaC~*#upe<3+twLIUh{q7h<Eqf
z122#VCh~vUX&DV^ujGD8KXt*3@1a<eu1aTcL73i=Z>UNNuiKwP8Qq(wwXdSB?vujF
z_&?D?Azk+Z%IKqBS9FN|EBVsHLxI!1B1qnG{BXszfurt|1Q`K-7i%34y6!HDbd0pW
z7hvVsH0E?&sxvMB-$YYLd&-|)J3apvV!BU+;CBJOLkop;-F=j$#g~6k<UUb+dI$9Q
z2Z)hRnJ2O_T@uass|3U><IDLY#MA7v;zE@lV}DoJYie*&zmP&f#+CYC3;Ppq2Vym0
zPybF-lJ!gMOJvga&lU}-?jL<kq`kx`A3ZktJ`nMDMZ)yn(^pEjr!z?_^=C>7iTYC|
Ty?*kWW?vKef2$fJuiO6zTQuNz
literal 0
HcmV?d00001
new file mode 100644
@@ -0,0 +1,12 @@
+typedef int plain[7];
+typedef const plain monster;
+
+struct A {
+ monster q;
+};
+
+void fun(struct A * a) {
+ (void) a;
+ // assignment to read-only location
+ // a->q[0] = 0;
+}
new file mode 100644
GIT binary patch
literal 2920
zcmbtV-D@0G6hC)oH#^BBYmzmZHGP;;Z5wcAcB4(xYU<W#lh7g|wA2SB%<kUZ9o?O+
zv$G{p#22abt%4w;U{Mh9-w;Ib#Yg{vLVfI;&<8zd=HBhi%}9$Lm^tVE&gcC&_kQx`
zl}kCsKoWxs@Mt7afFCCw$@N66LmB4b+ScuRTem;{>(0ABe}`~BQJG1E=|on3mLlig
zz`;6x2K^==Zx%^g$QObz#xWAhEjY-Em+@y_gkvmk4pE%^09e7gjuOCBdlUjQ$F<1}
z?3-^<Yx$^KASw5G7pBd3$c4?Z7fNNzC@q!d*nDyJS=2JNU1nvh<v47YJq(h69xUqu
z8ev63G_lHOz$l%!Ua`(u+h|=piPl(JnHi>Kr8q^IoB_j>W@{L2%4M%rBy_4mY3qw$
zzFr|?tDqR?76GQ8!qgNOUZldQWWd}C$w?|uB3{M60c-eY>|tpJ|H;1MUNG3%U0FT*
z(mAI;iv2Kl;)5H!#oLY_MgD<vv*tFF2!%zMOf%xJQed}o21e-(!j3%(he0RgEt|Hd
zKM030kDegv=3Ce7joMkeR&`h0n!Qq8sn)91Gxq6S47KIQLgAcQww-=F3i*16hdc_J
zIP{}tcYS|t)meSnb~@m72Yv3f2Cer3uM@;xFKGCUpyLNUPt4AX`7j=OEkE`X(P;(k
zw$l!JR4Z(5Y@D}GV?oPLPz^ktEC?>$hr7V`XW7zp(Y%98c?@y-h?0%CSem_++nAZS
zga#>``KOM^!-K!Gl(@)QFmC2}GY;tu)MSw%+E3RRX+P;OMoD@u1D`yC5n!Y<KB6;V
z<_MPBWB+830Y|O|IDvNa$~ue>`QuM6-2vknPGOw!b%3(WL^#drRs4wNQU(%#PK*~c
z{4+7G2u?et?#i-aukL?c!PV8gqT%ym{E^^#d^s1Yvmk7U%?eq!-~1Qc7C6<e)(`IR
zpdb4U<Z+bpu9RZFAA?Kn1a4zE1UKS6-)-^6sIwP@?E&f%*>5x=e)EvpkNmL154-e&
zkV_X#0d8~9?{mCP+;9+c7dz7##(wjC5r}v9+L7PqqVWI8me8NpO0K62R~N$gyooW{
zs&pI&gz24kSv68*-TxHo=zRQF{~G%0F)5wQ{{sya(rxK6p~tzd*pT>Z`eMT$0;h9D
zkUY!yA|*txv>uZb4-zfFPl8LP+wP!3$H?|;0am4>;JPi%Gpqi)qA8?5)lavYUVjTQ
zJtji%n*iUYfkL|N9_q64|1R>&b)x*#?|S|lh*3;gCyEK35Y70D1O%7)C8zr#%l}W|
z?>)x<Q{k_f!J>X3g@Mc~?Y|QKhwcu<r2m>U6kN_<!e5|}wSM<A){kBd=`Yun>d|vk
r>>W}6jwqP!b$X3-f7+9*sotfckf=XZ(&tZcv;5_S^1bSevhM#6w{_d%
literal 0
HcmV?d00001
@@ -773,6 +773,13 @@ InOutSpec in_out_specs[] =
"data/test-diff-filter/test-PR26309-report-0.txt",
"output/test-diff-filter/test-PR26309-report-0.txt",
},
+ {
+ "data/test-diff-filter/test-PR26739-v0.o",
+ "data/test-diff-filter/test-PR26739-v1.o",
+ "--no-default-suppression",
+ "data/test-diff-filter/test-PR26739-report-0.txt",
+ "output/test-diff-filter/test-PR26739-report-0.txt",
+ },
// This should be the last entry
{NULL, NULL, NULL, NULL, NULL}
};