| 509 | } |
| 510 | |
| 511 | static void |
| 512 | check_refinement(Errors &errs, const Transform &t, State &src_state, |
| 513 | State &tgt_state, const Value *var, const Type &type, |
| 514 | const State::ValTy &ap, const State::ValTy &bp, |
| 515 | bool check_each_var) { |
| 516 | auto fndom_a = ap.domain(); |
| 517 | auto fndom_b = bp.domain(); |
| 518 | auto &retdom_a = ap.return_domain; |
| 519 | auto &retdom_b = bp.return_domain; |
| 520 | auto &a = ap.val; |
| 521 | auto &b = bp.val; |
| 522 | |
| 523 | auto &uvars = ap.undef_vars; |
| 524 | auto qvars = src_state.getQuantVars(); |
| 525 | if (!config::disallow_ub_exploitation) |
| 526 | qvars.insert(ap.undef_vars.begin(), ap.undef_vars.end()); |
| 527 | auto &src_nondet_vars = src_state.getNondetVars(); |
| 528 | qvars.insert(src_nondet_vars.begin(), src_nondet_vars.end()); |
| 529 | auto &fn_qvars = tgt_state.getFnQuantVars(); |
| 530 | qvars.insert(fn_qvars.begin(), fn_qvars.end()); |
| 531 | |
| 532 | expr axioms_expr; |
| 533 | { |
| 534 | AndExpr axioms = src_state.getAxioms(); |
| 535 | axioms.add(tgt_state.getAxioms()); |
| 536 | axioms_expr = std::move(axioms)(); |
| 537 | } |
| 538 | |
| 539 | if (check_expr(axioms_expr && fndom_a, "ub_src").isUnsat()) { |
| 540 | if (config::fail_if_src_is_ub) { |
| 541 | errs.add("Source function is always UB", false); |
| 542 | return; |
| 543 | } else { |
| 544 | errs.addWarning( |
| 545 | "Source function is always UB.\n" |
| 546 | "It can be refined by any target function.\n" |
| 547 | "Please make sure this is what you wanted."); |
| 548 | } |
| 549 | } |
| 550 | |
| 551 | // note that precondition->toSMT() may add stuff to getPre, |
| 552 | // so order here matters |
| 553 | // FIXME: broken handling of transformation precondition |
| 554 | //src_state.startParsingPre(); |
| 555 | //expr pre = t.precondition ? t.precondition->toSMT(src_state) : true; |
| 556 | expr pre, pre_src_forall; |
| 557 | { |
| 558 | expr pre_src, pre_tgt; |
| 559 | { |
| 560 | auto pre_src_and = src_state.getPre(); |
| 561 | auto &pre_tgt_and = tgt_state.getPre(); |
| 562 | |
| 563 | // optimization: rewrite "tgt /\ (src -> foo)" to "tgt /\ foo" if src=tgt |
| 564 | pre_src_and.del(pre_tgt_and); |
| 565 | pre_src = std::move(pre_src_and)(); |
| 566 | pre_tgt = pre_tgt_and(); |
| 567 | } |
| 568 |
no test coverage detected