1
0
mirror of synced 2024-11-28 09:30:51 +01:00

Fixed enum parse/evaluate error and crash

This commit is contained in:
WerWolv 2021-01-10 17:14:38 +01:00
parent c71c610eba
commit ad40c53eb2
3 changed files with 13 additions and 8 deletions

View File

@ -333,7 +333,7 @@ namespace hex::lang {
[[nodiscard]] const std::unordered_map<std::string, ASTNode*>& getEntries() const { return this->m_entries; } [[nodiscard]] const std::unordered_map<std::string, ASTNode*>& getEntries() const { return this->m_entries; }
void addEntry(const std::string &name, ASTNode* expression) { this->m_entries.insert({ name, expression }); } void addEntry(const std::string &name, ASTNode* expression) { this->m_entries.insert({ name, expression }); }
[[nodiscard]] const ASTNode *getUnderlyingType() const { return this->m_underlyingType; } [[nodiscard]] ASTNode *getUnderlyingType() { return this->m_underlyingType; }
private: private:
std::unordered_map<std::string, ASTNode*> m_entries; std::unordered_map<std::string, ASTNode*> m_entries;

View File

@ -440,13 +440,17 @@ namespace hex::lang {
entryPatterns.push_back({{ valueNode->getType(), valueNode->getValue() }, name }); entryPatterns.push_back({{ valueNode->getType(), valueNode->getValue() }, name });
} }
auto underlyingType = dynamic_cast<ASTNodeTypeDecl*>(node->getUnderlyingType());
if (underlyingType == nullptr)
throwEvaluateError("enum underlying type was not ASTNodeTypeDecl. This is a bug");
size_t size; size_t size;
if (auto underlyingType = dynamic_cast<const ASTNodeBuiltinType*>(node->getUnderlyingType()); underlyingType != nullptr) if (auto builtinType = dynamic_cast<ASTNodeBuiltinType*>(underlyingType->getType()); builtinType != nullptr)
size = Token::getTypeSize(underlyingType->getType()); size = Token::getTypeSize(builtinType->getType());
else else
throwEvaluateError("invalid enum underlying type"); throwEvaluateError("invalid enum underlying type");
return new PatternDataEnum(startOffset, size, entryPatterns); return new PatternDataEnum(startOffset, size, entryPatterns);;
} }
PatternData* Evaluator::evaluateBitfield(ASTNodeBitfield *node) { PatternData* Evaluator::evaluateBitfield(ASTNodeBitfield *node) {
@ -711,7 +715,7 @@ namespace hex::lang {
delete result; delete result;
} }
this->m_endianStack.pop_back(); this->m_endianStack.clear();
} }
} catch (EvaluateError &e) { } catch (EvaluateError &e) {
this->m_consoleLog.emplace_back(ConsoleLogLevel::Error, e); this->m_consoleLog.emplace_back(ConsoleLogLevel::Error, e);

View File

@ -454,6 +454,7 @@ namespace hex::lang {
auto underlyingType = dynamic_cast<ASTNodeTypeDecl*>(parseType(-2)); auto underlyingType = dynamic_cast<ASTNodeTypeDecl*>(parseType(-2));
if (underlyingType == nullptr) throwParseError("failed to parse type", -2); if (underlyingType == nullptr) throwParseError("failed to parse type", -2);
if (underlyingType->getEndian().has_value()) throwParseError("underlying type may not have an endian specification", -2);
const auto enumNode = new ASTNodeEnum(underlyingType); const auto enumNode = new ASTNodeEnum(underlyingType);
ScopeExit enumGuard([&]{ delete enumNode; }); ScopeExit enumGuard([&]{ delete enumNode; });
@ -471,7 +472,7 @@ namespace hex::lang {
ASTNode *valueExpr; ASTNode *valueExpr;
auto name = getValue<std::string>(-1); auto name = getValue<std::string>(-1);
if (enumNode->getEntries().empty()) if (enumNode->getEntries().empty())
lastEntry = TO_NUMERIC_EXPRESSION(new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned8Bit, u8(0) })); valueExpr = lastEntry = TO_NUMERIC_EXPRESSION(new ASTNodeIntegerLiteral({ Token::ValueType::Unsigned8Bit, u8(0) }));
else else
valueExpr = new ASTNodeNumericExpression(lastEntry->clone(), new ASTNodeIntegerLiteral({ Token::ValueType::Any, s32(1) }), Token::Operator::Plus); valueExpr = new ASTNodeNumericExpression(lastEntry->clone(), new ASTNodeIntegerLiteral({ Token::ValueType::Any, s32(1) }), Token::Operator::Plus);
@ -480,13 +481,13 @@ namespace hex::lang {
else if (MATCHES(sequence(SEPARATOR_ENDOFPROGRAM))) else if (MATCHES(sequence(SEPARATOR_ENDOFPROGRAM)))
throwParseError("unexpected end of program", -2); throwParseError("unexpected end of program", -2);
else else
throwParseError("invalid union member", 0); throwParseError("invalid enum entry", -1);
if (!MATCHES(sequence(SEPARATOR_COMMA))) { if (!MATCHES(sequence(SEPARATOR_COMMA))) {
if (MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) if (MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE)))
break; break;
else else
throwParseError("missing ',' between enum entries", 0); throwParseError("missing ',' between enum entries", -1);
} }
} }