Баг в компиляторе MSVC++ 2015?
От: Рома Мик Россия http://romamik.com
Дата: 19.01.17 21:39
Оценка:
Есть такой язык haxe, он умеет компилироваться в c++, при этом тянет за собой свой рантайм. К нему есть библиотека Kha, которая этот рантайм местами заменяет.
Есть минимальный пример на языке haxe, который при компиляции в с++, и дальнейшей компиляцией в MSVC++ 2015 вызывает падение программы. Только в Release, и только если включена оптимизация /O2 или /Ox.
Строчка на которой крашится выглядит так:
 ::String _hx_tmp2 = ((_hx_tmp1 + HX_("test",52,c8,f9,4c).substr((int)1,null())) + HX_("_",5f,00,00,00));

String — это часть библиотеки haxe, имеет два поля char * __s и int length. Я добавил вывод отладочной информации в substr() и operator+:
Kore::log(Kore::LogLevel::Info, "%i %i", result.length, result.__s );// substr

Kore::log(Kore::LogLevel::Info, "%i %i %i", inRHS.length, inRHS.__s, *((int*)(&inRHS.__s)+1)); // operator +

и получил вывод:
3 50990268 - substr
20315128 3 50990268 - operator+

Т.е. operator+ получил неправильный указатель, указывающий на 4 байта раньше чем надо. Дебагер значений этих переменных не показывает, т.к. оптимизации включены.

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

Подобная, но другая, ошибка есть еще в одном месте кода, но там не удалось собрать минимальный пример, проявляется только в большом проекте, там баг пропадает даже с включенной /O2 если выключить /WL (whole program optimisation). Там тоже функции передается в качестве аргумента результат выполнения другой функции, эта функция перед возвращением имеет нормальный результат, а получатель получает null.

Вопрос, что с этим делать, и как дальше жить?
Можно ли это куда-то засабмитить? С учетом того, что я не могу это воспроизвести на голом c++, т.е. мой пример — это не минимальный пример на c++.
Может быть проблема не в компиляторе, а в каком-то UB, непонятно как прокравшемся в C++ код?
Отредактировано 19.01.2017 21:40 Рома Мик . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.