Баг в GCC?

bleyman


#include <stdio.h>
#include <stdexcept>

static int parse_datasource(int it)
{
printf("0\n");
// throw std::exception; // will be caught
int result = 0;
if (it == 10)
{
printf("1\n");
++it;
result = parse_datasource(it);
}
else
{
printf("2\n");
throw std::exception; // will not be caught
}
printf("3\n");
return result;
}

int main
{
try
{
parse_datasource(7);
}
catch (std::exception & err)
{
printf("caught!\n");
}
}

gcc 4.6.0, 'g++46 -O2 test.cpp' не ловит эксепшен, типа, "terminate called after throwing an instance of 'std::exception'".
Если раскомментировать первый throw, то всё ок ловится. В gcc3.4.6 и 4.2.2 всё ок. Без -O2 (или с более низким уровнем оптимизации) всё ок. Если закомментировать ++it или рекурсивный вызов в первой ветке — всё ок.
Ща посмотрю повторима ли ошибка на другой машине с 4.6.0, и есть ли она в 4.6.1 (хотя в what's new они ничего похожего не пишут — у них есть более детальные багрепорты?)

Maurog

Баг в GCC!

procenkotanya

Похоже на баг, конечно, но на ванильном 4.6.0 под x86_64-linux не воспроизводится. "Детальные багрепорты" достаются через багзиллу, да.

bleyman

Скомпилил 4.6.1, там тоже всё ок, видимо действительно баг. Алсо, мне было влом делать 3-stage bootstrap, так что может что-то крайне удивительное случилось!
А откуда ты брал "ванильный 4.6.0", с фтп.гну.орг? А то в дебиановских репозиториях например огромное количество микро-релизов. Кстати, можно как-нибудь принудительно поставить какой-нибудь конкретный? Типа, я научился брать последний (4.6.1) из testing, а как найти какой-нибудь ранний 4.6.0.

procenkotanya

> Алсо, мне было влом делать 3-stage bootstrap
FWIW, можно делать ../gcc-src/configure --disable-bootstrap --enable-languages=c,c++
> А откуда ты брал "ванильный 4.6.0", с фтп.гну.орг?
Ну мне было проще из имеющегося под рукой гита зачекаутить нужный коммит.
Про дебиановские пакеты я хз.

bleyman

FWIW, можно делать ../gcc-src/configure --disable-bootstrap --enable-languages=c,c++

Ну так я это и сделал, говорю же. Так что я не уверен, что предыдущий компилятор не повлиял каким-то непредсказуемым образом на новый.
Алсо, как выяснилось скомпилённый мной 4.6.1 на той машине тоже глючит таким же образом, но в другом месте.
Может так быть, что он берёт какие-то неправильные хедеры, от предыдущего gcc например? Типа, там CentOS и стоит gcc 3.4.6, я его не хочу трогать, поэтому говорю ./configure executable-suffix=46 (по памяти, оно на работе, короче в результате новый гцц ставится как gcc46/g++46 плюс prefix=/usr (а не дефолтный /usr/local, because that's how CentOS rolls).
Алсо, там 32битная машинка, ты же наверное на 64битной проверял? Я щаз ставлю свежую убунту в виртуалке, посмотрю как там...
EDIT: в 32битной убунте нет глюка (одного из, по крайней мере). Видимо, мне либо удалось свести с ума компилятор компилируя его старым компилятором, либо он маразматично использует старые хедеры/библиотеки зачем-то как-то.

erotic

Алсо, как выяснилось скомпилённый мной 4.6.1 на той машине тоже глючит таким же образом, но в другом месте.
Напиши плиз, где глючит, я свой проверю. А то я его недавно на продакшне стал использовать.
Собирал тоже на CentOS не трогая основной 4.1.2, но в 3-stage: ./configure --prefix=/usr/local/gcc-4.6.1 --disable-multilib

bleyman

Напиши плиз, где глючит, я свой проверю.
http://pastebin.com/WKDngKBd — просто падает, даже не печатает оригинальный эксепшен.
Короче какая-то полная херня с эксепшенами происходит. Прозреваю, что это я сделал что-то ужасное всё-таки, а гцц ни при чём. Типа, там сервер с довольно старым CentOS, апдейтится не с интернетов а из какого-то локального (и тоже весьма несвежего, гцц там 3.4.6) миррора, а я на него периодически в обход юма ставлю всякое. Вот, видимо, довыёбывался =(

erotic

Наверное. У меня с -O2 и с -O3 ловится исключение в твоем примере.

erotic

Поставил свежеанонсированный 4.6.2 с обещанными исправлениями багов 4.6.1. В итоге код, который компилировался под 4.6.1, теперь выдает такое:
/home//programming/target/include/test/TestData.hpp: В функции-члене «std::vector<T> test::test_data<std::vector<T> >::operator[](ssize_t)»:
/home//programming/target/include/test/TestData.hpp:54:47: внутренняя ошибка компилятора: в build_new_op, в cp/call.c:5016
Отправьте подробное сообщение об ошибке
с препроцессированным исходным кодом.
Смотрите инструкции в <http://gcc.gnu.org/bugs.html>.
:(

procenkotanya

Сочувствую, но не вижу ни тесткейса, ни тем более твоего бага на gcc.gnu.org (hint, hint!)

erotic

Минимально, что у меня не компилится, это вот:

#include <string> // for ssize_t, I don't know where it is really placed
#include <vector>

template <typename T>
struct test_data
{
T operator[] (ssize_t i) { return T(i); }
};

template <typename T>
struct test_data<std::vector<T> >
{
std::vector<T> operator[] (ssize_t i)
{
std::vector<T> res;
const size_t max = (i < 0) ? -i : i;
return res;
}
};

int main
{
return 0;
}

Баг пока не отрепортил, т.к. хочу на 4.7 проверить, а с его сборкой возникли проблемы.

procenkotanya

Опции ещё укажи, с -O* не воспроизводится

erotic

Из опций только -std=c++0x, сорри, забыл.

procenkotanya

Ага, в 4.7 тоже воспроизводится. Там банально забыли в одном switch'e ABS_EXPR обработать, похоже. Минимальный тесткейс:
template<class T> int foo(int a)
{
const unsigned b = a < 0 ? -a : a;
return 0;
}

Я могу сам зарепортить, если не возражаешь.
edit: ABS_EXPR strikes again! Если кто помнит, в 4.2 был совершенно embarrassing баг с мискомпиляцией таких выражений.

erotic

Давай. Ссылку только кинь, смотреть буду.
Оставить комментарий
Имя или ник:
Комментарий: