@@ -121,6 +121,21 @@ tryConvertRuleJson(const std::string &ruleId, const std::string &toolName,
121
121
}
122
122
}
123
123
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
+
124
139
optional<Result> tryConvertResultJson (const ResultJson &resultJson,
125
140
const std::string &toolName,
126
141
const std::string &id) {
@@ -166,6 +181,7 @@ optional<Result> tryConvertResultJson(const ResultJson &resultJson,
166
181
if (locations.empty ()) {
167
182
return nonstd::nullopt;
168
183
}
184
+ tryConvertMessage (toolName, resultJson.message , locations.back ());
169
185
170
186
return Result{std::move (locations), std::move (metadatas), id,
171
187
std::move (errors)};
@@ -325,27 +341,87 @@ bool Location::isInside(const std::string &name) const {
325
341
: (m == -1 && isOSSeparator (filename[n])));
326
342
}
327
343
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) {
331
359
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;
345
376
}
377
+ }
378
+ }
346
379
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
+ }
348
423
}
424
+ bp.setNotFound ();
349
425
}
350
426
351
427
std::string Location::toString () const {
0 commit comments