// Coerce a literal expression to given tuple or non-tuple types static bool coerce_literal_to_type(ast_t** astp, ast_t* target_type, lit_chain_t* chain, pass_opt_t* options, bool report_errors) { assert(astp != NULL); ast_t* literal_expr = *astp; assert(literal_expr != NULL); ast_t* lit_type = ast_type(literal_expr); if(lit_type == NULL || (ast_id(lit_type) != TK_LITERAL && ast_id(lit_type) != TK_OPERATORLITERAL)) { // Not a literal return true; } if(ast_child(lit_type) != NULL) { // Control block literal return coerce_control_block(astp, target_type, chain, options, report_errors); } switch(ast_id(literal_expr)) { case TK_TUPLE: // Tuple literal { size_t cardinality = ast_childcount(literal_expr); if(!coerce_group(astp, target_type, chain, cardinality, options, report_errors)) return false; break; } case TK_INT: return uif_type_from_chain(options, literal_expr, target_type, chain, false, report_errors); case TK_FLOAT: return uif_type_from_chain(options, literal_expr, target_type, chain, true, report_errors); case TK_ARRAY: if(!coerce_group(astp, target_type, chain, CHAIN_CARD_ARRAY, options, report_errors)) return false; break; case TK_SEQ: { // Only coerce the last expression in the sequence ast_t* last = ast_childlast(literal_expr); if(!coerce_literal_to_type(&last, target_type, chain, options, report_errors)) return false; ast_settype(literal_expr, ast_type(last)); return true; } case TK_CALL: { AST_GET_CHILDREN(literal_expr, positional, named, receiver); ast_t* arg = ast_child(positional); if(!coerce_literal_to_type(&receiver, target_type, chain, options, report_errors)) return false; if(arg != NULL && !coerce_literal_to_type(&arg, target_type, chain, options, report_errors)) return false; ast_settype(literal_expr, ast_type(ast_child(receiver))); return true; } case TK_DOT: { ast_t* receiver = ast_child(literal_expr); if(!coerce_literal_to_type(&receiver, target_type, chain, options, report_errors)) return false; break; } default: ast_error(literal_expr, "Internal error, coerce_literal_to_type node %s", ast_get_print(literal_expr)); assert(0); return false; } // Need to reprocess node now all the literals have types ast_settype(literal_expr, NULL); return (pass_expr(astp, options) == AST_OK); }
// // Start Test Case #9 - (derivation) // // static int mutatorTest(BPatch_thread *, BPatch_image *appImage) test_results_t test5_9_Mutator::executeTest() { bool found = false; BPatch_Vector<BPatch_function *> bpfv; const char *fn = "derivation_test::func_cpp"; if (NULL == appImage->findFunction(fn, bpfv) || !bpfv.size() || NULL == bpfv[0]){ logerror("**Failed** test #9 (derivation)\n"); logerror(" Unable to find function %s\n", fn); return FAILED; } BPatch_function *f1 = bpfv[0]; BPatch_Vector<BPatch_point *> *point9_1 = f1->findPoint(BPatch_exit); if (!point9_1 || (point9_1->size() < 1)) { logerror("Unable to find point derivation_test::func_cpp - exit.\n"); return FAILED; } bpfv.clear(); const char *fn2 = "main"; if (NULL == appImage->findFunction(fn2, bpfv) || !bpfv.size() || NULL == bpfv[0]){ logerror("**Failed** test #9 (derivation)\n"); logerror(" Unable to find function %s\n", fn2); return FAILED; } BPatch_function *f2 = bpfv[0]; BPatch_Vector<BPatch_point *> *point9_2 = f2->findPoint(BPatch_allLocations); if (!point9_2 || (point9_2->size() < 1)) { logerror("Unable to find point in main.\n"); return FAILED; } BPatch_variableExpr *expr9_0=appImage->findVariable(*(*point9_2)[0], "test5_9_test9"); if (!expr9_0) { logerror("**Failed** test #9 (derivation)\n"); logerror(" Unable to locate one of variables\n"); return FAILED; } BPatch_Vector<BPatch_variableExpr *> *fields = expr9_0->getComponents(); if (!fields || fields->size() == 0 ) { logerror("**Failed** test #9 (derivation)\n"); logerror(" struct lacked correct number of elements\n"); return FAILED; } int index = 0; while ( index < fields->size() ) { if ( !strcmp("call_cpp", (*fields)[index]->getName()) || !strcmp("cpp_test_util::call_cpp", (*fields)[index]->getName())) { found = true; break; } index ++; } if ( !found ) { logerror("**Failed** test #9 (derivation)\n"); logerror(" Can't find inherited class member functions\n"); logerror(" Expected call_cpp or cpp_test_util::call_cpp\n"); index = 0; while ( index < fields->size() ) { logerror(" Field %d: %s\n", index, (*fields)[index]->getName()); ++index; } return FAILED; } // TODO pass a success message to the mutatee const char *passfn = "test5_9_passed"; BPatch_Vector<BPatch_function *> passfv; if ((NULL == appImage->findFunction(passfn, passfv)) || (passfv.size() < 1) || (NULL == passfv[0])) { logerror("**Failed** test #9 (derivation)\n"); logerror(" Can't find function %s\n", passfn); return FAILED; } BPatch_function *pass_func = passfv[0]; BPatch_Vector<BPatch_snippet *> pass_args; BPatch_funcCallExpr pass_expr(*pass_func, pass_args); appAddrSpace->insertSnippet(pass_expr, *point9_1); return PASSED; }