]> granicus.if.org Git - re2c/commitdiff
src/dfa/dfa.h: simplify constructor to avoid g++-3.4 bug 220/head
authorSergei Trofimovich <slyfox@gentoo.org>
Sat, 29 Sep 2018 21:11:27 +0000 (22:11 +0100)
committerSergei Trofimovich <slyfox@gentoo.org>
Sat, 29 Sep 2018 21:26:19 +0000 (22:26 +0100)
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 <slyfox@gentoo.org>
re2c/src/dfa/dfa.h

index a52536dcb74dd5338a8af8bfb102b29f28d79487..49f8de94d0bc797e87e8bc6418ff9afd9a8dd37e 100644 (file)
@@ -5,6 +5,7 @@
 #include <valarray>
 #include <vector>
 #include <set>
+#include <string.h>
 
 #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;