Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
[C++] WTF поведение clang в отношении функций с [[pure]] (aka __attribute__((pure))) и исключениями 05.07.20 16:20 Число просмотров: 3041
Автор: leo <Леонид Юрьев> Статус: Elderman Отредактировано 05.07.20 16:52 Количество правок: 1
|
Еще больше года назад заметил в одном из проектов странное поведение throw() при сборке clang-ом.
- то ловится и обрабатывается как в gcc и msvc;
- то тупо std::terminate();
- то 50/50 в разных ситуациях;
Для прода в то время использовались только gcc и msvc.
Кроме этого, под OSX код отрабатывал нормально.
Поэтому тогда списал на баги clang-а и пошел дальше.
На днях вернулся и потратил день на глубокое копание в причинах.
Дошел до трассировки поиска по DWARF-таблицам и исследования содержимого этих таблиц.
Собственно убедился что обработка в libstdc++ работает верное, а clang тупо не всегда генерирует необходимые данных.
После еще пару часов пытался выяснить почему.
Оказалось что причина в_attribute_(pure)).
Нельзя сказать что clang совсем не прав, ибо pure-функции не должны менять состояние программы, а выброс исключений как-бы его меняет.
Но делает он это совершенно пакостным образом:
1._attribute_(pure)) имеет приоритет над всеми другими правилами и декларациями, включая явный noexcept(false).
2. никакие предупреждения не генерируются, даже с -Wall и -Wextra, даже если для функции явно специфицировано noexcept(false), и даже в режиме C++17 (где noexcept(true/false) является частью типа).
3. никакие санитайзеры (была надежда на UBSAN) ничего не видят.
4. в самом clang атрибут pure не документирован, хотя виден через __has_attribute(pure) и обрабатывается как фронтендом. так и бекэндом.
В оригинале (в gcc) реализовано полностью адекватное/ожидаемое поведение:
-_attribute_(pure)) не отменяет noexcept(false).
- оптимизатор выполняет common subexpression elimination (т.е. где возможно оставляет один вызов функции вместо нескольких), но при этом предусматривает обработку исключений.
Как оказалось проблема достаточно известная, даже баг такой заведен (https://bugs.llvm.org/show_bug.cgi?id=43275) и знаючи найти элементарно.
Почему не проявляется на OSX - не знаю (не копал), но скорее всего у яблочников это либо заглушено (__has_attribute(pure) => false), либо поставлена собственная подпорка.
Такая вот канитель.
|
- [C++] WTF поведение clang в отношении функций с [[... - leo 05.07.20 16:20 [3041]
|
|
|