@@ -121,6 +121,21 @@ tryConvertRuleJson(const std::string &ruleId, const std::string &toolName,
121121 }
122122}
123123
124+ void
125+ tryConvertMessage (const std::string &toolName, const optional<Message> &errorMessage, ref<Location> &loc) {
126+ if (toolName != " Cooddy" || !errorMessage.has_value ())
127+ return ;
128+ std::string start = " Dereferencing of \" " ;
129+ std::string end = " \" which can be null" ;
130+ auto &text = errorMessage->text ;
131+ if (text.substr (0 , start.size ()) == start &&
132+ text.substr (text.size () - end.size (), end.size ()) == end) {
133+ auto size = text.size () - end.size () - start.size ();
134+ auto derefedExpr = text.substr (start.size (), size);
135+ loc = new CoodyNPELocation (*loc);
136+ }
137+ }
138+
124139optional<Result> tryConvertResultJson (const ResultJson &resultJson,
125140 const std::string &toolName,
126141 const std::string &id) {
@@ -166,6 +181,7 @@ optional<Result> tryConvertResultJson(const ResultJson &resultJson,
166181 if (locations.empty ()) {
167182 return nonstd::nullopt ;
168183 }
184+ tryConvertMessage (toolName, resultJson.message , locations.back ());
169185
170186 return Result{std::move (locations), std::move (metadatas), id,
171187 std::move (errors)};
@@ -325,27 +341,87 @@ bool Location::isInside(const std::string &name) const {
325341 : (m == -1 && isOSSeparator (filename[n])));
326342}
327343
328- bool Location::isInside (KBlock *block, const Instructions &origInsts) const {
329- auto first = block->getFirstInstruction ()->info ;
330- auto last = block->getLastInstruction ()->info ;
344+ void Location::isInside (InstrWithPrecision &kp, const Instructions &origInsts) const {
345+ auto ki = kp.ptr ;
346+ auto inst = ki->info ;
347+ if (!isa<DbgInfoIntrinsic>(ki->inst ) && startLine <= inst->line && inst->line <= endLine) {
348+ auto opCode = ki->inst ->getOpcode ();
349+ if (*startColumn <= inst->column && inst->column <= *endColumn &&
350+ origInsts.at (inst->line ).at (inst->column ).count (opCode) != 0 )
351+ kp.precision = Precision::ColumnLevel;
352+ else
353+ kp.precision = Precision::LineLevel;
354+ return ;
355+ }
356+ }
357+
358+ void Location::isInside (BlockWithPrecision &bp, const Instructions &origInsts) {
331359 if (!startColumn.has_value ()) {
332- if (first->line > endLine)
333- return false ;
334- return startLine <= last->line ; // and `first <= line` from above
335- } else {
336- for (size_t i = 0 ; i < block->numInstructions ; ++i) {
337- auto inst = block->instructions [i]->info ;
338- auto opCode = block->instructions [i]->inst ->getOpcode ();
339- if (!isa<DbgInfoIntrinsic>(block->instructions [i]->inst ) &&
340- inst->line <= endLine && inst->line >= startLine &&
341- inst->column <= *endColumn && inst->column >= *startColumn &&
342- origInsts.at (inst->line ).at (inst->column ).count (opCode) != 0 ) {
343- return true ;
344- }
360+ auto first = bp.ptr ->getFirstInstruction ()->info ;
361+ auto last = bp.ptr ->getLastInstruction ()->info ;
362+ if (first->line <= endLine && startLine <= last->line )
363+ bp.precision = Precision::LineLevel;
364+ else
365+ bp.setNotFound ();
366+ return ;
367+ }
368+ auto tmpBP = bp;
369+ bp.setNotFound ();
370+ for (size_t i = 0 ; i < tmpBP.ptr ->numInstructions ; ++i) {
371+ InstrWithPrecision kp (tmpBP.ptr ->instructions [i]);
372+ isInside (kp, origInsts);
373+ if (kp.precision >= tmpBP.precision ) {
374+ tmpBP.precision = kp.precision ;
375+ bp = tmpBP;
345376 }
377+ }
378+ }
346379
347- return false ;
380+ void CoodyNPELocation::isInside (BlockWithPrecision &bp, const Instructions &origInsts) {
381+ // if (x + y > z && aaa->bbb->ccc->ddd)
382+ // ^^^^^^^^^^^^^^^^^ first, skip all this
383+ // second skip this ^^^^^^^^ (where Cooddy event points)
384+ // finally, get this ^ (real location of `Load` instruction)
385+ auto block = bp.ptr ;
386+ size_t start = 0 ;
387+ auto inside = false ;
388+ auto precision = bp.precision ;
389+ KInstruction *ki = nullptr ;
390+ for (; start < block->numInstructions ; ++start) {
391+ ki = block->instructions [start];
392+ InstrWithPrecision kp (ki);
393+ Location::isInside (kp, origInsts);
394+ if (kp.precision >= precision) { // first: go until Cooddy event
395+ precision = kp.precision ;
396+ if (!inside) // first: reached Cooddy event
397+ inside = true ;
398+ } else if (inside) // second: skip until left Coody event
399+ break ;
400+ }
401+ if (!inside) { // no Cooddy event in this Block
402+ bp.setNotFound ();
403+ return ;
404+ }
405+ if (precision == Precision::LineLevel) {
406+ bp.precision = precision;
407+ return ;
408+ }
409+ // finally: Load instruction
410+ if (ki->inst ->getOpcode () == Instruction::Load) {
411+ // we got precise instruction, so redefine the location
412+ startLine = (endLine = ki->info ->line );
413+ startColumn = (endColumn = ki->info ->column );
414+ bp.precision = Precision::ColumnLevel;
415+ return ;
416+ }
417+ // most probably Cooddy points to a macro call
418+ for (size_t i = 0 ; i < start; i++) {
419+ if (block->instructions [i]->inst ->getOpcode () == Instruction::Load) {
420+ bp.precision = Precision::LineLevel;
421+ return ;
422+ }
348423 }
424+ bp.setNotFound ();
349425}
350426
351427std::string Location::toString () const {
0 commit comments