4040#include " klee/Config/Version.h"
4141#include " klee/Config/config.h"
4242#include " klee/Core/Interpreter.h"
43+ #include " klee/Core/TerminationTypes.h"
4344#include " klee/Expr/ArrayExprOptimizer.h"
4445#include " klee/Expr/ArrayExprVisitor.h"
4546#include " klee/Expr/Assignment.h"
@@ -519,9 +520,9 @@ Executor::Executor(LLVMContext &ctx, const InterpreterOptions &opts,
519520 InterpreterHandler *ih)
520521 : Interpreter(opts), interpreterHandler(ih), searcher(nullptr ),
521522 externalDispatcher(new ExternalDispatcher(ctx)), statsTracker(0 ),
522- pathWriter(0 ), symPathWriter(0 ),
523- specialFunctionHandler( 0 ), timers{time::Span (TimerInterval)},
524- guidanceKind (opts.Guidance), codeGraphInfo(new CodeGraphInfo()),
523+ pathWriter(0 ), symPathWriter(0 ), specialFunctionHandler( 0 ),
524+ timers{time::Span (TimerInterval)}, guidanceKind(opts.Guidance) ,
525+ codeGraphInfo(new CodeGraphInfo()),
525526 distanceCalculator(new DistanceCalculator(*codeGraphInfo)),
526527 targetCalculator(new TargetCalculator(*codeGraphInfo)),
527528 targetManager(new TargetManager(guidanceKind, *distanceCalculator,
@@ -2728,6 +2729,7 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
27282729 if (bi->getMetadata (" md.ret" )) {
27292730 state.stack .forceReturnLocation (locationOf (state));
27302731 }
2732+ state.lastBrConfidently = true ;
27312733
27322734 transferToBasicBlock (bi->getSuccessor (0 ), bi->getParent (), state);
27332735 } else {
@@ -2747,6 +2749,11 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
27472749 maxNewStateStackSize =
27482750 std::max (maxNewStateStackSize,
27492751 branches.first ->stack .stackRegisterSize () * 8 );
2752+ branches.first ->lastBrConfidently = false ;
2753+ branches.second ->lastBrConfidently = false ;
2754+ } else {
2755+ (branches.first ? branches.first : branches.second )->lastBrConfidently =
2756+ true ;
27502757 }
27512758
27522759 // NOTE: There is a hidden dependency here, markBranchVisited
@@ -4018,9 +4025,11 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
40184025 if (iIdx >= vt->getNumElements ()) {
40194026 // Out of bounds write
40204027 terminateStateOnProgramError (
4021- state, new ErrorEvent (locationOf (state),
4022- StateTerminationType::BadVectorAccess,
4023- " Out of bounds write when inserting element" ));
4028+ state,
4029+ new ErrorEvent (locationOf (state),
4030+ StateTerminationType::BadVectorAccess,
4031+ " Out of bounds write when inserting element" ),
4032+ StateTerminationConfidenceCategory::CONFIDENT);
40244033 return ;
40254034 }
40264035
@@ -4061,9 +4070,11 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
40614070 if (iIdx >= vt->getNumElements ()) {
40624071 // Out of bounds read
40634072 terminateStateOnProgramError (
4064- state, new ErrorEvent (locationOf (state),
4065- StateTerminationType::BadVectorAccess,
4066- " Out of bounds read when extracting element" ));
4073+ state,
4074+ new ErrorEvent (locationOf (state),
4075+ StateTerminationType::BadVectorAccess,
4076+ " Out of bounds read when extracting element" ),
4077+ StateTerminationConfidenceCategory::CONFIDENT);
40674078 return ;
40684079 }
40694080
@@ -4967,28 +4978,41 @@ void Executor::terminateStateOnTargetError(ExecutionState &state,
49674978 terminationType = StateTerminationType::User;
49684979 }
49694980 terminateStateOnProgramError (
4970- state, new ErrorEvent (locationOf (state), terminationType, messaget));
4981+ state, new ErrorEvent (locationOf (state), terminationType, messaget),
4982+ StateTerminationConfidenceCategory::CONFIDENT);
49714983}
49724984
4973- void Executor::terminateStateOnError (ExecutionState &state,
4974- const llvm::Twine &messaget,
4975- StateTerminationType terminationType,
4976- const llvm::Twine &info,
4977- const char *suffix) {
4985+ void Executor::terminateStateOnError (
4986+ ExecutionState &state, const llvm::Twine &messaget,
4987+ StateTerminationType terminationType,
4988+ StateTerminationConfidenceCategory confidence, const llvm::Twine &info,
4989+ const char *suffix) {
49784990 std::string message = messaget.str ();
4979- static std::set<std::pair<Instruction *, std::string>> emittedErrors;
4991+ static std::set<
4992+ std::pair<Instruction *,
4993+ std::pair<StateTerminationConfidenceCategory, std::string>>>
4994+ emittedErrors;
49804995 const KInstruction *ki = getLastNonKleeInternalInstruction (state);
49814996 Instruction *lastInst = ki->inst ();
49824997
4983- if ((EmitAllErrors ||
4984- emittedErrors.insert (std::make_pair (lastInst, message)).second ) &&
4998+ if ((EmitAllErrors || emittedErrors
4999+ .insert (std::make_pair (
5000+ lastInst, std::make_pair (confidence, message)))
5001+ .second ) &&
49855002 shouldWriteTest (state, true )) {
49865003 std::string filepath = ki->getSourceFilepath ();
5004+
5005+ std::string prefix =
5006+ (confidence == StateTerminationConfidenceCategory::CONFIDENT
5007+ ? " ERROR"
5008+ : " POSSIBLE ERROR" );
5009+
49875010 if (!filepath.empty ()) {
4988- klee_message (" ERROR : %s:%zu: %s" , filepath .c_str (), ki-> getLine (),
4989- message.c_str ());
5011+ klee_message ((prefix + " : %s:%zu: %s" ) .c_str (), filepath. c_str (),
5012+ ki-> getLine (), message.c_str ());
49905013 } else {
4991- klee_message (" ERROR: (location information missing) %s" , message.c_str ());
5014+ klee_message ((prefix + " : (location information missing) %s" ).c_str (),
5015+ message.c_str ());
49925016 }
49935017 if (!EmitAllErrors)
49945018 klee_message (" NOTE: now ignoring this error at this location" );
@@ -5034,13 +5058,14 @@ void Executor::terminateStateOnExecError(ExecutionState &state,
50345058 assert (reason > StateTerminationType::USERERR &&
50355059 reason <= StateTerminationType::EXECERR);
50365060 ++stats::terminationExecutionError;
5037- terminateStateOnError (state, message, reason, " " );
5061+ terminateStateOnError (state, message, reason,
5062+ StateTerminationConfidenceCategory::CONFIDENT, " " );
50385063}
50395064
5040- void Executor::terminateStateOnProgramError (ExecutionState &state,
5041- const ref<ErrorEvent> &reason,
5042- const llvm::Twine &info,
5043- const char *suffix) {
5065+ void Executor::terminateStateOnProgramError (
5066+ ExecutionState &state, const ref<ErrorEvent> &reason,
5067+ StateTerminationConfidenceCategory confidence, const llvm::Twine &info,
5068+ const char *suffix) {
50445069 assert (reason->ruleID > StateTerminationType::SOLVERERR &&
50455070 reason->ruleID <= StateTerminationType::PROGERR);
50465071 ++stats::terminationProgramError;
@@ -5059,19 +5084,22 @@ void Executor::terminateStateOnProgramError(ExecutionState &state,
50595084 }
50605085 state.eventsRecorder .record (reason);
50615086
5062- terminateStateOnError (state, reason->message , reason->ruleID , info, suffix);
5087+ terminateStateOnError (state, reason->message , reason->ruleID , confidence,
5088+ info, suffix);
50635089}
50645090
50655091void Executor::terminateStateOnSolverError (ExecutionState &state,
50665092 const llvm::Twine &message) {
50675093 ++stats::terminationSolverError;
5068- terminateStateOnError (state, message, StateTerminationType::Solver, " " );
5094+ terminateStateOnError (state, message, StateTerminationType::Solver,
5095+ StateTerminationConfidenceCategory::CONFIDENT, " " );
50695096}
50705097
50715098void Executor::terminateStateOnUserError (ExecutionState &state,
50725099 const llvm::Twine &message) {
50735100 ++stats::terminationUserError;
5074- terminateStateOnError (state, message, StateTerminationType::User, " " );
5101+ terminateStateOnError (state, message, StateTerminationType::User,
5102+ StateTerminationConfidenceCategory::CONFIDENT, " " );
50755103}
50765104
50775105// XXX shoot me
@@ -5442,13 +5470,20 @@ void Executor::executeFree(ExecutionState &state, ref<Expr> address,
54425470 new ErrorEvent (new AllocEvent (mo->allocSite ),
54435471 locationOf (*it->second ), StateTerminationType::Free,
54445472 " free of alloca" ),
5473+ rl.size () != 1 ? StateTerminationConfidenceCategory::PROBABLY
5474+ : StateTerminationConfidenceCategory::CONFIDENT,
54455475 getAddressInfo (*it->second , address));
54465476 } else if (mo->isGlobal ) {
5477+ if (rl.size () != 1 ) {
5478+ klee_warning (" Following error if likely false positive" );
5479+ }
54475480 terminateStateOnProgramError (
54485481 *it->second ,
54495482 new ErrorEvent (new AllocEvent (mo->allocSite ),
54505483 locationOf (*it->second ), StateTerminationType::Free,
54515484 " free of global" ),
5485+ rl.size () != 1 ? StateTerminationConfidenceCategory::PROBABLY
5486+ : StateTerminationConfidenceCategory::CONFIDENT,
54525487 getAddressInfo (*it->second , address));
54535488 } else {
54545489 it->second ->removePointerResolutions (mo);
@@ -5544,6 +5579,8 @@ bool Executor::resolveExact(ExecutionState &estate, ref<Expr> address,
55445579 *unbound,
55455580 new ErrorEvent (locationOf (*unbound), StateTerminationType::Ptr,
55465581 " memory error: invalid pointer: " + name),
5582+ !results.empty () ? StateTerminationConfidenceCategory::PROBABLY
5583+ : StateTerminationConfidenceCategory::CONFIDENT,
55475584 getAddressInfo (*unbound, address));
55485585 }
55495586 }
@@ -5633,7 +5670,7 @@ void Executor::concretizeSize(ExecutionState &state, ref<Expr> size,
56335670 new ErrorEvent (locationOf (*hugeSize.second ),
56345671 StateTerminationType::Model,
56355672 " concretized symbolic size" ),
5636- info.str ());
5673+ StateTerminationConfidenceCategory::CONFIDENT, info.str ());
56375674 }
56385675 }
56395676 }
@@ -6359,7 +6396,8 @@ void Executor::executeMemoryOperation(
63596396 *state,
63606397 new ErrorEvent (new AllocEvent (mo->allocSite ), locationOf (*state),
63616398 StateTerminationType::ReadOnly,
6362- " memory error: object read only" ));
6399+ " memory error: object read only" ),
6400+ StateTerminationConfidenceCategory::CONFIDENT);
63636401 } else {
63646402 wos->write (mo->getOffsetExpr (address), value);
63656403 }
@@ -6431,6 +6469,10 @@ void Executor::executeMemoryOperation(
64316469 return ;
64326470 }
64336471
6472+ bool mayBeFalsePositive =
6473+ resolvedMemoryObjects.size () > 1 ||
6474+ (resolvedMemoryObjects.size () == 1 && mayBeOutOfBound);
6475+
64346476 ExecutionState *unbound = nullptr ;
64356477 if (MergedPointerDereference) {
64366478 ref<Expr> guard;
@@ -6488,7 +6530,10 @@ void Executor::executeMemoryOperation(
64886530 new ErrorEvent (new AllocEvent (mo->allocSite ),
64896531 locationOf (*branches.first ),
64906532 StateTerminationType::ReadOnly,
6491- " memory error: object read only" ));
6533+ " memory error: object read only" ),
6534+ mayBeFalsePositive
6535+ ? StateTerminationConfidenceCategory::PROBABLY
6536+ : StateTerminationConfidenceCategory::CONFIDENT);
64926537 state = branches.second ;
64936538 } else {
64946539 ref<Expr> result = SelectExpr::create (
@@ -6560,7 +6605,10 @@ void Executor::executeMemoryOperation(
65606605 *bound,
65616606 new ErrorEvent (new AllocEvent (mo->allocSite ), locationOf (*bound),
65626607 StateTerminationType::ReadOnly,
6563- " memory error: object read only" ));
6608+ " memory error: object read only" ),
6609+ mayBeFalsePositive
6610+ ? StateTerminationConfidenceCategory::PROBABLY
6611+ : StateTerminationConfidenceCategory::CONFIDENT);
65646612 } else {
65656613 wos->write (mo->getOffsetExpr (address), value);
65666614 }
@@ -6622,6 +6670,8 @@ void Executor::executeMemoryOperation(
66226670 new ErrorEvent (new AllocEvent (baseObjectPair.first ->allocSite ),
66236671 locationOf (*unbound), StateTerminationType::Ptr,
66246672 " memory error: out of bound pointer" ),
6673+ mayBeFalsePositive ? StateTerminationConfidenceCategory::PROBABLY
6674+ : StateTerminationConfidenceCategory::CONFIDENT,
66256675 getAddressInfo (*unbound, address));
66266676 return ;
66276677 }
@@ -6631,6 +6681,8 @@ void Executor::executeMemoryOperation(
66316681 *unbound,
66326682 new ErrorEvent (locationOf (*unbound), StateTerminationType::Ptr,
66336683 " memory error: out of bound pointer" ),
6684+ mayBeFalsePositive ? StateTerminationConfidenceCategory::PROBABLY
6685+ : StateTerminationConfidenceCategory::CONFIDENT,
66346686 getAddressInfo (*unbound, address));
66356687 }
66366688}
@@ -6864,8 +6916,7 @@ void Executor::executeMakeSymbolic(ExecutionState &state,
68646916 (!AllowSeedTruncation && obj->numBytes > mo->size ))) {
68656917 std::stringstream msg;
68666918 msg << " replace size mismatch: " << mo->name << " [" << mo->size
6867- << " ]"
6868- << " vs " << obj->name << " [" << obj->numBytes << " ]"
6919+ << " ]" << " vs " << obj->name << " [" << obj->numBytes << " ]"
68696920 << " in test\n " ;
68706921
68716922 terminateStateOnUserError (state, msg.str ());
@@ -7309,8 +7360,7 @@ void Executor::logState(const ExecutionState &state, int id,
73097360 *f << " Address memory object: " << object.first ->address << " \n " ;
73107361 *f << " Memory object size: " << object.first ->size << " \n " ;
73117362 }
7312- *f << state.symbolics .size () << " symbolics total. "
7313- << " Symbolics:\n " ;
7363+ *f << state.symbolics .size () << " symbolics total. " << " Symbolics:\n " ;
73147364 size_t sc = 0 ;
73157365 for (const auto &symbolic : state.symbolics ) {
73167366 *f << " Symbolic number " << sc++ << " \n " ;
0 commit comments