Подтвердить что ты не робот

Как предотвратить возврат указателя на временную переменную?

В недавней поисковой ошибке я обнаружил проблему с возвратом указателя на член временной переменной. Оскорбительный (упрощенный) код:

struct S {
    S(int i) : i(i) {}
    int i;
    int* ptr() { return &i; }
};

int* fun(int i) { return S(i).ptr(); }  // temporary S dies but pointer lives on

int main() {
    int* p = fun(1);
    return *p;  // undefined
}

Как это предотвратить? GCC и Clang имеют -Waddress-of-temporary и -Wreturn-stack-address, но они, похоже, теряют след из-за того, что ptr() выступает как средний человек за грязные дела. Они запускаются только тогда, когда указатель берется непосредственно:

int* fun(int i) { return &S(i).i; }  // rightly fails to compile

Мой проект также включает cppcheck в непрерывной интеграции, но он также не может его поднять (поднял здесь).

Какой инструмент статического анализа может предотвратить этот класс ошибок?

EDIT: GCC делает это с версии 6.1.0 с -Wreturn-local-addr и (неожиданно) -O2 включен.

4b9b3361

Ответ 1

Я разработчик Cppcheck.

Мой проект также включает cppcheck в непрерывной интеграции, но он также не может его поднять.

интересная ошибка. Это ошибка, о которой cppcheck хочет предупредить. У нас есть некоторые связанные проверки, но это, к сожалению, проскользнуло.

Не удивительно, учитывая регулярный характер cppcheck.

Я лично не понимаю, почему некоторые люди говорят, что cppcheck является инструментом регулярных выражений.

Он использует AST, контекстный анализ потока значений и т.д. для обнаружения ошибок. Так и GCC и Clang. Иногда Cppcheck считается инструментом регулярных выражений, но GCC и Clang не являются.