From: Sergei Trofimovich Date: Sat, 29 Sep 2018 21:11:27 +0000 (+0100) Subject: src/dfa/dfa.h: simplify constructor to avoid g++-3.4 bug X-Git-Tag: 1.2~334^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9efad4a55092f34bfefcf869720eb591db7d1fe7;p=re2c src/dfa/dfa.h: simplify constructor to avoid g++-3.4 bug On g++-3.4.6 re2c tests SIGSEGVed due to use of uninitialized data: ``` $ valgrind ... ./re2c -8 a.re -o foo.c Conditional jump or move depends on uninitialised value(s) at 0x432F23: re2c::tcpool_t::insert(re2c::tcmd_t const*) (tcmd.cc:202) by 0x421FDA: re2c::freeze_tags(re2c::dfa_t&) (freeze.cc:45) by 0x43A7FF: re2c::ast_to_dfa(re2c::spec_t const&, re2c::Output&) (compile.cc:88) by 0x43B052: push_back (stl_iterator.h:614) by 0x43B052: re2c::compile(re2c::Scanner&, re2c::Output&, re2c::Opt&) (???:0) by 0x449D29: main (main.cc:31) Uninitialised value was created by a heap allocation at 0x403252F: operator new[](unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) by 0x42FC9E: re2c::find_state(re2c::determ_context_t&) (dfa.h:37) by 0x429BD9: re2c::dfa_t::dfa_t(re2c::nfa_t const&, re2c::opt_t const*, std::string const&, re2c::Warn&) (determinization.cc:56) by 0x43A76C: re2c::ast_to_dfa(re2c::spec_t const&, re2c::Output&) (compile.cc:69) by 0x43B052: push_back (stl_iterator.h:614) by 0x43B052: re2c::compile(re2c::Scanner&, re2c::Output&, re2c::Opt&) (???:0) by 0x449D29: main (main.cc:31) ``` the problem here arose in default array constructor: ```c++ explicit dfa_state_t(size_t nchars) : // ... , tcmd(new tcmd_t*[nchars + 2]()) // +2 for final and fallback epsilon-transitions // ... ``` g++-3.4.6 can't figure out zero-initialization rule (likely a gcc bug). The change uses non-initializing new[] and memset() instead. Signed-off-by: Sergei Trofimovich --- diff --git a/re2c/src/dfa/dfa.h b/re2c/src/dfa/dfa.h index a52536dc..49f8de94 100644 --- a/re2c/src/dfa/dfa.h +++ b/re2c/src/dfa/dfa.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "src/conf/warn.h" #include "src/dfa/tcmd.h" @@ -29,12 +30,16 @@ struct dfa_state_t explicit dfa_state_t(size_t nchars) : arcs(new size_t[nchars]) - , tcmd(new tcmd_t*[nchars + 2]()) // +2 for final and fallback epsilon-transitions + , tcmd(NULL) , tcid(NULL) , rule(Rule::NONE) , fallthru(false) , fallback(false) - {} + { + size_t sz = nchars + 2; // +2 for final and fallback epsilon-transitions + tcmd = new tcmd_t*[sz]; + memset(tcmd, 0, sizeof (tcmd_t*) * sz); + } ~dfa_state_t() { delete[] arcs;