Запутанный анализ потока управления из теста Parasoft C ++ - PullRequest
8 голосов
/ 27 апреля 2011

Мы используем Parasoft C ++ test для статического анализа нашего кода.У него проблемы с кодом, подобным следующему:

void foo(int* x) {
    try {
        bar();
    } catch(...) {
        delete x;
        throw;
    }

    *x;
}

В строке *x; он предупреждает, что:

Освобожденная память не должна быть доступна ни при каких обстоятельствах

Каким-то образом сделан вывод, что поток управления может перейти в блок catch(...), удалить x, пройти за throw; и перейти к *x;.Я попробовал throw std::exception(""); и пару других и получил то же самое.Parasoft наверняка знает об исключениях и включает их в свой поток управления, потому что есть много других тестов, которые включают проверку исключений.Это просто запутано в этом случае, или на самом деле есть какой-то способ для выполнения этой программы, чтобы ударить как delete x;, так и *x;?

Ответы [ 3 ]

2 голосов
/ 02 мая 2011

Так что инструмент не тот (об этом я уже говорил, я знаю), и я предполагаю, что вы не хотите скрывать предупреждение.

Я согласен с комментарием @ Pascal, что несколько опасно переписывать кодпросто чтобы обойти ограничения некоторых инструментов.Что вы можете сделать, это отключить эту защиту только для файлов, где у вас есть эта проблема.

Затем у вас есть начальная сборка без предупреждения, без инструмента, предлагающего перезаписать существующий допустимый код.

Для нового кода вам придется принять некоторыестиль, который понимает инструмент.Это не проблема, потому что это будет код, над которым вы сейчас работаете, поэтому будет меньше проблем, если вам придется немного переписать его, чтобы избавиться от предупреждений.

Несмотря на правильность, существующий стиль далек от идеала.

Я бы рекомендовал хранить указатели типа x в auto_ptr.Это автоматически удалит содержимое auto_ptr, если оно выходит из области видимости - если вы явно не удалите его из auto_ptr.Это намного проще для глаз, а также хорошо документирует, что эта функция становится владельцем указателя.

void foo(auto_ptr<int> x)
{
    bar();
    *x;
}

Я ожидаю, что у ParaSoft не будет проблем с этим кодом.

0 голосов
/ 04 июня 2013

Быстрое обновление:

1) Вышеупомянутое правило вообще не является правилом анализа потока.При этом правило (ID MRM-31) было улучшено в тесте C ++ 9.2.0 и более поздних версиях.Для этого в тесте C ++ существует соответствующее правило анализа потока (ID: BD-RES-FREE), которое должно выполнять то, что вы хотите.

0 голосов
/ 27 апреля 2011

Возможно, это глупое предложение, но что скажет Parasoft, если вы оставите улов на конец?Т.е.

void foo(int* x) 
  {
  try 
    {
    bar();
    *x;
    } 
  catch(...) 
    {
    delete x;
    throw;
    }      
  }

Я понимаю, что это может не сработать для всех комбинаций операторов и исключений, например, если у вас есть несколько типов исключений для разной обработки на разных этапах foo, но, по крайней мере, это может дать вамначало обходного пути, если вы действительно хотите избавиться от предупреждения.

...