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/20, WalterCouto, Walter Couto, WalterCouto@users.noreply.github.com
|
||||||
2018/12/23, youkaichao, Kaichao You, youkaichao@gmail.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/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;
|
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::NoViableAltException(Parser *recognizer)
|
||||||
: NoViableAltException(recognizer, recognizer->getTokenStream(), recognizer->getCurrentToken(),
|
: NoViableAltException(recognizer, recognizer->getTokenStream(), recognizer->getCurrentToken(),
|
||||||
recognizer->getCurrentToken(), nullptr, recognizer->getContext(), false) {
|
recognizer->getCurrentToken(), nullptr, recognizer->getContext(), false) {
|
||||||
|
@ -17,12 +31,10 @@ NoViableAltException::NoViableAltException(Parser *recognizer)
|
||||||
NoViableAltException::NoViableAltException(Parser *recognizer, TokenStream *input,Token *startToken,
|
NoViableAltException::NoViableAltException(Parser *recognizer, TokenStream *input,Token *startToken,
|
||||||
Token *offendingToken, atn::ATNConfigSet *deadEndConfigs, ParserRuleContext *ctx, bool deleteConfigs)
|
Token *offendingToken, atn::ATNConfigSet *deadEndConfigs, ParserRuleContext *ctx, bool deleteConfigs)
|
||||||
: RecognitionException("No viable alternative", recognizer, input, ctx, offendingToken),
|
: RecognitionException("No viable alternative", recognizer, input, ctx, offendingToken),
|
||||||
_deadEndConfigs(deadEndConfigs), _startToken(startToken), _deleteConfigs(deleteConfigs) {
|
_deadEndConfigs(buildConfigsRef(deadEndConfigs, deleteConfigs)), _startToken(startToken) {
|
||||||
}
|
}
|
||||||
|
|
||||||
NoViableAltException::~NoViableAltException() {
|
NoViableAltException::~NoViableAltException() {
|
||||||
if (_deleteConfigs)
|
|
||||||
delete _deadEndConfigs;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Token* NoViableAltException::getStartToken() const {
|
Token* NoViableAltException::getStartToken() const {
|
||||||
|
@ -30,5 +42,5 @@ Token* NoViableAltException::getStartToken() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
atn::ATNConfigSet* NoViableAltException::getDeadEndConfigs() const {
|
atn::ATNConfigSet* NoViableAltException::getDeadEndConfigs() const {
|
||||||
return _deadEndConfigs;
|
return _deadEndConfigs.get();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,9 @@ namespace antlr4 {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Which configurations did we try at input.index() that couldn't match input.LT(1)?
|
/// Which configurations did we try at input.index() that couldn't match input.LT(1)?
|
||||||
atn::ATNConfigSet* _deadEndConfigs;
|
/// Shared pointer that conditionally deletes the configurations (based on flag
|
||||||
|
/// passed during construction)
|
||||||
// Flag that indicates if we own the dead end config set and have to delete it on destruction.
|
Ref<atn::ATNConfigSet> _deadEndConfigs;
|
||||||
bool _deleteConfigs;
|
|
||||||
|
|
||||||
/// The token object at the start index; the input stream might
|
/// The token object at the start index; the input stream might
|
||||||
/// not be buffering tokens so get a reference to it. (At the
|
/// not be buffering tokens so get a reference to it. (At the
|
||||||
|
|
Loading…
Reference in New Issue