|
41 | 41 |
|
42 | 42 | #include <fmt/format.h> |
43 | 43 |
|
44 | | -#include <memory> |
45 | 44 | #include <functional> |
46 | 45 |
|
47 | 46 | using namespace std::string_literals; |
@@ -101,24 +100,37 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect, |
101 | 100 | std::vector<YulString> AsmAnalyzer::operator()(Literal const& _literal) |
102 | 101 | { |
103 | 102 | expectValidType(_literal.type, nativeLocationOf(_literal)); |
104 | | - if (_literal.kind == LiteralKind::String && _literal.value.str().size() > 32) |
| 103 | + bool erroneousLiteral = false; |
| 104 | + if (_literal.kind == LiteralKind::String && !_literal.value.unlimited() && _literal.value.hint() && _literal.value.hint()->size() > 32) |
| 105 | + { |
| 106 | + erroneousLiteral = true; |
105 | 107 | m_errorReporter.typeError( |
106 | 108 | 3069_error, |
107 | 109 | nativeLocationOf(_literal), |
108 | | - "String literal too long (" + std::to_string(_literal.value.str().size()) + " > 32)" |
109 | | - ); |
110 | | - else if (_literal.kind == LiteralKind::Number && bigint(_literal.value.str()) > u256(-1)) |
| 110 | + "String literal too long (" + std::to_string(formatLiteral(_literal, false).size()) + " > 32)"); |
| 111 | + } |
| 112 | + else if (_literal.kind == LiteralKind::Number && _literal.value.hint() && bigint(*_literal.value.hint()) > u256(-1)) |
| 113 | + { |
| 114 | + erroneousLiteral = true; |
111 | 115 | m_errorReporter.typeError(6708_error, nativeLocationOf(_literal), "Number literal too large (> 256 bits)"); |
| 116 | + } |
112 | 117 | else if (_literal.kind == LiteralKind::Boolean) |
113 | | - yulAssert(_literal.value == "true"_yulstring || _literal.value == "false"_yulstring, ""); |
| 118 | + { |
| 119 | + yulAssert(_literal.value.value() == true || _literal.value.value() == false); |
| 120 | + if (_literal.value.hint()) |
| 121 | + yulAssert(*_literal.value.hint() == "true" || *_literal.value.hint() == "false"); |
| 122 | + } |
114 | 123 |
|
115 | 124 | if (!m_dialect.validTypeForLiteral(_literal.kind, _literal.value, _literal.type)) |
| 125 | + { |
| 126 | + erroneousLiteral = true; |
116 | 127 | m_errorReporter.typeError( |
117 | 128 | 5170_error, |
118 | 129 | nativeLocationOf(_literal), |
119 | | - "Invalid type \"" + _literal.type.str() + "\" for literal \"" + _literal.value.str() + "\"." |
120 | | - ); |
| 130 | + "Invalid type \"" + _literal.type.str() + "\" for literal \"" + formatLiteral(_literal, false) + "\"."); |
| 131 | + } |
121 | 132 |
|
| 133 | + yulAssert(erroneousLiteral || validLiteral(_literal), "Invalid literal after validating it through AsmAnalyzer."); |
122 | 134 | return {_literal.type}; |
123 | 135 | } |
124 | 136 |
|
@@ -417,23 +429,25 @@ std::vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall) |
417 | 429 | std::string functionName = _funCall.functionName.name.str(); |
418 | 430 | if (functionName == "datasize" || functionName == "dataoffset") |
419 | 431 | { |
420 | | - if (!m_dataNames.count(std::get<Literal>(arg).value)) |
| 432 | + auto const& argumentAsLiteral = std::get<Literal>(arg); |
| 433 | + if (!m_dataNames.count(YulString(formatLiteral(argumentAsLiteral)))) |
421 | 434 | m_errorReporter.typeError( |
422 | 435 | 3517_error, |
423 | 436 | nativeLocationOf(arg), |
424 | | - "Unknown data object \"" + std::get<Literal>(arg).value.str() + "\"." |
| 437 | + "Unknown data object \"" + formatLiteral(argumentAsLiteral) + "\"." |
425 | 438 | ); |
426 | 439 | } |
427 | 440 | else if (functionName.substr(0, "verbatim_"s.size()) == "verbatim_") |
428 | 441 | { |
429 | | - if (std::get<Literal>(arg).value.empty()) |
| 442 | + static u256 const empty {valueOfStringLiteral("").value()}; |
| 443 | + auto const& literalValue = std::get<Literal>(arg).value; |
| 444 | + if ((literalValue.unlimited() && literalValue.builtinStringLiteralValue().empty()) || (!literalValue.unlimited() && literalValue.value() == empty)) |
430 | 445 | m_errorReporter.typeError( |
431 | 446 | 1844_error, |
432 | 447 | nativeLocationOf(arg), |
433 | 448 | "The \"verbatim_*\" builtins cannot be used with empty bytecode." |
434 | 449 | ); |
435 | 450 | } |
436 | | - |
437 | 451 | argTypes.emplace_back(expectUnlimitedStringLiteral(std::get<Literal>(arg))); |
438 | 452 | continue; |
439 | 453 | } |
@@ -492,12 +506,12 @@ void AsmAnalyzer::operator()(Switch const& _switch) |
492 | 506 | (*this)(*_case.value); |
493 | 507 |
|
494 | 508 | /// Note: the parser ensures there is only one default case |
495 | | - if (watcher.ok() && !cases.insert(valueOfLiteral(*_case.value)).second) |
| 509 | + if (watcher.ok() && !cases.insert(_case.value->value.value()).second) |
496 | 510 | m_errorReporter.declarationError( |
497 | 511 | 6792_error, |
498 | 512 | nativeLocationOf(_case), |
499 | 513 | "Duplicate case \"" + |
500 | | - valueOfLiteral(*_case.value).str() + |
| 514 | + formatLiteral(*_case.value) + |
501 | 515 | "\" defined." |
502 | 516 | ); |
503 | 517 | } |
@@ -557,8 +571,9 @@ YulString AsmAnalyzer::expectExpression(Expression const& _expr) |
557 | 571 |
|
558 | 572 | YulString AsmAnalyzer::expectUnlimitedStringLiteral(Literal const& _literal) |
559 | 573 | { |
560 | | - yulAssert(_literal.kind == LiteralKind::String, ""); |
561 | | - yulAssert(m_dialect.validTypeForLiteral(LiteralKind::String, _literal.value, _literal.type), ""); |
| 574 | + yulAssert(_literal.kind == LiteralKind::String); |
| 575 | + yulAssert(m_dialect.validTypeForLiteral(LiteralKind::String, _literal.value, _literal.type)); |
| 576 | + yulAssert(_literal.value.unlimited()); |
562 | 577 |
|
563 | 578 | return {_literal.type}; |
564 | 579 | } |
|
0 commit comments