From bcccb9830afb95f6b79752fd99ba9f88747fd892 Mon Sep 17 00:00:00 2001 From: Kareem Khazem Date: Tue, 19 Sep 2017 09:04:00 +0100 Subject: [PATCH 1/7] Regenerated cross-compiled arch flag test binaries This was needed after an update to goto-cc, which caused previously-compiled binaries used in the test suite to trigger an assertion failure. Also updated instructions on how to generate these binaries. This commit fixes #1376. --- .../ansi-c/arch_flags_mcpu_bad/object.intel | Bin 4483 -> 4454 bytes .../ansi-c/arch_flags_mcpu_good/object.arm | Bin 4208 -> 4183 bytes .../ansi-c/arch_flags_mcpu_good/test.desc | 9 +++++++-- .../ansi-c/arch_flags_mthumb_bad/object.intel | Bin 4485 -> 4456 bytes .../ansi-c/arch_flags_mthumb_good/object.arm | Bin 4268 -> 4185 bytes .../ansi-c/arch_flags_mthumb_good/test.desc | 9 +++++++-- 6 files changed, 14 insertions(+), 4 deletions(-) diff --git a/regression/ansi-c/arch_flags_mcpu_bad/object.intel b/regression/ansi-c/arch_flags_mcpu_bad/object.intel index e32d04e4c5675da66bdfac403dd8587ddfac4357..11593f7dcf173d5b37e0ea5e851e403068c6528c 100644 GIT binary patch literal 4454 zcmbtYZFCe@8NPS7X|j{h)r4vZ)M1G%I%*k7Z;`HShq3c;T=k$?SxY0KAR+1?h zGpRbdX^;RRa&1b_FcSP{Xk8+&XPhS8Xi_yz=il2=d|#K*4My&mky_jEuisbnnAQ&6 zNGqCdv7}>KeWct)wz) z+E%j3TwY128o@`t63nTVnq>~NY;q?7*8r&u7e?0s(L6Oeu)4Mc-3t5-j##PssI+k+tozw+NoypjNCQ2tYwK$1mAHjVYvK( z{-`jR`wJIz2kzx9)?_;t>=agiaIdt+HMxSsenT4*s?A94Yf=O#Bs?4~=`Tl6lHIDM z2$l2E;ppYyaFn#vh4QexaT~R!peB(2yGiB8#cvw_B(;mKs36zNgl5$YdQ9QJfz<1edR-zdRi6-2 zS55m%b%hG4_Y0}DB}4C@@KdRo`9y|!5+@*W0umoc=S)av7KwjyeJuQ-VEw7TNbO#k z?F&l0NtTmOgWLmh*Jl=}ylwMl6x@S1%N4OKT3yL7bq5sPgrb{VQIk-#deUD}i;%<% zrCBIyIVeTYiX~mmQ+~R7+}bYXZVJMtAgn4P0^bu0w+hgjd@B4M-6$&)kxAGk(-l zdN0$Ilxbl&n<|H$0qq&?NL0YCiiIB$u>pJ%FN zseL5A$%Tc@T|`c~P51?fc!ED&j;EVPic`MGjfd;{;v3Q1O}iz(kGNwRK=R*1I5YFT zyyUkC&mI=_^Db@7h?7Gi@h3Sax$8?8|G%*AV1)Wj__H+~-{ks6w#@k@#k7&#IpkoD zXE!dg`_%ECeqc$-l3^g!diy^HD0pA>wB8!?rIpL=uD<-L#W0q=Y#WUgrgq+~ss3QDbv2a2_ zCts8n&7Z`OA9BJpGhUYs0dNR_S~|`!`cuM^^dF^mZ}fVjzZ)?%jDC{3R%TJ*5Hl0o zv8kYDuEC*e+#y|1d@2^+E-3C8ks@f}lHJ=+`f+52rmKd5h6dtEa6HLHX9OZ%n{%n0iKnP+c44* zM&{p>+R+k1vS;K@gtWMk&ebv_HNNzCHeQ8|SGkQn9=~3}udsn|YP|z~)XF!R0Zr?2aM1_P3$EWjT!S;XNS4FP!9MbQe@$t-$>}+UQJQ!Aw7=$Zu)l`1 z?5^MyMaTruqio{!#uGdH+1-z)qa^{|%*!NM0S71v%m=4Vb}+wp2)3`>fQJN#;a{C+wnMZ5v` zF6G0&FtEw1^pu|(zT~4zPC>*ei1-mm@0L@q(f`om4ghMCxPI_0{5&i_&n^FP!E!Y9!2;`_(4$go5zbwy4$?DzT=~wZAfLOK zWdipMIG+LM`zjl5h32ETLYITLLgbZq0*7ci{!@xRI$R*#Pp?SrUU7PzG{E^BqP&+5 z(}gk#XePc}tAhUm_%DF}5qL95c^kxVzz@;E(t1@~CsM;O&h=}g5PFpUPHHPoZTN-f zl_T_0SuioHq306fT#`uZvay0s=&tbs%mf{;?kK{zK8@3f>QZl6Xe*81n6vzHJ|CT^ z#&TXwIwxs8ZtBZ$_dN=vzXn()qvvehCK9+zaqwySR^f8HI*ID469a-AqrZ(N&1??$ zcHEw)=-Frj8`FIBEKENe#r1clKysEI^{wl|MZ>*R9p}N&WGCnWiC1!|*N)Rkzl^(s z_kZpklVC83v{Ozfc#_t~PZg;AjK1wlh4&WdAaE>vTIl9lSETYr(*19WIY=xcB?sT2 z^+eu)OT5F}-Qo;Qi2v~@K%9-9rZsQ!(7WZXx9G2_W8t=r&-?g<3Hdn<5dIE*lZr=_ dl3ySl0G9VqUBkYjr*vGK=BWE#2=7rs{tI8e{D}Yn literal 4483 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 literal 4208 zcmai1Yj_k_89rwhYIaDwO3bDWR%6pDT0^o)8o*wpY|>iADKe$D-lnrNXOn^5neEIh zNobW?D?(c=l~gL1a4Bf3RUf$%2=`0$!SEx$N&_PD&!1lK2R`_oIkT6*GwJ@==h@kr z_xs-Wyx(P3JU;)i=zXNhHM=clq?ZwSJMA?MuZPe}k+xPsQv0Vg>Z;eDXC$&QB5qSn z%OiwDyL8)fJq>eiCsqHB zHTT##*6grCnpw>TTgI|>KF2Jt*<-HP)QyW-Gu^DGb2@J7c9`n|zFD(evq^8(9KA=) zWVLQr&FT4q+HKng_@@3u8`GN0NNkOiY{7-8gVR(swQ$jsPj@X+9lKx|Jdd1hFfy7D z)X3npv1kh4WR4Uo0KP0Ug|yQKBgKml0S^mht7mXIbUj&`)nD2i1Et2a#mM zHJ3B;nd`KOg%n`B29d#MN2NAlp(<|122$5>z9Nwv%W*S}Ce9=9d5N^%!}2y#VGdCm z=doPg>&H{~3atAsO6{dXSrx72bwtVMp!Gd+=jSg{dGUe;$mrfnl>xLYjIY}1CGaic zTtb{nAULxskhT_DM#vY$fqn64;v*`Giyyxq`F!b*2~j(|bl_#vLx6(Anq1F;Lq!!e zt&@^%mB)Vnkwn=-m5-@hPStePqE(UWk;GW^NP@J?5;ll83mIxrk8tG;+Qcoyqbg>gp{S3u?pC-YEnwyF5Tg3KcqBgvvC{o;Q3L>L(@i)O-m8jj-x zD4YO=nO_lr^Hx_+YL;XR`d2Fcs0ccLgOr?IsoRs53H@_!Ng{8{Sjy20dYX{;fWO#}T^mT!VcDg_yeq+6qe4r9>!SOJ}jM>KwHDfy% z4z|X1KMvUAfR%NnLpGkgPW}F}Q1JieVW|x=`?*5wg`{rba0O-2Rb7?!p+0$+9tP`S zuwGQJ^ARHdk2(xxYl-Pg^o2Xcu*mpzL3!ETpnW;W9+GOi8Q+7XyP1lKbIg4v+A0!#YPj?Vq?*3G4lGc$jomEjh=b? z_Q^~H5BVl~R_OTc8?n-1^MiSIZ<(i7s>j z3SHm|{e<6-YH(8Vl^hwP_NVkUsRYa&x{?lsW$R+osNgDyex8hzEiADiu2j-zi?BGnChZ0BG@R0!4mC*HzD*khmOum6A1dpt`)AAp!?)REUy%PKf>?l;eQc?ey=*xu)n5% znRJ4|CjL9XyFB({KK}2@6fE6;vwn|a)|cx{j{b($6L~&f-#z9pk-w$SiFJef3<&2E z@6zh`dE^ec^LO+V^&Gs|<8uR_I3d5M5&s_gJ{6ZRrT>7l2e7=tG_aSN858eH?+K_F IZli?!ALiP`UjP6A diff --git a/regression/ansi-c/arch_flags_mcpu_good/test.desc b/regression/ansi-c/arch_flags_mcpu_good/test.desc index c7daf68b878..141e5a37063 100644 --- a/regression/ansi-c/arch_flags_mcpu_good/test.desc +++ b/regression/ansi-c/arch_flags_mcpu_good/test.desc @@ -12,12 +12,17 @@ The object file 'object.arm' was compiled from 'source.c' with goto-cc along with an ARM cross-compiler on a 64-bit platform with the following command line: - goto-cc --native-compiler=arm-none-eabi-gcc -mcpu=cortex-a15 -c source.c + goto-cc -o object.arm --native-compiler=arm-none-eabi-gcc -mcpu=cortex-a15 -c source.c -On Ubuntu, you can get a suitable compiler using: +To regenerate object.arm on an x86_64 machine, you will need to install +an ARM-32 cross compiler and pass the name of that compiler to the +--native-compiler flag. On Ubuntu, you can get a suitable compiler +using: sudo apt install gcc-arm-none-eabi +which will install arm-none-eabi-gcc (amongst other things). + preproc.i is already pre-processed so that it can be linked in without needing to invoke a pre-processor from a cross-compile toolchain on your local machine. Linking it together with the ARM object file, while diff --git a/regression/ansi-c/arch_flags_mthumb_bad/object.intel b/regression/ansi-c/arch_flags_mthumb_bad/object.intel index 72136c8ae3c2dde8dd0dd3f52071351503030d68..fc2d521766a2ba4b6dbf66c986efcd814df9c79c 100644 GIT binary patch literal 4456 zcmbtYZFCe@8NPS7X|j{h)r4vZ)M1G%I%r01lV)x}3q3c;TXZMjU3v(;xvt*^oNB3AW-}{K?j&FvAe8|_&k#B2$heaPW+g?5J-Kzu(;K%c zx&ex6M&HHAd{pQnv(n{Y41be`s;a!6Hkg*!N#se|qic3I3B4C+YX$JWU}F;6Y}K%d z^oKwMkKVqcF)7Td9twzGB7hBEH50a^fQ9gOHIch^s+j^KcMUFUS>hAHcU(&t zK7XJ;DlFy>!w21le+7#*$=4}%H@J7g$ zyY6{MT0))k6_>XH@`7?*{V%095JizV>}!#_IaETYe?ETWb2$nI;&QS zSRWZ%%1Z8}W97ZvO1bW%FG(Hcq3#{=Gbi6|S~i#HIWz)?M&QtWA>?y;EZiXIOM>{G zKqL1-V=3~nTcMKUdDNPMnn3>VCY2u-ziIrF)Gqp>f?O{XnpHFCGKK#JQm;emb&0f8 zeL_fGHSI6e5h|qKFQnF%484ECPo-uS5*g-6oPfj$NPHljGa;Q>B>u_uvG9X}^{4(K zwR>f@FDUUQSx!C;au3K|pIM;tw#}PSa1Y)rSH!Ytb|u5q9Z+-=if(d6O+wM?Nq{=$%^9I_(GQ zVCs3r?E(mz2JSS+ZTE232;7dtQUrZdBD?08AFfMwG4wG&9|QDSUTz`G9|p%QPirS{To!%3)_fdxkp_6|k#f;YS4Q`j@4(<%T>m>WAt~7k9*X#W@P(Q6N8> zj&I;2HFhP?iRuu>bR7ur^zbu*7v;u_6vq)iMiete;*T}xhQ@kH{P77Y=BDEMf@$-4 zrdpQTN8+0tSlHY}Nnxf)^vQ6;~UvB=a&>SkL=DN z2Xj2Tagp7pj^B<1KPbc7gqo)p0+B`IciXIAG@Q|CBg>phokh@D9`ws1=;~Pb83Fi} z{nA6_CH2g>A6_13W!az`2jn;)>%O`&{xyM$k?<@~aUg|CP0Np>XD^hslfimzrTjd) zfHu0o+vw{8<{SHKmd>^q(uxr9%^@kWs40{aehRW;lA1YYsfOmB5hozz1ouW2;qQut z69PKKu6Q-H*x@-u5Ljcs$afZ>K5|*U@D7AZ|*Bkxah^b-plhm~`i;9Ps znb?j^1vPUG4qf98>4M@@vG8_5amR=hK?|4c-hR@LBQrEzH4HQ~5Kn^RNiI4g5HVx2 z0@3()Xwfjw4*CJQE$j&&1n3|KH3cZDEGIyp`&Y=*&c|Wyh#x4nTrV?6fOiCVRyv-C zk+v|h@SfC;mJpIXBX=UC#f`MDmKmw>rN^`JDr~&UZS3**^$LE)4TMwc9q^-8zR3)L z+5o8aiK7L_3fZ+X{w;xvK6qYm{r2G+oWU+x4lf7$$n*U*rR^rC=NLw5!Rgcfn#;ld z8q%`6f>#tFFRV38n>|-hGbH{Z_0acF0skHPXQ_QriN?R{zJ*A;V`03xhu$c2q*z)w zC=J%5h^ajvy#Z%#aA&?({5k4jFAsu+FIFn9y>!gaoZ`0Q)xsDI8iPTPexF{X@gLBJ z_z&p>m4h!)hC!Ly$KzlGzf4cxZu~7d3tA!()B+6ddWHTi)Z5viIIDK})gt-*bWDnP z1MXeQhktQklUL~}KQ(;GN0*#}h*J>pBaq%Lr(UD~q3#Xz~l0QmYH+tW*c-89%OkXH<~S zUCc6pdj_1(fb)Ho4Yxw`(OaR*!CN8n$~%EWG#&pbMIRk5lJ2Khq;{`3y-ph7d=63G zONZ$~nFKTw->p@_e*yd#!2bxm8Kk@oVmRQ3=wNBRa@UE}FpP8j8YzYzrN5Kf+^G$} z@Vs(_UMdSFW;OI&LYzwyXBNdWiom$ujh#bE>j$Qn!Z)M+^$Zdy6VJ$Ajjx$qe(NH z!_6JH=P7zNn!v_1A3Y1x&qi_mohg!>rAK}1x_HrWE>*{QFf`c-dO+fpTY(1v&^E3!fIcxz-h_f{}Foqhbyc%Sg$= zH)uVPH{cR)GiSFrLlffvJc_Sxx$7g1PK4C(BP6LF$L*Jz0 f5vAl8NC$xBJyh4QujnZq*QPn@ycfcIl#u@d@=5(+ literal 4485 zcmbtYU345}8UDUq0^LbqwGo9>F%YX&3CSjDy4AYYP6CK^fUZSUaG2fsHko#JW;;9E zB-L7eL@E?4O`HE8^3$J4s6dENtv#Njhf^=?O>V4hsI`~g`BN`M@%iSPo!!WpdcmI4 zoYR@v=Y5~&d*A1MXZPK+A|uyN-q;-Y ziMe+WB-&80iguc*Su3qMhGmi)2vJsNj4UIo4ktFHibmEk%tp;lcN-2%J4Kr{7986! zy9xRXvuy6Sq{|u<@*A_Yvvuk*01d$C_+bOfj=bXS-R}%IBEr zG&!u`Gatm(fIONsvtTr)n|NR~lhwKkYR>5{=2B`()1iU&UY_)D5eO{WsBQaWy& z4pvMEhB$KcCg`(Dsf|7(ZE!hDJeO*6(`ZoqtOZ5fKR7-=jZwrO<9L@e$ZhA9p*tl;!&2PHw(aOoSw(z=7}II-72Okl$-$C z1V{U*K>OI(wJ5j}atgPIh_^m1wO3NOWh5wUq1&<@Ui&_e5kwy0k?TD1Q=3^X@AN^{wSfQhKO&-I8+ps> zy1_eI^yz2*EVcQ<><@>y1+BXjYR5J5S>)KDbbM}^D%-bi#f7z3q;fCiSPqS>W|_7V z#I8t7;VTk|ecl)9PC+bG*67Y7L7XZN@d)S~0iDJweiVeJoChgxof<zIv!;qfdx?s}k-Y_x9J6HO?D(rlzeTuoe^j zHA~_C8q$0pOMVTiY!x71|D)6f#}q~BtD+#*eO#5T7gnmGt5#|UW)|=+K$QzzmHS0v z4;)MUpCaVrI{KhcZrgGww!+sQJQ}2&mPLK>Nr<3Fq1jPx7)cTI8~ban85C~HgKif= z9~zcoE2h!*<3T~acDC}&)=b~8jwAeW9{!siXF2+?fd1B~6pNR1V{^T z7~mju0*EJo`0cv1r8A=Zo7xQ9gDF;;D&=B0ui09T!Nv;YJ4E?Qh-I@zzF-tc2*e&i z^haOyhV@-(Bv32*j(qoQB5mdJ*if(sJhG5TX*R+wAlyQN)Du+@c%~IGyZAKf^)#T&l3Oxc23vMfN)fY=N#i>zN3IRR}>Ni8cB%bg5@=0k3&;&BROCg*bb%Zv>-%G8f?t(TBi96>iv=POP zAm^aTIf=CFX2~9|`Yvvah|zm6RD#A)kiNGm#w1@kRVzc1d+H5SXT2o(y(ub|T$qfv zl`G-zr;~dH7I2W-51(}WFPG?fPofv-q|{RC z82K!9r75u?&(rxJ78W#9z)~u@TP^ar zwwRbe-A$kuUxbQ>=w>}dziRHu}O3MIV=1o4p zzro*DsZM*T&d^^;t-j8Fs?+pLMXDz2b=1my&miA3P9Rv>bVH!#oL<$o4vvl6Lqi?6>LSxj7wEQPN|$bnyn$cb{obDkVO zrH7>0imi2yP6x^1n)FJGo`xdRP^9YRGWNWe`zv&;y1itVuGI5%yt=$b+1Q|T{=S~$ zBYH70UcD3^uO@NIXKMH)txNvQ1AUdgam^0KOoixj^fey&Q9i40%@obF`-{Ts6oa{3 zqDpvy))8e3e(Z3VyZyXD9}~NQhp>=%jn*vk$c;+J&*^WeW8()6eBQ$+O30h&aQ+Nk gq~a2#WfR%lQj)ls|7t(Q(`cfQ?Bvpch$ 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 literal 4268 zcmai2Uvv~#9lm$BY1v8WT4HS*w2h5etES0jLlSDcMK(}vaf)nCiSkvHG;C_do9@6Mf_-Pkj6&q>b7 z%|P?z&|X7#dkDQ8NwyG@J``=xEYopS(|*Zz=|E6LQPe;8{89JyEp=h!kIm61j7)nkzDL>tw2V^$#bB zH#k<&)|isBG}SdMliWs#yspd0F|y`p>XB^G$hn5usM=bO;WEuF+N{xWZNuz#Qh2g9 zXPAt{`lUn?e|=chYuS5nPtgq<4_o#=BK3S}t#Y(V?p!;& zHq^F+xWj$B9WJerYvXT83HXT0B`&C%+&&g2B4=@5tYS9D6w&;})EMZ;IQb_8`5jZ? zx?IVfqhVq3Zm_qSWD85BgZCl+(GRZ35M);|F#<$*}hS_D92HZfH zq~ja8A#!coZ>1y>%IhNJY$WXw)5zfw><+T=Tt&HVkIhuwQCJ_+mgm$tRD2E|cB{$P`%TeZwKfdw46_PEgawUevQsszti@O6Iu@3Fp)Hl+<+Ovj%PU43#wN(5zn zKpS#m{zXV;yYB#u-iDuVu*^13GI?S?tnYkmp!Rt*dLE6IS>~zD>G%#|;5R>#T1#!@ zW(WgzfJCNp(IHBBrCD4c`BIVdFG7l_JhHLGq|%sAfK-GWse zkrFG?YWHjytDh5Af!V4VXO;ndRf{i_(^K(qz(s`av zR4+v*s!0c{)A$AXKh$P83Yp@3RwXY-3#zT=8Ag~xx`_O@2+QS+f@3%&f^xdS*>lD} zb3CM>-L(-B2F80S&B_;W+`^Hjdm)v@##&4*K=wk4)IZPn3ibEh!=!zW(EgWnln<%ijzzJbeOk1mw6KIXSM~*(@=Ms_tX-Y zcckM5f%(FXm^cRdhoQni805$1$^bwI0BVbpFjFkPV@|<{Q{3H`XkhQl zRG|89@X_@$Jr)L2Ij)ZZ?HJHrp)B)bii|kOp)ituLN7_JLH~o4c$JgBLU~Rcq?bQ# zUXW;)Vc%ug_fx864$)GkzeY#OBdIhc^q>+Of>g-SYa z?8A-=;JF}?7V<{fjyHWf-l9jPM5)tWc)m%;!(1s%^wQCL9L|ixnIoQfK2DF)iL&_8 z0!4$5(e;^rpS>v^AMlG9q`#3`f}G_&k)uZ_8K7q?>Jal>G59Dyi&D-?q=Ovy!4R)Q zeksHBQY2Aw#4BZp&V-es=I|E7U!VXwgED5kGEP9|NLl8nFLR9kPD%!i4rGqf^A$2p z*5@jfTF*o4d9-(&)*gaJ;aU518=V-fW zx$K3anj@L{vLz?|3Qp0#NUbY^ito;3I*tcU(yJ9!_>qC^Gg&X*DfyvqF?AK?T!lH5 zr*-sgT9-NPll+{%yJ}`&yrC88_!+LGhfjffx{9Xey?DPv5&7kVz8qbkbwu8R{|UIv zYxcWzx0pIU!b0i{ty$#ENxAbE^bgdv@!pTmO?={n{1UOlpP`FXT*6`dSLi2z Date: Wed, 11 Oct 2017 10:16:50 +0200 Subject: [PATCH 2/7] grapht::output_dot needs digraph declaration Without the "digraph call_graph{" this is not parsable dot. This change makes the output dot consistent with the previous output_dot function in call_grapht --- src/util/graph.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/util/graph.h b/src/util/graph.h index 607a7e3d8e2..502eeab826a 100644 --- a/src/util/graph.h +++ b/src/util/graph.h @@ -655,8 +655,12 @@ std::list::node_indext> grapht::topsort() const template void grapht::output_dot(std::ostream &out) const { + out << "digraph call_graph {\n"; + for(node_indext n=0; n @@ -668,7 +672,12 @@ void grapht::output_dot_node(std::ostream &out, node_indext n) const it=node.out.begin(); it!=node.out.end(); it++) - out << n << " -> " << it->first << '\n'; + { + out << " \"" << n << "\" -> " + << "\"" << it->first << "\" " + << " [arrowhead=\"vee\"];" + << "\n"; + } } #endif // CPROVER_UTIL_GRAPH_H From e62f7550a0e135006a7902bf47810b492670eb14 Mon Sep 17 00:00:00 2001 From: polgreen Date: Tue, 17 Oct 2017 13:38:34 +0200 Subject: [PATCH 3/7] Introduce reachable call graph class, and rewrite call graph to inherit from grapht I have rewritten call_grapht to inherit from grapht, because I think there should be fewer graph classes in CBMC. Instead of constructing the entire call graph, the reachable call graph class constructs only the reachable call graph. There is some duplication between the call_graph class and the show_call_sequences function, however the show_call_sequences function outputs the graph on the fly, instead of constructing it, which doesn't allow for further use of the graph --- src/analyses/Makefile | 1 + src/analyses/call_graph.cpp | 104 +++++++++++------ src/analyses/call_graph.h | 61 ++++++++-- src/analyses/reachable_call_graph.cpp | 105 ++++++++++++++++++ src/analyses/reachable_call_graph.h | 36 ++++++ .../goto_instrument_parse_options.cpp | 20 +++- .../goto_instrument_parse_options.h | 1 + src/goto-programs/slice_global_inits.cpp | 27 +---- src/util/graph.h | 2 +- unit/analyses/call_graph.cpp | 36 +++--- 10 files changed, 304 insertions(+), 89 deletions(-) create mode 100644 src/analyses/reachable_call_graph.cpp create mode 100644 src/analyses/reachable_call_graph.h diff --git a/src/analyses/Makefile b/src/analyses/Makefile index a63a4d4e1c6..8094a345251 100644 --- a/src/analyses/Makefile +++ b/src/analyses/Makefile @@ -22,6 +22,7 @@ SRC = ai.cpp \ locals.cpp \ natural_loops.cpp \ reaching_definitions.cpp \ + reachable_call_graph.cpp \ static_analysis.cpp \ uncaught_exceptions_analysis.cpp \ uninitialized_domain.cpp \ diff --git a/src/analyses/call_graph.cpp b/src/analyses/call_graph.cpp index 93850f64d1d..683ed7905dc 100644 --- a/src/analyses/call_graph.cpp +++ b/src/analyses/call_graph.cpp @@ -7,7 +7,7 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ /// \file -/// Function Call Graphs +/// Function Call Graph #include "call_graph.h" @@ -18,14 +18,9 @@ call_grapht::call_grapht() { } -call_grapht::call_grapht(const goto_modelt &goto_model): - call_grapht(goto_model.goto_functions) +call_grapht::call_grapht(const goto_modelt &goto_model) { -} - -call_grapht::call_grapht(const goto_functionst &goto_functions) -{ - forall_goto_functions(f_it, goto_functions) + forall_goto_functions(f_it, goto_model.goto_functions) { const goto_programt &body=f_it->second.body; add(f_it->first, body); @@ -51,50 +46,91 @@ void call_grapht::add( const irep_idt &caller, const irep_idt &callee) { - graph.insert(std::pair(caller, callee)); + std::size_t caller_idx = node_numbering.number(caller); + if(caller_idx >= nodes.size()) + { + node_indext node_index = add_node(); + nodes[node_index].function_name = caller; + } + + std::size_t callee_idx = node_numbering.number(callee); + if(callee_idx >= nodes.size()) + { + node_indext node_index = add_node(); + nodes[node_index].function_name = callee; + } + + add_edge(caller_idx, callee_idx); } -/// Returns an inverted copy of this call graph -/// \return Inverted (callee -> caller) call graph -call_grapht call_grapht::get_inverted() const + +void call_grapht::output_dot_node(std::ostream &out, node_indext n) const { - call_grapht result; - for(const auto &caller_callee : graph) - result.add(caller_callee.second, caller_callee.first); - return result; + const nodet &node = nodes.at(n); + + for(const auto &edge : node.out) + { + out << " \"" << node.function_name << "\" -> " << "\"" + << nodes[edge.first].function_name << "\" " << " [arrowhead=\"vee\"];" + << "\n"; + } } -void call_grapht::output_dot(std::ostream &out) const +void call_grapht::output_xml_node(std::ostream &out, node_indext n) const { - out << "digraph call_graph {\n"; + const nodet &node = nodes.at(n); - for(const auto &edge : graph) + for(const auto &edge : node.out) { - out << " \"" << edge.first << "\" -> " - << "\"" << edge.second << "\" " - << " [arrowhead=\"vee\"];" - << "\n"; + out << "\n"; } +} - out << "}\n"; +void call_grapht::output_xml(std::ostream &out) const +{ + for(node_indext n = 0; n < nodes.size(); n++) + output_xml_node(out, n); } -void call_grapht::output(std::ostream &out) const +call_grapht call_grapht::get_inverted() const { - for(const auto &edge : graph) + call_grapht result; + for(const auto &n : nodes) { - out << edge.first << " -> " << edge.second << "\n"; + for(const auto &i : n.in) + result.add(n.function_name, nodes[i.first].function_name); } + return result; } -void call_grapht::output_xml(std::ostream &out) const +std::unordered_set +call_grapht::reachable_functions(irep_idt start_function) { - for(const auto &edge : graph) + std::unordered_set result; + std::list worklist; + node_indext start_index; + + if(get_node_index(start_function, start_index)) + worklist.push_back(start_index); + else + throw "no start function found in call graph"; + + while(!worklist.empty()) { - out << "\n"; + const node_indext id = worklist.front(); + worklist.pop_front(); + + result.insert(nodes[id].function_name); + for(const auto &o : nodes[id].out) + { + if(result.find(nodes[o.first].function_name) == result.end()) + worklist.push_back(o.first); + } } + + return result; } diff --git a/src/analyses/call_graph.h b/src/analyses/call_graph.h index 684f74c3a3a..b8a4d61d58b 100644 --- a/src/analyses/call_graph.h +++ b/src/analyses/call_graph.h @@ -7,34 +7,77 @@ Author: Daniel Kroening, kroening@kroening.com \*******************************************************************/ /// \file -/// Function Call Graphs +/// Function Call Graph #ifndef CPROVER_ANALYSES_CALL_GRAPH_H #define CPROVER_ANALYSES_CALL_GRAPH_H #include #include +#include #include -class call_grapht +#include +#include +#include + + +/// Function call graph inherits from grapht to allow forward and +/// backward traversal of the function call graph + +struct call_graph_nodet: public graph_nodet +{ + typedef graph_nodet::edget edget; + typedef graph_nodet::edgest edgest; + + irep_idt function_name; + bool visited = false; +}; + +class call_grapht: public grapht { public: call_grapht(); explicit call_grapht(const goto_modelt &); - explicit call_grapht(const goto_functionst &); - void output_dot(std::ostream &out) const; - void output(std::ostream &out) const; + void add(const irep_idt &caller, const irep_idt &callee); void output_xml(std::ostream &out) const; + call_grapht get_inverted() const; + std::unordered_set + reachable_functions(irep_idt start); - typedef std::multimap grapht; - grapht graph; + bool get_node_index(const irep_idt& function_name, node_indext &n) const + { + for(node_indext idx = 0; idx < nodes.size(); idx++) + { + if(nodes[idx].function_name == function_name) + { + n = idx; + return true; + } + } + return false; + } + + std::unordered_set get_successors( + const irep_idt& function_name) const + { + std::unordered_set result; + node_indext function_idx; + if(!get_node_index(function_name, function_idx)) + return result; + + for(const auto &o : nodes[function_idx].out) + result.insert(nodes[o.first].function_name); + return result; + } - void add(const irep_idt &caller, const irep_idt &callee); - call_grapht get_inverted() const; protected: + void output_dot_node(std::ostream &out, node_indext n) const override; + void output_xml_node(std::ostream &out, node_indext n) const; + numbering node_numbering; void add(const irep_idt &function, const goto_programt &body); }; diff --git a/src/analyses/reachable_call_graph.cpp b/src/analyses/reachable_call_graph.cpp new file mode 100644 index 00000000000..50674fde86c --- /dev/null +++ b/src/analyses/reachable_call_graph.cpp @@ -0,0 +1,105 @@ +/*******************************************************************\ + +Module: Reachable Call Graphs + +Author: + +\*******************************************************************/ + +/// \file +/// Reachable Call Graph +/// Constructs a call graph only from the functions reachable from a given +/// entry point, or the goto_functions.entry_point if none is given. + +#include "reachable_call_graph.h" +#include + + +reachable_call_grapht::reachable_call_grapht +(const goto_modelt & _goto_model) +{ + build(_goto_model.goto_functions); +} + +void reachable_call_grapht::build(const goto_functionst & goto_functions) +{ + irep_idt start_function_name = goto_functions.entry_point(); + build(goto_functions, start_function_name); +} + + +void reachable_call_grapht::build( + const goto_functionst & goto_functions, + irep_idt start_function_name) +{ + std::set working_queue; + std::set done; + + // start from entry point + working_queue.insert(start_function_name); + + while(!working_queue.empty()) + { + irep_idt caller=*working_queue.begin(); + working_queue.erase(working_queue.begin()); + + if(!done.insert(caller).second) + continue; + + const goto_functionst::function_mapt::const_iterator f_it= + goto_functions.function_map.find(caller); + + if(f_it==goto_functions.function_map.end()) + continue; + + const goto_programt &program= + f_it->second.body; + + forall_goto_program_instructions(i_it, program) + { + if(i_it->is_function_call()) + { + const exprt &function_expr=to_code_function_call(i_it->code).function(); + if(function_expr.id()==ID_symbol) + { + irep_idt callee = to_symbol_expr(function_expr).get_identifier(); + add(caller, callee); + working_queue.insert(callee); + } + } + } + } +} + + +std::unordered_set +reachable_call_grapht::backward_slice(irep_idt destination_function) +{ + std::unordered_set result; + std::list worklist; + for(node_indext idx=0; idx + backward_slice(irep_idt destination_function); +protected: + void build(const goto_functionst &); + void build(const goto_functionst &, irep_idt start_function); +}; + +#endif /* SRC_ANALYSES_REACHABLE_CALL_GRAPH_H_ */ diff --git a/src/goto-instrument/goto_instrument_parse_options.cpp b/src/goto-instrument/goto_instrument_parse_options.cpp index 5fa1567001b..88acb7f061e 100644 --- a/src/goto-instrument/goto_instrument_parse_options.cpp +++ b/src/goto-instrument/goto_instrument_parse_options.cpp @@ -60,6 +60,8 @@ Author: Daniel Kroening, kroening@kroening.com #include #include #include +#include + #include @@ -647,17 +649,25 @@ int goto_instrument_parse_optionst::doit() { do_indirect_call_and_rtti_removal(); call_grapht call_graph(goto_model); - if(cmdline.isset("xml")) call_graph.output_xml(std::cout); - else if(cmdline.isset("dot")) - call_graph.output_dot(std::cout); else - call_graph.output(std::cout); + call_graph.output_dot(std::cout); return 0; } + if(cmdline.isset("reachable-call-graph")) + { + do_indirect_call_and_rtti_removal(); + reachable_call_grapht reach_graph(goto_model); + if(cmdline.isset("xml")) + reach_graph.output_xml(std::cout); + else + reach_graph.output_dot(std::cout); + return 0; + } + if(cmdline.isset("dot")) { namespacet ns(goto_model.symbol_table); @@ -1452,6 +1462,8 @@ void goto_instrument_parse_optionst::help() " --list-calls-args list all function calls with their arguments\n" // NOLINTNEXTLINE(whitespace/line_length) " --print-path-lengths print statistics about control-flow graph paths\n" + " --call-graph show graph of function calls\n" + " --reachable-call-graph show graph of function calls potentially reachable from main function\n" // NOLINT(*) "\n" "Safety checks:\n" " --no-assertions ignore user assertions\n" diff --git a/src/goto-instrument/goto_instrument_parse_options.h b/src/goto-instrument/goto_instrument_parse_options.h index 04b3a8f7b2b..d6f85090923 100644 --- a/src/goto-instrument/goto_instrument_parse_options.h +++ b/src/goto-instrument/goto_instrument_parse_options.h @@ -44,6 +44,7 @@ Author: Daniel Kroening, kroening@kroening.com "(max-var):(max-po-trans):(ignore-arrays)" \ "(cfg-kill)(no-dependencies)(force-loop-duplication)" \ "(call-graph)" \ + "(reachable-call-graph)" \ "(no-po-rendering)(render-cluster-file)(render-cluster-function)" \ "(nondet-volatile)(isr):" \ "(stack-depth):(nondet-static)" \ diff --git a/src/goto-programs/slice_global_inits.cpp b/src/goto-programs/slice_global_inits.cpp index cc4f7349eb7..a08b3331449 100644 --- a/src/goto-programs/slice_global_inits.cpp +++ b/src/goto-programs/slice_global_inits.cpp @@ -30,11 +30,8 @@ void slice_global_inits(goto_modelt &goto_model) // gather all functions reachable from the entry point call_grapht call_graph(goto_model); - const call_grapht::grapht &graph=call_graph.graph; - goto_functionst &goto_functions=goto_model.goto_functions; - std::list worklist; - std::unordered_set functions_reached; + goto_functionst &goto_functions=goto_model.goto_functions; const irep_idt entry_point=goto_functionst::entry_point(); @@ -44,26 +41,8 @@ void slice_global_inits(goto_modelt &goto_model) if(e_it==goto_functions.function_map.end()) throw "entry point not found"; - worklist.push_back(entry_point); - - do - { - const irep_idt id=worklist.front(); - worklist.pop_front(); - - functions_reached.insert(id); - - const auto &p=graph.equal_range(id); - - for(auto it=p.first; it!=p.second; it++) - { - const irep_idt callee=it->second; - - if(functions_reached.find(callee)==functions_reached.end()) - worklist.push_back(callee); - } - } - while(!worklist.empty()); + std::unordered_set functions_reached= + call_graph.reachable_functions(entry_point); const irep_idt initialize=CPROVER_PREFIX "initialize"; functions_reached.erase(initialize); diff --git a/src/util/graph.h b/src/util/graph.h index 502eeab826a..0e2a0f6157a 100644 --- a/src/util/graph.h +++ b/src/util/graph.h @@ -263,7 +263,7 @@ class grapht std::list topsort() const; void output_dot(std::ostream &out) const; - void output_dot_node(std::ostream &out, node_indext n) const; + virtual void output_dot_node(std::ostream &out, node_indext n) const; protected: class tarjant diff --git a/unit/analyses/call_graph.cpp b/unit/analyses/call_graph.cpp index 985c804c91c..77c328cecac 100644 --- a/unit/analyses/call_graph.cpp +++ b/unit/analyses/call_graph.cpp @@ -30,15 +30,13 @@ static symbolt create_void_function_symbol( return function; } -static bool multimap_key_matches( - const std::multimap &map, +static bool graph_key_matches( + const call_grapht graph, const irep_idt &key, - const std::set &values) + const std::unordered_set &values) { - auto matching_values=map.equal_range(key); - std::set matching_set; - for(auto it=matching_values.first; it!=matching_values.second; ++it) - matching_set.insert(it->second); + std::unordered_set matching_set = + graph.get_successors(key); return matching_set==values; } @@ -106,10 +104,11 @@ SCENARIO("call_graph", { THEN("We expect A -> { A, B }, B -> { C, D }") { - const auto &check_graph=call_graph_from_goto_functions.graph; - REQUIRE(check_graph.size()==4); - REQUIRE(multimap_key_matches(check_graph, "A", {"A", "B"})); - REQUIRE(multimap_key_matches(check_graph, "B", {"C", "D"})); + REQUIRE(call_graph_from_goto_functions.size()==4); + REQUIRE(graph_key_matches + (call_graph_from_goto_functions, "A", {"A", "B"})); + REQUIRE(graph_key_matches + (call_graph_from_goto_functions, "B", {"C", "D"})); } } @@ -119,12 +118,15 @@ SCENARIO("call_graph", call_graph_from_goto_functions.get_inverted(); THEN("We expect A -> { A }, B -> { A }, C -> { B }, D -> { B }") { - const auto &check_graph=inverse_call_graph_from_goto_functions.graph; - REQUIRE(check_graph.size()==4); - REQUIRE(multimap_key_matches(check_graph, "A", {"A"})); - REQUIRE(multimap_key_matches(check_graph, "B", {"A"})); - REQUIRE(multimap_key_matches(check_graph, "C", {"B"})); - REQUIRE(multimap_key_matches(check_graph, "D", {"B"})); + REQUIRE(inverse_call_graph_from_goto_functions.size()==4); + REQUIRE(graph_key_matches + (inverse_call_graph_from_goto_functions, "A", {"A"})); + REQUIRE(graph_key_matches + (inverse_call_graph_from_goto_functions, "B", {"A"})); + REQUIRE(graph_key_matches + (inverse_call_graph_from_goto_functions, "C", {"B"})); + REQUIRE(graph_key_matches + (inverse_call_graph_from_goto_functions, "D", {"B"})); } } From 04e56c3cc2674e56b8959a9b415154644b7e1a0d Mon Sep 17 00:00:00 2001 From: polgreen Date: Tue, 17 Oct 2017 09:48:32 +0200 Subject: [PATCH 4/7] CR fixes for grapht Michael's comments on CR-766007 highlighted things that should be changed in grapht. --- src/util/graph.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/util/graph.h b/src/util/graph.h index 0e2a0f6157a..900a5c57ac7 100644 --- a/src/util/graph.h +++ b/src/util/graph.h @@ -666,15 +666,12 @@ void grapht::output_dot(std::ostream &out) const template void grapht::output_dot_node(std::ostream &out, node_indext n) const { - const nodet &node=nodes[n]; + const nodet &node=nodes.at(n); - for(typename edgest::const_iterator - it=node.out.begin(); - it!=node.out.end(); - it++) + for(const auto &edge : node.out) { out << " \"" << n << "\" -> " - << "\"" << it->first << "\" " + << "\"" << edge.first << "\" " << " [arrowhead=\"vee\"];" << "\n"; } From 799d0348961d180619bba430280430865f3da2cb Mon Sep 17 00:00:00 2001 From: polgreen Date: Wed, 11 Oct 2017 13:23:49 +0200 Subject: [PATCH 5/7] return shortest path from function call graph Returns the list of functions on the shortest path from a src function to a destination function on the function call graph. --- src/analyses/call_graph.cpp | 20 ++++++++++++++++++++ src/analyses/call_graph.h | 1 + 2 files changed, 21 insertions(+) diff --git a/src/analyses/call_graph.cpp b/src/analyses/call_graph.cpp index 683ed7905dc..5d581bdeb57 100644 --- a/src/analyses/call_graph.cpp +++ b/src/analyses/call_graph.cpp @@ -107,6 +107,26 @@ call_grapht call_grapht::get_inverted() const return result; } +std::listcall_grapht::shortest_function_path +(irep_idt src, irep_idt dest) +{ + std::list result; + node_indext src_idx, dest_idx; + if(!get_node_index(src, src_idx)) + throw "unable to find src function in call graph"; + if(!get_node_index(dest, dest_idx)) + throw "unable to find destination function in call graph"; + + patht path; + shortest_path(src_idx, dest_idx, path); + for(const auto &n : path) + { + result.push_back(nodes[n].function_name); + } + return result; +} + + std::unordered_set call_grapht::reachable_functions(irep_idt start_function) { diff --git a/src/analyses/call_graph.h b/src/analyses/call_graph.h index b8a4d61d58b..d31091a7c8b 100644 --- a/src/analyses/call_graph.h +++ b/src/analyses/call_graph.h @@ -46,6 +46,7 @@ class call_grapht: public grapht call_grapht get_inverted() const; std::unordered_set reachable_functions(irep_idt start); + std::listshortest_function_path(irep_idt src, irep_idt dest); bool get_node_index(const irep_idt& function_name, node_indext &n) const { From 635071ea3777a9a55ecb59e66703428e5ef02780 Mon Sep 17 00:00:00 2001 From: polgreen Date: Mon, 23 Oct 2017 19:54:30 +0200 Subject: [PATCH 6/7] Documentation of call graph and reachable call graph --- src/analyses/call_graph.h | 26 ++++++++++++++++++++++++-- src/analyses/reachable_call_graph.cpp | 5 ----- src/analyses/reachable_call_graph.h | 14 +++++++------- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/analyses/call_graph.h b/src/analyses/call_graph.h index d31091a7c8b..28fcd147173 100644 --- a/src/analyses/call_graph.h +++ b/src/analyses/call_graph.h @@ -23,9 +23,11 @@ Author: Daniel Kroening, kroening@kroening.com #include -/// Function call graph inherits from grapht to allow forward and +/// \brief Function call graph: each node represents a function +/// in the GOTO model, a directed edge from A to B indicates +/// that function A calls function B. +/// Inherits from grapht to allow forward and /// backward traversal of the function call graph - struct call_graph_nodet: public graph_nodet { typedef graph_nodet::edget edget; @@ -43,11 +45,28 @@ class call_grapht: public grapht void add(const irep_idt &caller, const irep_idt &callee); void output_xml(std::ostream &out) const; + + /// \return the inverted call graph call_grapht get_inverted() const; + + /// \brief get the names of all functions reachable from a start function + /// \param start name of initial function + /// \return set of all names of the reachable functions std::unordered_set reachable_functions(irep_idt start); + + /// \brief Function returns the shortest path on the function call graph + /// between a source and a destination function + /// \param src name of the starting function + /// \param dest name of the destination function + /// \return list of function names on the shortest path between src and dest std::listshortest_function_path(irep_idt src, irep_idt dest); + /// get the index of the node that corresponds to a function name + /// \param[in] function_name function_name passed by reference + /// \param[out] n variable for the node index to be written to + /// \return true if a node with the given function name exists, + /// false if it does not exist bool get_node_index(const irep_idt& function_name, node_indext &n) const { for(node_indext idx = 0; idx < nodes.size(); idx++) @@ -61,6 +80,9 @@ class call_grapht: public grapht return false; } + /// \brief get a list of functions called by a function + /// \param function_name the irep_idt of the function + /// \return an unordered set of all functions called by function_name std::unordered_set get_successors( const irep_idt& function_name) const { diff --git a/src/analyses/reachable_call_graph.cpp b/src/analyses/reachable_call_graph.cpp index 50674fde86c..2ed17371dd9 100644 --- a/src/analyses/reachable_call_graph.cpp +++ b/src/analyses/reachable_call_graph.cpp @@ -8,13 +8,9 @@ Module: Reachable Call Graphs /// \file /// Reachable Call Graph -/// Constructs a call graph only from the functions reachable from a given -/// entry point, or the goto_functions.entry_point if none is given. - #include "reachable_call_graph.h" #include - reachable_call_grapht::reachable_call_grapht (const goto_modelt & _goto_model) { @@ -71,7 +67,6 @@ void reachable_call_grapht::build( } } - std::unordered_set reachable_call_grapht::backward_slice(irep_idt destination_function) { diff --git a/src/analyses/reachable_call_graph.h b/src/analyses/reachable_call_graph.h index 2de7b84eb0d..4dcfd5cfd0c 100644 --- a/src/analyses/reachable_call_graph.h +++ b/src/analyses/reachable_call_graph.h @@ -8,6 +8,8 @@ Module: Reachable Call Graphs /// \file /// Reachable Call Graphs +/// Constructs a call graph only from the functions reachable from a given +/// entry point, or the goto_functions.entry_point if none is given. #ifndef CPROVER_ANALYSES_REACHABLE_CALL_GRAPH_H #define CPROVER_ANALYSES_REACHABLE_CALL_GRAPH_H @@ -19,13 +21,11 @@ class reachable_call_grapht: public call_grapht public: explicit reachable_call_grapht(const goto_modelt &); - /// \brief Generates list of functions reachable from initial state and - /// that may reach a given destination function - /// - /// This is done by inverting the reachable call graph and performing bfs on - /// the inverted call graph. - /// \param destination function - /// \return unorderded set of function names as irep_idts + /// \brief performs a backwards slice on a reachable call graph + /// and returns an unordered set of all functions between the initial + /// function and the destination function, i.e., a cone of influence + /// \param destination_function name of destination function + /// \return unordered set of function names std::unordered_set backward_slice(irep_idt destination_function); protected: From 6f7d4b4586688b2536bbf07e77559744b8623a68 Mon Sep 17 00:00:00 2001 From: polgreen Date: Tue, 24 Oct 2017 13:22:44 +0200 Subject: [PATCH 7/7] white space call graph --- src/analyses/call_graph.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/analyses/call_graph.cpp b/src/analyses/call_graph.cpp index 5d581bdeb57..dec7f9205c8 100644 --- a/src/analyses/call_graph.cpp +++ b/src/analyses/call_graph.cpp @@ -107,8 +107,8 @@ call_grapht call_grapht::get_inverted() const return result; } -std::listcall_grapht::shortest_function_path -(irep_idt src, irep_idt dest) +std::list call_grapht::shortest_function_path( + irep_idt src, irep_idt dest) { std::list result; node_indext src_idx, dest_idx;