diff options
author | chriseth <chris@ethereum.org> | 2019-01-22 20:49:41 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-22 20:49:41 +0800 |
commit | 10d17f245839f208ec5085309022a32cd2502f55 (patch) | |
tree | b2c9f68980d0d418cd6f511e9f3f3f71369abe25 /libyul/AsmAnalysis.cpp | |
parent | 1df8f40cd2fd7b47698d847907b8ca7b47eb488d (diff) | |
parent | 0ecafe032a84cb6960545dd7f18733430c1f782d (diff) | |
download | dexon-solidity-10d17f245839f208ec5085309022a32cd2502f55.tar.gz dexon-solidity-10d17f245839f208ec5085309022a32cd2502f55.tar.zst dexon-solidity-10d17f245839f208ec5085309022a32cd2502f55.zip |
Merge pull request #5836 from ethereum/develop
Merge develop into release for 0.5.3.
Diffstat (limited to 'libyul/AsmAnalysis.cpp')
-rw-r--r-- | libyul/AsmAnalysis.cpp | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index 0ecc5a30..a5552c51 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -24,6 +24,7 @@ #include <libyul/AsmScopeFiller.h> #include <libyul/AsmScope.h> #include <libyul/AsmAnalysisInfo.h> +#include <libyul/Utilities.h> #include <liblangutil/ErrorReporter.h> @@ -299,11 +300,14 @@ bool AsmAnalyzer::operator()(FunctionCall const& _funCall) bool success = true; size_t parameters = 0; size_t returns = 0; + bool needsLiteralArguments = false; if (BuiltinFunction const* f = m_dialect->builtin(_funCall.functionName.name)) { // TODO: compare types, too parameters = f->parameters.size(); returns = f->returns.size(); + if (f->literalArguments) + needsLiteralArguments = true; } else if (!m_currentScope->lookup(_funCall.functionName.name, Scope::Visitor( [&](Scope::Variable const&) @@ -347,8 +351,15 @@ bool AsmAnalyzer::operator()(FunctionCall const& _funCall) } for (auto const& arg: _funCall.arguments | boost::adaptors::reversed) + { if (!expectExpression(arg)) success = false; + else if (needsLiteralArguments && arg.type() != typeid(Literal)) + m_errorReporter.typeError( + _funCall.functionName.location, + "Function expects direct literals as arguments." + ); + } // Use argument size instead of parameter count to avoid misleading errors. m_stackHeight += int(returns) - int(_funCall.arguments.size()); m_info.stackHeightInfo[&_funCall] = m_stackHeight; @@ -380,7 +391,29 @@ bool AsmAnalyzer::operator()(Switch const& _switch) if (!expectExpression(*_switch.expression)) success = false; - set<tuple<LiteralKind, YulString>> cases; + if (m_dialect->flavour == AsmFlavour::Yul) + { + YulString caseType; + bool mismatchingTypes = false; + for (auto const& _case: _switch.cases) + if (_case.value) + { + if (caseType.empty()) + caseType = _case.value->type; + else if (caseType != _case.value->type) + { + mismatchingTypes = true; + break; + } + } + if (mismatchingTypes) + m_errorReporter.typeError( + _switch.location, + "Switch cases have non-matching types." + ); + } + + set<Literal const*, Less<Literal*>> cases; for (auto const& _case: _switch.cases) { if (_case.value) @@ -394,12 +427,11 @@ bool AsmAnalyzer::operator()(Switch const& _switch) m_stackHeight--; /// Note: the parser ensures there is only one default case - auto val = make_tuple(_case.value->kind, _case.value->value); - if (!cases.insert(val).second) + if (!cases.insert(_case.value.get()).second) { m_errorReporter.declarationError( _case.location, - "Duplicate case defined" + "Duplicate case defined." ); success = false; } |