Rename newtestsuite to testsuite
[dyninst.git] / testsuite / src / dyninst / test1_38.C
1 /*
2  * Copyright (c) 1996-2004 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  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: test1_38.C,v 1.1 2008/10/30 19:19:26 legendre Exp $
43 /*
44  * #Name: test1_38
45  * #Desc: CFG Loop Callee Tree
46  * #Dep: 
47  * #Arch:
48  * #Notes:
49  */
50
51 #include "BPatch.h"
52 #include "BPatch_Vector.h"
53
54 #include "test_lib.h"
55 #include "dyninst_comp.h"
56
57 class test1_38_Mutator : public DyninstMutator {
58         virtual test_results_t executeTest();
59 };
60
61 extern "C" DLLEXPORT TestMutator *test1_38_factory() 
62 {
63         return new test1_38_Mutator();
64 }
65
66 //
67 // Start Test Case #38 - (CFG loop/callee tree)
68 //
69
70 test_results_t test1_38_Mutator::executeTest() 
71 {
72         if (isMutateeFortran(appImage)) 
73         {
74                 return SKIPPED;
75         } 
76
77         BPatch_image *dummy = appThread->getImage();
78         assert (appThread->getImage());
79
80         const char *funcName = "test1_38_call1";
81         BPatch_Vector<BPatch_function *> funcs0;
82         appImage->findFunction(funcName, funcs0);
83
84         if (!funcs0.size()) 
85         {
86                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
87                 logerror("    cannot find function %s.\n", funcName);
88                 return FAILED;
89         }
90
91         BPatch_function *func = funcs0[0];
92
93         BPatch_flowGraph *cfg = func->getCFG();
94
95         // check that funcs are inserted in the proper places in the loop hierarchy
96         BPatch_loopTreeNode *root = cfg->getLoopTree();
97
98         if (!root->children.size()) 
99         {
100                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
101                 logerror("    no kids.\n");
102                 return FAILED;
103         }
104
105         BPatch_loopTreeNode *firstForLoop  = root->children[0];
106
107         // determine which node is the while loop and which is the second
108         // for loop, this is platform dependent
109
110         if (firstForLoop->children.size() < 2) 
111         {
112                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
113                 logerror("    not enough kids.\n");
114                 return FAILED;
115         }
116
117         BPatch_loopTreeNode *secondForLoop = firstForLoop->children[0];
118         BPatch_loopTreeNode *whileLoop     = firstForLoop->children[1];
119
120         // swap if got wrong
121         if (firstForLoop->children[0]->children.size() == 0) 
122         {
123                 secondForLoop = firstForLoop->children[1];
124                 whileLoop     = firstForLoop->children[0];
125         }
126
127         // root loop has 1 child, the outer for loop
128         if (1 != root->children.size()) 
129         {
130                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
131                 logerror("    root loop should have 1 child, found %d.\n",
132                                 root->children.size());
133                 return FAILED;
134         }
135
136         if (2 != root->numCallees()) 
137         {
138                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
139                 logerror("    root loop should have 2 functions, found %d.\n",
140                                 root->numCallees());
141                 return FAILED;
142         }
143         // call38_1 and call38_7 should be off the root
144         const char * f38_1 = root->getCalleeName(0);
145         const char * f38_7 = root->getCalleeName(1);
146
147         if (0 != strcmp("funCall38_1",f38_1)) 
148         {
149                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
150                 logerror("    expected funCall38_1 not %s.\n",f38_1);
151                 return FAILED;
152         }
153
154         if (0 != strcmp("funCall38_7",f38_7)) 
155         {
156                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
157                 logerror("    expected funCall38_7 not %s.\n",f38_7);
158                 return FAILED;
159         }
160
161         // the first for loop should have 3 children and 2 functions
162         if (3 != firstForLoop->numCallees()) 
163         {
164                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
165                 logerror("    first for loop found %d funcs not 3.\n", 
166                                 firstForLoop->numCallees());
167                 return FAILED;
168         }
169
170         if (2 != firstForLoop->children.size()) 
171         {
172                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
173                 logerror("    first for loop had %d children, not 2.\n",
174                                 firstForLoop->children.size());
175                 return FAILED;
176         }
177
178         // call38_2, call38_4 and call38_6 should be under the outer loop
179         const char * f38_2 = firstForLoop->getCalleeName(0);
180         const char * f38_4 = firstForLoop->getCalleeName(1);
181         const char * f38_6 = firstForLoop->getCalleeName(2);
182
183         if (0 != strcmp("funCall38_2",f38_2)) 
184         {
185                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
186                 logerror("    expected funCall38_2 not %s.\n",f38_2);
187                 return FAILED;
188         }
189
190         if (0 != strcmp("funCall38_4",f38_4)) 
191         {
192                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
193                 logerror("    expected funCall38_4 not %s.\n",f38_4);
194                 return FAILED;
195         }
196
197         if (0 != strcmp("funCall38_6",f38_6)) 
198         {
199                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
200                 logerror("    expected funCall38_6 not %s.\n",f38_6);
201                 return FAILED;
202         }
203
204         // the second for loop should have one child and no nested functions
205         if (1 != secondForLoop->children.size()) 
206         {
207                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
208                 logerror("    second for loop had %d children, not 1.\n",
209                                 secondForLoop->children.size());
210                 return FAILED;
211         }
212
213         if (0 != secondForLoop->numCallees()) 
214         {
215                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
216                 logerror("    second for loop had %d funcs (%s), should be 0.\n",
217                                 secondForLoop->numCallees(),
218                                 secondForLoop->getCalleeName(0));
219                 return FAILED;
220         }
221
222         BPatch_loopTreeNode *thirdForLoop  = secondForLoop->children[0];
223
224         // third for loop has no children and one function funCall38_3
225         if (0 != thirdForLoop->children.size()) 
226         {
227                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
228                 logerror("    third for loop had %d children, not 0.\n",
229                                 thirdForLoop->children.size());
230                 return FAILED;
231         }
232
233         if (1 != thirdForLoop->numCallees()) 
234         {
235                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
236                 logerror("    third for loop had %d funcs, not 1.\n",
237                                 thirdForLoop->numCallees());
238                 return FAILED;
239         }
240
241         const char * f38_3 = thirdForLoop->getCalleeName(0);
242
243         if (0 != strcmp("funCall38_3",f38_3)) 
244         {
245                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
246                 logerror("    expected funCall38_3 not %s.\n",f38_3);
247                 return FAILED;
248         }
249
250         // the while loop has no children and one function (funCall38_5)
251         if (0 != whileLoop->children.size()) 
252         {
253                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
254                 logerror("    while loop had %d children, not 0.\n",
255                                 whileLoop->children.size());
256                 return FAILED;
257         }
258
259         if (1 != whileLoop->numCallees()) 
260         {
261                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
262                 logerror("    while loop had %d functions, not 1.\n",
263                                 whileLoop->numCallees());
264                 return FAILED;
265         }
266
267         const char * f38_5 = whileLoop->getCalleeName(0);
268
269         if (0 != strcmp("funCall38_5",f38_5)) 
270         {
271                 logerror("**Failed** test #38 (CFG loop/callee tree)\n");
272                 logerror("    expected funCall38_5 not %s.\n",f38_5);
273                 return FAILED;
274         }
275
276         BPatch_variableExpr *passedExpr = 
277                 appImage->findVariable("test1_38_globalVariable2");
278
279         if (passedExpr == NULL) 
280         {
281                 logerror("**Failed** test1_38 (CFG loop/callee tree)\n");
282                 logerror("    Unable to locate test1_38_globalVariable2\n");
283                 return FAILED;
284         } 
285
286         int pvalue = 1;
287         passedExpr->writeValue(&pvalue);
288
289         return PASSED;
290 }
291