Это ошибка в libstdc++ из cfe-dev
ветка списка рассылки с заголовком -fsanitize=неопределенные и общие библиотеки говорит:
Это ошибка в libstdС++. Вы сможете обойти это с помощью файла черного списка дезинфицирующих средств, как только Уилл выпустит патч для этого, но на данный момент ручная фильтрация, вероятно, будет вашим лучшим вариантом.
Вот патч, чтобы это исправить; В ближайшие несколько дней я постараюсь добавить это в апстрим libstdc++. [...]
Как я отметил dyp в комментариях, нередко можно увидеть системы, в которых clang
использует libstdc++
, а не libc++
, и если мы проверим это на Coliru явно использует libstdc++ через -stdlib=libstdc++
, мы действительно можем воспроизвести проблему.
Следующий отчет об ошибке libstdc++
: неверные значения перечисления, вычисленные оператором~ в ios_base.h освещает этот вопрос и говорит:
Перегруженные операторы, определенные для перечислений в ios_base.h, имеют следующую форму:
Enum operator~(Enum e) { return Enum(~static_cast<int>(e)); }
~ создает значения за пределами диапазона значений типа перечисления, поэтому возврат к типу Enum имеет неопределенное значение (см. [expr.static.cast]p10), и на практике он создает значение Enum за пределами диапазона представляемые значения для типа Enum, поэтому поведение не определено.
Для справки [expr.static.cast]p10 говорит:
Значение интегрального типа или типа перечисления может быть явно преобразовано в тип перечисления. Значение не изменяется, если исходное значение находится в пределах диапазона значений перечисления (7.2). В противном случае результирующее значение не указано (и может не находиться в этом диапазоне). Значение типа с плавающей запятой также может быть преобразовано в тип перечисления. Результирующее значение совпадает с преобразованием исходного значения в базовый тип перечисления (4.9), а затем в тип перечисления.
и, как говорит hvd, это формально неопределенное поведение, но Ричард указывает, что на практике это заканчивается неопределенным поведением.
Т.К. указывает, что это поведение было изменено с неопределенного на неопределенное с помощью DR 1766. : значения вне диапазона значений перечисления:
Хотя проблема 1094 поясняет, что значение выражения типа перечисления может не находиться в диапазоне значений перечисления после преобразования в тип перечисления (см. 5.2.9 [expr.static.cast], параграф 10), результат просто неопределенное значение. Это, вероятно, следует усилить, чтобы получить неопределенное поведение, в свете того факта, что неопределенное поведение делает выражение непостоянным. См. также 9.6 [class.bit], параграф 4.
Новая формулировка появляется в проекте стандарта в N4431.
person
Shafik Yaghmour
schedule
08.05.2015
os << std::hex;
, кажется, также воспроизводит проблему. - person dyp   schedule 08.05.2015