From 70cb9ba1ae1e733eb8831f8fd62c9825cc09facf Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Thu, 16 Oct 2014 23:32:08 +0200 Subject: [PATCH] Yet another fix to the DWARF method "static-ness" detection heuristic * include/abg-fwd.h (is_pointer, is_qualified_type): Declare new functions. * src/abg-ir.cc (is_pointer, is_qualified_type): Implement these new functions. * src/abg-dwarf-reader.cc (finish_member_function_reading): Sometimes, the this pointer of a non-static method can point to a *qualified* version of its containing type. I am seeing that when comparing libstdc++.so from RHEL 6.5 and RHEL 7. Take that in account when trying to detect that the first parameter of a member function is the this pointer, and thus detect that the function is a non static member function. * tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi: New test input. * tests/data/test-read-dwarf/test8-qualified-this-pointer.so: New test input. * tests/data/test-read-dwarf/test8-qualified-this-pointer.cc: Source code of new test input. * tests/test-read-dwarf.cc: Update copyright year. (in_out_spec): Add the new test inputs to this array, so that this test harness runs on them. * tests/Makefile.am: Add the new test inputs to the source distribution. Signed-off-by: Dodji Seketeli --- include/abg-fwd.h | 6 ++++ src/abg-dwarf-reader.cc | 30 +++++++++++------- src/abg-ir.cc | 20 ++++++++++++ tests/Makefile.am | 10 ++++++ .../test8-qualified-this-pointer.cc | 15 +++++++++ .../test8-qualified-this-pointer.so | Bin 0 -> 9056 bytes .../test8-qualified-this-pointer.so.abi | 29 +++++++++++++++++ tests/test-read-dwarf.cc | 7 +++- 8 files changed, 104 insertions(+), 13 deletions(-) create mode 100644 tests/data/test-read-dwarf/test8-qualified-this-pointer.cc create mode 100755 tests/data/test-read-dwarf/test8-qualified-this-pointer.so create mode 100644 tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi diff --git a/include/abg-fwd.h b/include/abg-fwd.h index b7882e7a..aefd762f 100644 --- a/include/abg-fwd.h +++ b/include/abg-fwd.h @@ -194,6 +194,12 @@ is_class_type(const shared_ptr); shared_ptr is_class_type(const shared_ptr); +shared_ptr +is_pointer(const shared_ptr); + +shared_ptr +is_qualified_type(const shared_ptr); + shared_ptr look_through_decl_only_class(shared_ptr); diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index 7619cab6..6a0a76f1 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -4908,12 +4908,11 @@ finish_member_function_reading(Dwarf_Die* die, die_access_specifier(die, access); bool is_static = false; { - // Let's see if the first parameter has the same class - // type as the current class has a DW_AT_artificial - // attribute flag set. We are not looking at - // DW_AT_object_pointer (for DWARF 3) because it - // wasn't being emitted in GCC 4_4, which was already - // DWARF 3. + // Let's see if the first parameter is a pointer to an instance of + // the same class type as the current class and has a + // DW_AT_artificial attribute flag set. We are not looking at + // DW_AT_object_pointer (for DWARF 3) because it wasn't being + // emitted in GCC 4_4, which was already DWARF 3. function_decl::parameter_sptr first_parm; if (!f->get_parameters().empty()) first_parm = f->get_parameters()[0]; @@ -4921,13 +4920,20 @@ finish_member_function_reading(Dwarf_Die* die, bool is_artificial = first_parm && first_parm->get_artificial();; pointer_type_def_sptr this_ptr_type; + type_base_sptr other_klass; + if (is_artificial) - this_ptr_type = - dynamic_pointer_cast - (first_parm->get_type()); - if (this_ptr_type && (get_pretty_representation - (this_ptr_type->get_pointed_to_type()) - == klass->get_pretty_representation())) + this_ptr_type = is_pointer(first_parm->get_type()); + if (this_ptr_type) + other_klass = this_ptr_type->get_pointed_to_type(); + // Sometimes, other_klass can be qualified; e.g, volatile. In + // that case, let's get the unqualified version of other_klass. + if (qualified_type_def_sptr q = is_qualified_type(other_klass)) + other_klass = q->get_underlying_type(); + + if (other_klass + && (ir::get_type_declaration(other_klass)->get_qualified_name() + == klass->get_qualified_name())) ; else is_static = true; diff --git a/src/abg-ir.cc b/src/abg-ir.cc index e16e4aa8..7aee6420 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -3033,6 +3033,26 @@ class_decl_sptr is_class_type(const decl_base_sptr d) {return is_class_type(is_type(d));} +/// Test whether a type is a pointer_type_def. +/// +/// @param t the type to test. +/// +/// @return the @ref pointer_type_def_sptr if @p t is a +/// pointer_type_def, null otherwise. +pointer_type_def_sptr +is_pointer(const type_base_sptr t) +{return dynamic_pointer_cast(t);} + +/// Test whether a type is a qualified_type_def. +/// +/// @param t the type to test. +/// +/// @return the @ref qualified_type_def_sptr if @p t is a +/// qualified_type_def, null otherwise. +qualified_type_def_sptr +is_qualified_type(const type_base_sptr t) +{return dynamic_pointer_cast(t);} + /// If a class is a decl-only class, get its definition. Otherwise, /// just return the initial class. /// diff --git a/tests/Makefile.am b/tests/Makefile.am index 3929f503..b1145de9 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -232,12 +232,22 @@ tests/data/test-read-dwarf/test2.so \ tests/data/test-read-dwarf/test2.so.abi \ tests/data/test-read-dwarf/test3.c \ tests/data/test-read-dwarf/test3.so \ +tests/data/test-read-dwarf/test3.so.abi \ tests/data/test-read-dwarf/test4.c \ tests/data/test-read-dwarf/test4.so \ +tests/data/test-read-dwarf/test4.so.abi \ tests/data/test-read-dwarf/test5.cc \ tests/data/test-read-dwarf/test5.so \ +tests/data/test-read-dwarf/test5.so.abi \ tests/data/test-read-dwarf/test6.cc \ tests/data/test-read-dwarf/test6.so \ +tests/data/test-read-dwarf/test6.so.abi \ +tests/data/test-read-dwarf/test7.cc \ +tests/data/test-read-dwarf/test7.so \ +tests/data/test-read-dwarf/test7.so.abi \ +tests/data/test-read-dwarf/test8-qualified-this-pointer.cc \ +tests/data/test-read-dwarf/test8-qualified-this-pointer.so \ +tests/data/test-read-dwarf/test8-qualified-this-pointer.so.abi \ \ data/test-diff-filter/test0-v0.cc \ data/test-diff-filter/test0-v1.cc \ diff --git a/tests/data/test-read-dwarf/test8-qualified-this-pointer.cc b/tests/data/test-read-dwarf/test8-qualified-this-pointer.cc new file mode 100644 index 00000000..e40f1ba0 --- /dev/null +++ b/tests/data/test-read-dwarf/test8-qualified-this-pointer.cc @@ -0,0 +1,15 @@ +struct S +{ + int i; + + S() + : i(0) + {} + + int + foo() const; +}; + +int +S::foo() const +{return i;} diff --git a/tests/data/test-read-dwarf/test8-qualified-this-pointer.so b/tests/data/test-read-dwarf/test8-qualified-this-pointer.so new file mode 100755 index 0000000000000000000000000000000000000000..ea1244b15af21782c49711d6fff0030cbe3cb2ca GIT binary patch literal 9056 zcmeHMU2Ggz6+W}$P1adw?RcAzpH|sMNy!g8{z>Y(P28;G*jcAeT5Ly!2s0V)jCVKM zA9r^)aY}*E1Vo4;rG0=@@Blni^rfmm{Io*g5)?(y2lG>5ctC+tAZ^<3ATe1GxkqMD#Go5i z<2?fR30rBpWZ=pjSnVh*0a=u&j#YTwTuU0sNQFG*6Dp*nWFD!+o0Ggb$zyqk9Ajb` za8zhON!LwT?v>l69ZRyM^u*h?N%QEFqgSNjb>#R7h!p?yofqccKiqZS?_a()-(sD7NxMcZpmKU8-2Y#m-lo9zSR-L; z@M^*H zZ-Q66FJIS_*?dkf+D5_Fb+@&m6`aZ8}VP=EeZbmHyVlmYvTWz z_~(1(5rNW2;}?2(trxM$fREa9 z3Jt;DijC8S^JzPL0{KS~Mqi6FW4E6~2e*guHgT2Q$1i<$A%3}k;WFSOQUA&AQnsl3 zH=j;d>ob;SW|GGz~*o_kH3n+1XFSlRiICqm%T;9h~SVM`|%FT`n z9M{qMN{P$=d3P~SI`7*!_Dad1jbo^G8D!C3h0^aFfswwGC?23xj`d_5CTSqnd@Seq zKyFXrBZ37GlNB?5UIvHU&S`0fL99qzABGd6{imcoh7CgJe!e61m@NO7)XVLZ{{Gj3 z_s!mVUzGju11XR6^*s{Vi95?(k$u`jT4$uQy`!_Eqy6E?&SA@p#0}fQqusmUW9ZE3 zZ>QJ1doXWZ-$%gdmVoH4hCu{AgBKHD;kS>NZv+|?C5JgR4T?$`Xcz&-e;hNTc=>7T z2di+?1IijIrYnh;pIqYZx51yz*$@asQ3(XTfcHkqt|4;BTcz@i7ZIl2VK6N-zUNZV zD10gFlpUdPPz`Mfty5Z+792#ru%ZTn!AFAogGw0NxE9m^DTCo|9HI@Ha&VIa9N1)r z$-?i4!SFu(`>a|j%Y_ERRE~|^4#D7~K@~eP(2UtZ#2Oz!2DVpIj)eCIsp8m1GyJtf zo5)?z4=S?vZSv8`d;%{Ybm3i5{vBG2ck!tQdszY7D%#!Ar%JeeoJd<{)J~;~(aAja zjaASR3FKgE^l^u%A>~m^mQ34ixK}mC(@7(pY0Db4b#9}FDz?$SRb-1*hbURVb$O zxe7(cvVxT{h#+&585=aQ)7NZk3iD#WuURR5qF`h#J!K+?HOEpn3I*ewW6Al`2{faJ zBL7+;FWO>c(+R9Uk6!VniK=j?4q76g&009ZHPad|CDDhGOX9}>sit!i#CM9u#|zdO z)-vgw#d+))X8`=ScUlMBd*gcF-MAh(J+cZK=HAD-lIL$;A6OocmOPL0Jk1WeF+*zu z^LhPX*)1n%s+Vk-&+~c=G4joPUXNJv`hzASNq4M59CNf5FrVjtmb@-<``M1=3FOn- z!ul!MK`bM(CW5JMZoh=V#0))0*t%Pa#I_ z;u)Od2bTQ&Xd;qq9;;BqoST1Du174nekQcY49m}X_|uZl@(vR{JcciN_`DRch$2)v}!1D;dH*PJ&^n9Z|kBpXDF0#Qppr<5B(~x*Y#4Co9poZ zDESohxs$j42PEJ7oSm%>>ql-f=9$lus^NF%Hho9(JJ?VbdQ{<$=MFbNA}0=>N4H{O z8(usfc>bpOsaE}0?{~b-cq;U$j!~Vviml`I+-;)bYRUhrN?ZkAcPsG*;Ptc;_e0D( zpwU3ZfAp!E`0DcdR_P~D-q%&))#p`IuHs6@>r175uzW6BiPt#q5q{Q|&kZZ>L%{QQ zCEi@#KUd-{<$ZG{z7BXkt;Ab_=gCSujOV5iHze{Z?uL0@a~GVBh^_%KrBxPW;S ze-eI2#tn@3O5FRsZ84fhWg0@kHO2I5qQ=4IG>w~egA&| + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/test-read-dwarf.cc b/tests/test-read-dwarf.cc index 88b77cda..e8c12ea1 100644 --- a/tests/test-read-dwarf.cc +++ b/tests/test-read-dwarf.cc @@ -1,6 +1,6 @@ // -*- Mode: C++ -*- // -// Copyright (C) 2013 Red Hat, Inc. +// Copyright (C) 2013-2014 Red Hat, Inc. // // This file is part of the GNU Application Binary Interface Generic // Analysis and Instrumentation Library (libabigail). This library is @@ -90,6 +90,11 @@ InOutSpec in_out_specs[] = "data/test-read-dwarf/test7.so.abi", "output/test-read-dwarf/test7.so.abi" }, + { + "data/test-read-dwarf/test8-qualified-this-pointer.so", + "data/test-read-dwarf/test8-qualified-this-pointer.so.abi", + "output/test-read-dwarf/test8-qualified-this-pointer.so.abi" + }, // This should be the last entry. {NULL, NULL, NULL} };