Coverity - явное нулевое разыменование - PullRequest
0 голосов
/ 30 апреля 2018

У меня есть такой сценарий:

int main() {
  int *p;
  int *q;
  bool cond1, cond2;

  // Does some processing and sets the cond1 and cond2

  if (cond1) {
     p = // Assign valid address
     q = NULL;
  } else {
     p = NULL;
     q = // Assign valid address
  }

  // Does something else but cond1 and cond2 remains untouched  

  if (cond2) {
    ***// Using 'q' data members.***
  }
}

В моем коде только два условия: cond1 и cond2. Во-первых, если выполняется для cond1, а в противном случае выполняется для cond2. Только один из них может быть истинным одновременно. Я вижу дефект покрытия жирным шрифтом / курсивом. Coverity жалуется ниже сообщения:

CID 25469 (#1 of 1): Explicit null dereferenced (FORWARD_NULL)
9. var_deref_op: Dereferencing null pointer q.

Я не понимаю, почему здесь жалуется покровительство. В этом сценарии к тому времени, когда я захожу в «cond2», у меня уже есть «q» Правильно? Что я не понял?

Решения, которые я предлагаю:

.. Было бы хорошо, если я напишу! Cond1 просто так:

if (!cond1) {
  // Using 'q' data members.
}

.. Будет ли хорошо, если я добавлю дополнительные проверки:

if (cond2 && q != NULL) {
  // Using 'q' data members.
}

.. Это ложное срабатывание?

Что-нибудь еще? Заранее спасибо.

1 Ответ

0 голосов
/ 30 апреля 2018

Логически, исходя из того, что вы сказали, и предполагая, что code1 и code2 являются взаимоисключающими, это ложный положительный результат. Однако предупреждение имеет значение, поскольку оно указывает [sic] , что безопасность q не является очевидной из логики вашей функции.

Я бы, по крайней мере, поместил бы assert(q) внутри if (code2), но:

  1. утверждения обычно применяются только во время отладки (как мне недавно напомнили, сбой среды выполнения в сборке выпуска, который не имел смысла - в конце концов, у меня везде есть безопасность утверждений, верно?)
  2. этого все еще может быть недостаточно для удовлетворения Coverity.

В идеале вы должны придерживаться этого if / else и поместить всю свою логику туда. Общая логика для выполнения в середине? Разделите его на другую функцию, которую вы можете вызвать.

Дополнительным преимуществом этого является то, что вам, вероятно, больше не требуются и p, и q, и поэтому вся функция становится намного более скудной.

Если code1 и code2 оба могут быть истинными, тогда у вас есть существенная ошибка здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...