1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-02-14 20:22:19 +00:00

Fix some error handling in FunC (#599)

This commit is contained in:
SpyCheese 2023-01-23 10:01:40 +00:00 committed by GitHub
parent 653c88aa9d
commit c6143715cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 15 deletions

View file

@ -266,7 +266,7 @@ int emulate_div(int a, int b) {
if ((b & (VarDescr::_NonZero | VarDescr::_Bit)) == (VarDescr::_NonZero | VarDescr::_Bit)) { if ((b & (VarDescr::_NonZero | VarDescr::_Bit)) == (VarDescr::_NonZero | VarDescr::_Bit)) {
return a; return a;
} else if ((b & (VarDescr::_NonZero | VarDescr::_Bool)) == (VarDescr::_NonZero | VarDescr::_Bool)) { } else if ((b & (VarDescr::_NonZero | VarDescr::_Bool)) == (VarDescr::_NonZero | VarDescr::_Bool)) {
return emulate_negate(b); return emulate_negate(a);
} }
if (b & VarDescr::_Zero) { if (b & VarDescr::_Zero) {
return VarDescr::_Int | VarDescr::_Nan; return VarDescr::_Int | VarDescr::_Nan;

View file

@ -663,12 +663,20 @@ bool Op::generate_code_step(Stack& stack) {
stack.o << "REPEAT:<{"; stack.o << "REPEAT:<{";
stack.o.indent(); stack.o.indent();
stack.forget_const(); stack.forget_const();
StackLayout layout1 = stack.vars(); if (block0->noreturn()) {
stack.mode &= ~Stack::_InlineFunc; Stack stack_copy{stack};
stack.mode |= Stack::_NeedRetAlt; StackLayout layout1 = stack.vars();
block0->generate_code_all(stack); stack_copy.mode &= ~Stack::_InlineFunc;
stack.enforce_state(std::move(layout1)); stack_copy.mode |= Stack::_NeedRetAlt;
stack.opt_show(); block0->generate_code_all(stack_copy);
} else {
StackLayout layout1 = stack.vars();
stack.mode &= ~Stack::_InlineFunc;
stack.mode |= Stack::_NeedRetAlt;
block0->generate_code_all(stack);
stack.enforce_state(std::move(layout1));
stack.opt_show();
}
stack.o.undent(); stack.o.undent();
stack.o << "}>"; stack.o << "}>";
return true; return true;

View file

@ -388,7 +388,7 @@ struct VarDescr {
return val & _Const; return val & _Const;
} }
bool is_int_const() const { bool is_int_const() const {
return (val & (_Int | _Const)) == (_Int | _Const); return (val & (_Int | _Const)) == (_Int | _Const) && int_const.not_null();
} }
bool always_nonpos() const { bool always_nonpos() const {
return val & _Neg; return val & _Neg;

View file

@ -355,6 +355,9 @@ std::vector<var_idx_t> Expr::pre_compile(CodeBlob& code, std::vector<std::pair<S
return args[0]->pre_compile(code, lval_globs); return args[0]->pre_compile(code, lval_globs);
case _Var: case _Var:
case _Hole: case _Hole:
if (val < 0) {
throw src::ParseError{here, "unexpected variable definition"};
}
return {val}; return {val};
case _VarApply: case _VarApply:
if (args[0]->cls == _Glob) { if (args[0]->cls == _Glob) {

View file

@ -1372,7 +1372,7 @@ std::vector<TypeExpr*> parse_type_var_list(Lexer& lex) {
} }
auto loc = lex.cur().loc; auto loc = lex.cur().loc;
SymDef* new_sym_def = sym::define_symbol(lex.cur().val, true, loc); SymDef* new_sym_def = sym::define_symbol(lex.cur().val, true, loc);
if (new_sym_def->value) { if (!new_sym_def || new_sym_def->value) {
lex.cur().error_at("redefined type variable `", "`"); lex.cur().error_at("redefined type variable `", "`");
} }
auto var = TypeExpr::new_var(idx); auto var = TypeExpr::new_var(idx);
@ -1582,8 +1582,15 @@ void parse_pragma(Lexer& lex) {
char op = '='; bool eq = false; char op = '='; bool eq = false;
int sem_ver[3] = {0, 0, 0}; int sem_ver[3] = {0, 0, 0};
char segs = 1; char segs = 1;
auto stoi = [&](const std::string& s) {
auto R = td::to_integer_safe<int>(s);
if (R.is_error()) {
lex.cur().error("invalid semver format");
}
return R.move_as_ok();
};
if (lex.tp() == _Number) { if (lex.tp() == _Number) {
sem_ver[0] = std::stoi(lex.cur().str); sem_ver[0] = stoi(lex.cur().str);
} else if (lex.tp() == _Ident) { } else if (lex.tp() == _Ident) {
auto id1 = lex.cur().str; auto id1 = lex.cur().str;
char ch1 = id1[0]; char ch1 = id1[0];
@ -1600,9 +1607,9 @@ void parse_pragma(Lexer& lex) {
if (id1.length() < 3) { if (id1.length() < 3) {
lex.cur().error("expected number after comparator"); lex.cur().error("expected number after comparator");
} }
sem_ver[0] = std::stoi(id1.substr(2)); sem_ver[0] = stoi(id1.substr(2));
} else { } else {
sem_ver[0] = std::stoi(id1.substr(1)); sem_ver[0] = stoi(id1.substr(1));
} }
} else { } else {
lex.cur().error("expected semver with optional comparator"); lex.cur().error("expected semver with optional comparator");
@ -1612,7 +1619,7 @@ void parse_pragma(Lexer& lex) {
if (lex.tp() != _Ident || lex.cur().str[0] != '.') { if (lex.tp() != _Ident || lex.cur().str[0] != '.') {
lex.cur().error("invalid semver format"); lex.cur().error("invalid semver format");
} }
sem_ver[1] = std::stoi(lex.cur().str.substr(1)); sem_ver[1] = stoi(lex.cur().str.substr(1));
segs = 2; segs = 2;
lex.next(); lex.next();
} }
@ -1620,7 +1627,7 @@ void parse_pragma(Lexer& lex) {
if (lex.tp() != _Ident || lex.cur().str[0] != '.') { if (lex.tp() != _Ident || lex.cur().str[0] != '.') {
lex.cur().error("invalid semver format"); lex.cur().error("invalid semver format");
} }
sem_ver[2] = std::stoi(lex.cur().str.substr(1)); sem_ver[2] = stoi(lex.cur().str.substr(1));
segs = 3; segs = 3;
lex.next(); lex.next();
} }
@ -1630,7 +1637,7 @@ void parse_pragma(Lexer& lex) {
std::string s; std::string s;
for (int idx = 0; idx < 3; idx++) { for (int idx = 0; idx < 3; idx++) {
std::getline(iss, s, '.'); std::getline(iss, s, '.');
func_ver[idx] = std::stoi(s); func_ver[idx] = stoi(s);
} }
// End parsing embedded semver // End parsing embedded semver
std::string semver_expr; std::string semver_expr;