This is a proposed fix to bug #1826 which removes a race condition where
multiple threads could update ATNState::nextTokenWithinRule, leading to
corrupted std::vector instances in an InstanceSet.
ATN::nextTokens(ATNState* s) updates s->nextTokenWithinRule if the
IntervalSet is empty, and then sets it to be read only. However, if the
updated IntervalSet value was also empty, it becomes a read-only empty
set, causing an exception on a second call on the same state.
This was exposed a change I made to make IntervalSet::operator=()
respect the _readonly flag. (Which in turn was found by compiling with a
high warningly level.)
The approach in this update is to perform the update if the updated
value is not empty or if the current value is not read only. This
preserves the previous behaviour of creating a read-only empty set and
working on subsequent calls. It will throw on an attempt to update a
read-only value, where previously the read-only value would be silently
discarded and set to updatable.
The Travis CI build is failing after an include of <cstddef> -- This is
an attempt to work around that by including <stddef.h> instead. Problem
not apparent in my FreeBSD environment.
These changes are for compiling with high warning levels and -Werror.
There are no functional changes in this commit. Compiled with gcc 5.4
and clang 3.8.
Summary:
- Put virtual destructors into the appropriate .cpp file instead
of the inline version in the header to avoid many vtables.
- Change C-style casts to modern C++ casts.
- Add explicit casts in some signed to/from unsigned conversions.
- Remove unreached code in BufferedTokenStream.cpp and
LexerATNSimulator.cpp.
- Remove shadowed variables by qualifying constructor arguments with
the name name as a member variable.
- Add explicitly defined copy constructors and assignment operators
where required by gcc's -Weff-c++.
- Use std::numeric_limits<size_t>::max() instead of assigning a negative
number.
- Remove semi-colons after function definitions.
- Remove unneccessary casts.
- In preprocessor statements "#if label > value" change to
"#if defined(label) && label > value" to avoid warnings about the
undefined symbol being seen as zero.
- Remove ANTLR4CPP_PUBLIC from "enum class" definitions.
- Change the FinalAction move constructor to move instead of copy the
_cleanUp std::function object. (A side-effect of explicitly
initialising member variables as required by gcc's -Weff-c++. I turned
this one off because most constructors needed to be touched,
especially the classes implemented with InitializeInstanceFields()).
- Mark hex digit conversion functions as file static in guid.cpp.
The listener example still refers to Ref<> and shared pointers, but in
reality the generated method does not pass a shared pointer. The actual
signature looks more like this:
virtual void enterKey(ParserRuleContext * /*ctx*/) override { }
This change updates the example to match that signature, and removes a line
discussing Ref<>. It also adds the "override" keyword in order to make the
user's code a little more robust against typos/changes in the grammar.
as intended.
The existing code intended for ParseTreeWalker::DEFAULT to provide a
IterativeParseTreeWalker. However, the implementation initialized
ParseTreeWalker::DEFAULT by doing a (value) copy of an
IterativeParseTreeWalker, which sliced the object and therefore,
unfortunately, transformed it back into a regular ParseTreeWalker.
This change implements the desired behavior. Furthermore by making DEFAULT
a reference, we are able to preserve the interface to existing code.