Любой способ генерировать предупреждения для сравнения указателя функции?

У меня ушло навсегда, чтобы отследить, что в моем коде была ошибка, вызванная /OPT:ICF:

Так как / OPT: ICF может заставить один и тот же адрес назначаться различным функциям или элементам данных только для чтения. (константные переменные, скомпилированные с помощью / Gy), он может сломать программу, которая зависит от уникальных адресов для функций или членов данных только для чтения.

(Я хранил и сравнивал указатели функций на равенство, которые ломаются, когда компоновщик выбрасывает идентичные функции.)

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

Тестовый пример, конечно, тривиален:

//MSVC: /Gy /link /OPT:ICF
int test1(void) { return 0; }
int test2(void) { return 0; }
int main(void) { return test1 == test2; }

я пробовал -Wall, -Wextra, -Weverything, -pedanticи т. д., но ни один из них не генерирует предупреждения.

Есть любой Опция или инструмент компилятора (будь то часть Visual C ++, GCC, Clang или другое), которые могут анализировать мой код и сообщать мне, где я сравниваю указатели функций друг с другом, как в коде выше?

30

Решение

Есть ли какая-либо опция или инструмент компилятора (будь то часть Visual C ++, GCC, Clang или другая), которая может анализировать мой код и сообщать мне, где я сравниваю указатели функций друг с другом, как в коде выше?

Я не уверен, существует ли такая опция компилятора.

Тем не менее, есть такой инструмент. лязг-аккуратно. Вы можете написать свои собственные проверки для Clang-Tidy, это на самом деле удивительно легко, если вы будете следовать этот блог. В частности, AST уже поставляется с кучей сопоставителей, которые должны обрабатывать нужный вам вариант использования.

Нечто подобное похоже на работу:

binaryOperator(
anyOf(hasOperatorName("=="), hasOperatorName("!=")),
hasLHS(ignoringImpCasts(declRefExpr(hasType(functionType())))),
hasRHS(ignoringImpCasts(declRefExpr(hasType(functionType())))))

Который помечает пример в OP:

fp.cxx:3:25: note: "root" binds here
int main(void) { return test1 == test2; }
^~~~~~~~~~~~~~

Это работает специально для случая OP, но на самом деле вы должны быть более явным, чтобы соответствовать всем другим вероятным случаям:

const auto AnyFunc = ignoringImpCasts(declRefExpr(hasType(anyOf(
functionType(),
pointsTo(functionType()),
references(functionType())))));

Finder->AddMatcher(binaryOperator(
anyOf(hasOperatorName("=="), hasOperatorName("!=")),
hasLHS(AnyFunc),
hasRHS(AnyFunc)).bind("op"), this);

Или что-то близкое к этому.

8

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector