forked from jasder/antlr
Avoid double deletion when NoViableAltException is thrown
When ownership of the configurations set is passed to a NoViableAltException, it get deleted more than once if the exception happens to get copied.
This commit is contained in:
parent
1c6c62afc7
commit
d69e7c4d0f
|
@ -213,3 +213,4 @@ YYYY/MM/DD, github id, Full name, email
|
|||
2018/12/20, WalterCouto, Walter Couto, WalterCouto@users.noreply.github.com
|
||||
2018/12/23, youkaichao, Kaichao You, youkaichao@gmail.com
|
||||
2019/02/06, ralucado, Cristina Raluca Vijulie, ralucris.v[at]gmail[dot]com
|
||||
2019/02/23, gedimitr, Gerasimos Dimitriadis, gedimitr@gmail.com
|
||||
|
|
|
@ -9,6 +9,20 @@
|
|||
|
||||
using namespace antlr4;
|
||||
|
||||
namespace {
|
||||
|
||||
// Create a normal shared pointer if the configurations are to be deleted. If not, then
|
||||
// the shared pointer is created with a deleter that does nothing.
|
||||
Ref<atn::ATNConfigSet> buildConfigsRef(atn::ATNConfigSet *configs, bool deleteConfigs) {
|
||||
if (deleteConfigs) {
|
||||
return Ref<atn::ATNConfigSet>(configs);
|
||||
} else {
|
||||
return Ref<atn::ATNConfigSet>(configs, [](atn::ATNConfigSet *){});
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NoViableAltException::NoViableAltException(Parser *recognizer)
|
||||
: NoViableAltException(recognizer, recognizer->getTokenStream(), recognizer->getCurrentToken(),
|
||||
recognizer->getCurrentToken(), nullptr, recognizer->getContext(), false) {
|
||||
|
@ -17,12 +31,10 @@ NoViableAltException::NoViableAltException(Parser *recognizer)
|
|||
NoViableAltException::NoViableAltException(Parser *recognizer, TokenStream *input,Token *startToken,
|
||||
Token *offendingToken, atn::ATNConfigSet *deadEndConfigs, ParserRuleContext *ctx, bool deleteConfigs)
|
||||
: RecognitionException("No viable alternative", recognizer, input, ctx, offendingToken),
|
||||
_deadEndConfigs(deadEndConfigs), _startToken(startToken), _deleteConfigs(deleteConfigs) {
|
||||
_deadEndConfigs(buildConfigsRef(deadEndConfigs, deleteConfigs)), _startToken(startToken) {
|
||||
}
|
||||
|
||||
NoViableAltException::~NoViableAltException() {
|
||||
if (_deleteConfigs)
|
||||
delete _deadEndConfigs;
|
||||
}
|
||||
|
||||
Token* NoViableAltException::getStartToken() const {
|
||||
|
@ -30,5 +42,5 @@ Token* NoViableAltException::getStartToken() const {
|
|||
}
|
||||
|
||||
atn::ATNConfigSet* NoViableAltException::getDeadEndConfigs() const {
|
||||
return _deadEndConfigs;
|
||||
return _deadEndConfigs.get();
|
||||
}
|
||||
|
|
|
@ -27,10 +27,9 @@ namespace antlr4 {
|
|||
|
||||
private:
|
||||
/// Which configurations did we try at input.index() that couldn't match input.LT(1)?
|
||||
atn::ATNConfigSet* _deadEndConfigs;
|
||||
|
||||
// Flag that indicates if we own the dead end config set and have to delete it on destruction.
|
||||
bool _deleteConfigs;
|
||||
/// Shared pointer that conditionally deletes the configurations (based on flag
|
||||
/// passed during construction)
|
||||
Ref<atn::ATNConfigSet> _deadEndConfigs;
|
||||
|
||||
/// The token object at the start index; the input stream might
|
||||
/// not be buffering tokens so get a reference to it. (At the
|
||||
|
|
Loading…
Reference in New Issue