Bug#498708: g++-4.3: internal compiler error with fipa-* optimization options
Package: g++-4.3
Version: 4.3.1-9
Severity: important
I tried to compile the following code with the following options and got the errors mentioned in place:
-fipa-struct-reorg <-- fast.cc:289: internal compiler error: Segmentation fault
-fipa-pta <-- /usr/include/c++/4.3/bits/vector.tcc: In member
function 'void std::vector<_Tp,
_Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename
std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer,
std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = int, _Alloc =
std::allocator<int>]':
/usr/include/c++/4.3/bits/vector.tcc:283: internal compiler error: in
initialize_flags_in_bb, at tree-into-ssa.c:437
The commandline was (with FOO being one of the above flags)
g++ \
-O3 -march=native \
-FOO
-fwhole-program -combine \
-funsafe-loop-optimizations -Wunsafe-loop-optimizations \
-ftree-loop-linear \
fast.cc
The source code is:
++
// License: GPLv3
// -> contact author for use not covered by GPLv3
//
// (C) 2008 Sebastian Mach
// seb@greenhybrid.net
// http://greenhybrid.net , http://picogen.org
//-----------------------------------------------------------------------------
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
//-----------------------------------------------------------------------------
// convenience functions
//-----------------------------------------------------------------------------
// can also be used to check whether c is in ['0'..'9'] ("bool isNum = toInt(c) != -1;")
template <typename C> int toInt (C c) {
// note that the C++ standard does not mandate
// that the number-chars 0-9 are continous when
// interpeted as integers, thus this function
// does the portable way.
// --> trust in constant folding
// --> check if '0'-'9' are continous when cast to integer
if ('1'-'0' == 1
&& '2'-'0' == 2
&& '3'-'0' == 3
&& '4'-'0' == 4
&& '5'-'0' == 5
&& '6'-'0' == 6
&& '7'-'0' == 7
&& '8'-'0' == 8
&& '9'-'0' == 9
) {
static int ret [2] = {-1, -1};
ret [1] = c - '0';
return ret [c>('0'-1) & c<('9'+1)];
} else {
switch (c) { // not much slower if the compiler emits jump tables
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
};
return -1;
}
}
// compiler should do a good job with it
template <typename A, typename B> class tuple {
const A a_;
const B b_;
public:
tuple (A a, B b) : a_(a), b_(b) {}
const A& a () const { return a_; }
const B& b () const { return b_; }
operator A () const { return a_; }
operator B () const { return b_; }
};
//-----------------------------------------------------------------------------
// some enums to be used as typesafe template args
//-----------------------------------------------------------------------------
enum order_t {
order_in_main_section,
order_in_ref_section
};
enum safemode_t {
safe,
unsafe
};
//-----------------------------------------------------------------------------
// some enums to be used as typesafe template args
//-----------------------------------------------------------------------------
template <typename C, C L, C R, order_t T=order_in_main_section, safemode_t S=safe> class Reorder {
private:
// that function assumes we're already inside the pair of
// brackets (i.e. after '[')
template <class I> tuple <bool, int> scanRefTarget (I &curr, I end) {
using namespace std;
I old_curr = curr;
int len = 0; // used to check validity of reference
int refID = 0; // the reference-id
while (R != *curr) { // <-- until we hit an end-bracket
if (S == safe) {
if (end == curr) { // <-- rudimentary error checking
cerr << "found end of file but expected numbers or '" << R << endl;
throw;
}
}
const int d = toInt (*curr);
if (-1 != d) {
refID = refID * 10 + d;
++len;
}
++curr;
}
if (0 != len) {
return tuple <bool, int> (true, refID);
}
curr = old_curr; // <-- was not a reference, so rollback
return tuple <bool, int> (false, -1);
}
template <typename I> struct Chunk { // intentionally POD
I begin, end;
int ref_target;
Chunk <I> *next;
};
template <typename I> struct Reference { // intentionally POD
I begin, end;
int order;
};
template <class I> Chunk<I> *scanText (I &curr, I end) {
Chunk<I> *chunk = new Chunk<I>;
Chunk<I> * const first_chunk = chunk;
chunk->begin = curr;
chunk->next = 0;
chunk->ref_target = -1;
while (true) {
if (L == *curr) { // <-- we've hit a start-bracket
++curr; // <-- eat start-bracket
const I old_curr = curr;
const tuple <bool, int> refID = scanRefTarget (curr, end);
if (refID) {
//cout << "hit a ref:" << static_cast <int> (refID) << endl;
chunk->ref_target = refID;
chunk->end = old_curr-1;
chunk->next = new Chunk<I>;
chunk = chunk->next;
chunk->next = 0;
chunk->ref_target = -1;
chunk->begin = curr+1;
}
} else if (end == curr) {
chunk->end = curr;
break;
} else if ('\n' == *curr) {
I old_curr = curr;
if ('@' == *++curr
&& 'f' == *++curr
&& 'o' == *++curr
&& 'o' == *++curr
&& 't' == *++curr
&& 'n' == *++curr
&& 'o' == *++curr
&& 't' == *++curr
&& 'e' == *++curr
&& ':' == *++curr
) {
chunk->end = old_curr;
// eat forward to newline
while (curr != end && *curr != '\n')
++curr;
++curr; // eatup newline
break;
} else {
curr = old_curr;
}
}
++curr;
};
return first_chunk;
}
template <typename I> void scanReferences (std::map <int, Reference <I> > &refs, std::vector<int> &orderedRRefs, I &curr, I end) {
using namespace std;
int footnodeID = 0;
while (true) {
while (L != *curr && '\n' != *curr && end != curr)
++curr;
if (L == *curr) {
++curr; // <-- eat start-bracket
const I old_curr = curr;
const tuple <bool, int> refID = scanRefTarget (curr, end);
++curr;
if (refID) {
Reference<I> ref;
while (' ' == *curr || '\n' == *curr) // <-- eat whitespace
++curr;
ref.begin = curr;
while (*curr != '\n' && curr != end)
++curr;
ref.end = curr;
ref.order = footnodeID++;
orderedRRefs.push_back (refID);
refs [refID] = ref;
}
} else if (end == curr) {
break;
}
++curr;
}
}
public:
template <class I> Reorder (I begin, I end) {
using namespace std;
I curr = begin;
Chunk<I> *chunk = scanText<I> (curr, end);
map <int, Reference <I> > refs;
std::vector<int> orderedRRefs;
scanReferences <I> (refs, orderedRRefs, curr, end);
// dump text
for (const Chunk<I> *it = chunk; 0 != it; it = it->next) {
for (I a=it->begin; a != it->end; ++a) {
cout << *a;
}
if (-1 != it->ref_target) {
cout << "[" << refs [it->ref_target].order << "]";
}
}
cout << '\n';
// dump footnotes
cout << "@footnote:\n";
for (vector<int>::iterator it=orderedRRefs.begin(); it!=orderedRRefs.end(); ++it) {
cout << "[" << refs [*it].order << "] ";
for (I c=refs [*it].begin; c!=refs [*it].end; ++c) {
cout << *c;
}
cout << "\n";
}
while (0 != chunk) {
Chunk <I> *tmp = chunk;
chunk = chunk->next;
delete tmp;
}
}
};
//-----------------------------------------------------------------------------
// main
//-----------------------------------------------------------------------------
int main (int argc, char *argv []) {
using namespace std;
/*string text =
"[66]abc [33] def [99] ghi [33]lalal\n"
"@footnote:\n"
"[66] the lazy dogs\n"
"[33] the C++ compendium\n"
"[99] hmm, a footnote\n"
;*/
char *begin, *end;
{
ifstream f ("testfile");
f.seekg (0, ios::end);
int len = f.tellg();
f.seekg (0, ios::beg);
begin = new char [len];
end = begin + len;
f.read (begin, len);
f.close();
}
Reorder <char, '[', ']', order_in_main_section, unsafe> (begin, end);
return 0;
}
--
-- System Information:
Debian Release: lenny/sid
APT prefers testing
APT policy: (500, 'testing'), (500, 'stable')
Architecture: i386 (i686)
Kernel: Linux 2.6.22-3-k7 (SMP w/1 CPU core)
Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
Versions of packages g++-4.3 depends on:
ii gcc-4.3 4.3.1-9 The GNU C compiler
ii gcc-4.3-base 4.3.1-9 The GNU Compiler Collection (base
ii libc6 2.7-13 GNU C Library: Shared libraries
ii libgmp3c2 2:4.2.2+dfsg-3 Multiprecision arithmetic library
ii libmpfr1ldbl 2.3.1.dfsg.1-2 multiple precision floating-point
ii libstdc++6-4.3-dev 4.3.1-9 The GNU Standard C++ Library v3 (d
g++-4.3 recommends no packages.
Versions of packages g++-4.3 suggests:
ii g++-4.3-multilib 4.3.1-9 The GNU C++ compiler (multilib fil
pn gcc-4.3-doc <none> (no description available)
pn libstdc++6-4.3-dbg <none> (no description available)
-- no debconf information
Reply to: