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