Update copyright to LGPL on all files
[dyninst.git] / testsuite / src / dyninst / test1_38.C
1 /*
2  * Copyright (c) 1996-2009 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 // $Id: test1_38.C,v 1.1 2008/10/30 19:19:26 legendre Exp $
33 /*
34  * #Name: test1_38
35  * #Desc: CFG Loop Callee Tree
36  * #Dep: 
37  * #Arch:
38  * #Notes:
39  */
40
41 #include "BPatch.h"
42 #include "BPatch_Vector.h"
43
44 #include "test_lib.h"
45 #include "dyninst_comp.h"
46
47 class test1_38_Mutator : public DyninstMutator {
48         virtual test_results_t executeTest();
49 };
50
51 extern "C" DLLEXPORT TestMutator *test1_38_factory() 
52 {
53         return new test1_38_Mutator();
54 }
55
56 //
57 // Start Test Case #38 - (CFG loop/callee tree)
58 //
59
60 test_results_t test1_38_Mutator::executeTest() 
61 {
62         if (isMutateeFortran(appImage)) 
63         {
64                 return SKIPPED;
65         } 
66
67         assert (appImage);
68
69         const char *funcName = "test1_38_call1";
70         BPatch_Vector<BPatch_function *> funcs0;
71         appImage->findFunction(funcName, funcs0);
72
73         if (!funcs0.size()) 
74         {
75                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
76                 logerror("    cannot find function %s.\n", funcName);
77                 return FAILED;
78         }
79
80         BPatch_function *func = funcs0[0];
81
82         BPatch_flowGraph *cfg = func->getCFG();
83
84         // check that funcs are inserted in the proper places in the loop hierarchy
85         BPatch_loopTreeNode *root = cfg->getLoopTree();
86
87         if (!root->children.size()) 
88         {
89                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
90                 logerror("    no kids.\n");
91                 return FAILED;
92         }
93
94         BPatch_loopTreeNode *firstForLoop  = root->children[0];
95
96         // determine which node is the while loop and which is the second
97         // for loop, this is platform dependent
98
99         if (firstForLoop->children.size() < 2) 
100         {
101                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
102                 logerror("    not enough kids.\n");
103                 return FAILED;
104         }
105
106         BPatch_loopTreeNode *secondForLoop = firstForLoop->children[0];
107         BPatch_loopTreeNode *whileLoop     = firstForLoop->children[1];
108
109         // swap if got wrong
110         if (firstForLoop->children[0]->children.size() == 0) 
111         {
112                 secondForLoop = firstForLoop->children[1];
113                 whileLoop     = firstForLoop->children[0];
114         }
115
116         // root loop has 1 child, the outer for loop
117         if (1 != root->children.size()) 
118         {
119                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
120                 logerror("    root loop should have 1 child, found %d.\n",
121                                 root->children.size());
122                 return FAILED;
123         }
124
125         if (2 != root->numCallees()) 
126         {
127                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
128                 logerror("    root loop should have 2 functions, found %d.\n",
129                                 root->numCallees());
130                 return FAILED;
131         }
132         // call38_1 and call38_7 should be off the root
133         const char * f38_1 = root->getCalleeName(0);
134         const char * f38_7 = root->getCalleeName(1);
135
136         if (0 != strcmp("funCall38_1",f38_1)) 
137         {
138                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
139                 logerror("    expected funCall38_1 not %s.\n",f38_1);
140                 return FAILED;
141         }
142
143         if (0 != strcmp("funCall38_7",f38_7)) 
144         {
145                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
146                 logerror("    expected funCall38_7 not %s.\n",f38_7);
147                 return FAILED;
148         }
149
150         // the first for loop should have 3 children and 2 functions
151         if (3 != firstForLoop->numCallees()) 
152         {
153                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
154                 logerror("    first for loop found %d funcs not 3.\n", 
155                                 firstForLoop->numCallees());
156                 return FAILED;
157         }
158
159         if (2 != firstForLoop->children.size()) 
160         {
161                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
162                 logerror("    first for loop had %d children, not 2.\n",
163                                 firstForLoop->children.size());
164                 return FAILED;
165         }
166
167         // call38_2, call38_4 and call38_6 should be under the outer loop
168         const char * f38_2 = firstForLoop->getCalleeName(0);
169         const char * f38_4 = firstForLoop->getCalleeName(1);
170         const char * f38_6 = firstForLoop->getCalleeName(2);
171
172         if (0 != strcmp("funCall38_2",f38_2)) 
173         {
174                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
175                 logerror("    expected funCall38_2 not %s.\n",f38_2);
176                 return FAILED;
177         }
178
179         if (0 != strcmp("funCall38_4",f38_4)) 
180         {
181                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
182                 logerror("    expected funCall38_4 not %s.\n",f38_4);
183                 return FAILED;
184         }
185
186         if (0 != strcmp("funCall38_6",f38_6)) 
187         {
188                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
189                 logerror("    expected funCall38_6 not %s.\n",f38_6);
190                 return FAILED;
191         }
192
193         // the second for loop should have one child and no nested functions
194         if (1 != secondForLoop->children.size()) 
195         {
196                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
197                 logerror("    second for loop had %d children, not 1.\n",
198                                 secondForLoop->children.size());
199                 return FAILED;
200         }
201
202         if (0 != secondForLoop->numCallees()) 
203         {
204                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
205                 logerror("    second for loop had %d funcs (%s), should be 0.\n",
206                                 secondForLoop->numCallees(),
207                                 secondForLoop->getCalleeName(0));
208                 return FAILED;
209         }
210
211         BPatch_loopTreeNode *thirdForLoop  = secondForLoop->children[0];
212
213         // third for loop has no children and one function funCall38_3
214         if (0 != thirdForLoop->children.size()) 
215         {
216                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
217                 logerror("    third for loop had %d children, not 0.\n",
218                                 thirdForLoop->children.size());
219                 return FAILED;
220         }
221
222         if (1 != thirdForLoop->numCallees()) 
223         {
224                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
225                 logerror("    third for loop had %d funcs, not 1.\n",
226                                 thirdForLoop->numCallees());
227                 return FAILED;
228         }
229
230         const char * f38_3 = thirdForLoop->getCalleeName(0);
231
232         if (0 != strcmp("funCall38_3",f38_3)) 
233         {
234                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
235                 logerror("    expected funCall38_3 not %s.\n",f38_3);
236                 return FAILED;
237         }
238
239         // the while loop has no children and one function (funCall38_5)
240         if (0 != whileLoop->children.size()) 
241         {
242                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
243                 logerror("    while loop had %d children, not 0.\n",
244                                 whileLoop->children.size());
245                 return FAILED;
246         }
247
248         if (1 != whileLoop->numCallees()) 
249         {
250                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
251                 logerror("    while loop had %d functions, not 1.\n",
252                                 whileLoop->numCallees());
253                 return FAILED;
254         }
255
256         const char * f38_5 = whileLoop->getCalleeName(0);
257
258         if (0 != strcmp("funCall38_5",f38_5)) 
259         {
260                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
261                 logerror("    expected funCall38_5 not %s.\n",f38_5);
262                 return FAILED;
263         }
264
265         BPatch_variableExpr *passedExpr = 
266                 appImage->findVariable("test1_38_globalVariable2");
267
268         if (passedExpr == NULL) 
269         {
270                 logerror("**Failed** test1_38 (CFG loop/callee tree)\n");
271                 logerror("    Unable to locate test1_38_globalVariable2\n");
272                 return FAILED;
273         } 
274
275         int pvalue = 1;
276         passedExpr->writeValue(&pvalue);
277
278         return PASSED;
279 }
280