Fix wrong native locations in optimized Yul artifacts#15309
Conversation
b487140 to
0d75360
Compare
|
|
||
| m_stackState = Parsed; | ||
| optimize(*m_parserResult, true); | ||
| yulAssert(analyzeParsed(), "Invalid source code after optimization."); |
There was a problem hiding this comment.
This is what was causing double warnings. analyzeParsed() is not side-effect free and actually adds anything that is reported to the current error list. The assumption was probably that a this point nothing will be reported because the code compiles. Warnings and infos are still possible though. They will be reported again unless the code that triggers them happens to be optimized out.
| public: | ||
| static void compile( | ||
| Object& _object, | ||
| Object const& _object, |
There was a problem hiding this comment.
Not sure why this wasn't const already. It should have been because EVMObjectCompiler does not modify the object. I'm changing it here because I wanted to be sure that optimize() is the only place that actually modifies the object and requires reparsing.
There was a problem hiding this comment.
Probably a remnant of findFunctionCalls not having a const version. Still, even a const ref to an object allows modification on the ast, as it's sitting in a smart pointer which doesnt propagate constness. I think this should be changed eventually
There was a problem hiding this comment.
True. But at least your immutable AST PR does address it, at least for the AST which is the most relevant part of the object. Perhaps we should just make Object a proper class and hide other members behind const accessors too.
| YulStack cleanStack(m_evmVersion, m_eofVersion, m_language, m_optimiserSettings, m_debugInfoSelection); | ||
| bool reanalysisSuccessful = cleanStack.parseAndAnalyze(m_charStream->name(), source); |
There was a problem hiding this comment.
Using YulStack in YulStack feels a bit like an overkill, but it seemed cleaner to me than refactoring the parsing methods to make them usable without overwriting what's in the current stack.
clonker
left a comment
There was a problem hiding this comment.
Overall it looks good to me. I am not sure if I am too happy with YulStack as a whole, it does play with a lot of side effects (which of course is somewhat in the nature of combining parsing/analyzing/optimizing/assembling). Maybe it would help a bit to, e.g., have both unoptimized and optimized objects in the state.
| public: | ||
| static void compile( | ||
| Object& _object, | ||
| Object const& _object, |
There was a problem hiding this comment.
Probably a remnant of findFunctionCalls not having a const version. Still, even a const ref to an object allows modification on the ast, as it's sitting in a smart pointer which doesnt propagate constness. I think this should be changed eventually
| /// rather than the initial source. | ||
| /// @warning Does not update the error list or the original source (@a m_charStream) to make | ||
| /// it possible to report errors to the user even after the optimization has been performed. | ||
| void reparse(); |
There was a problem hiding this comment.
Sounds like something that could potentially also be solved by keeping the original parsing result / object around and the optimize method create a new, optimized version of it (perhaps in the spirit of the immutable AST PR). Then, I imagine, there also wouldn't be this mix of properties where some refer to data before optimization, some to data after optimization and you could potentially get rid of the YulStack in YulStack implementation of reparse.
There was a problem hiding this comment.
True, that would be a much better design, more similar to CompilerStack. YulStack is just wildly inconsistent. Parsing is stateful but creates new things (stores parsing result), then optimization is stateful but modifies things in place, and then assembling is stateless and not in-place (just returns the result to the caller). It should be more like a proper pipeline with each stage filling its artifact based on the result of previous stages.
Still, I'm not to keen to get into that refactor right now. I'd get rid of YulStack from reparse() but I would still basically have to do the refactor I avoided, i.e. create stateless helpers for parsing and analysis so that I can run them on different objects. I wanted this to be a quick fix so that I get the cache to PR to a mergeable state before I'm off tomorrow.
So, if there are no bugs or bigger issues here, I'd rather merge this as is to unblock the caching PR. We can always do that refactor on top of them, later.
0d75360 to
babe3d9
Compare
- This makes it apply to yul compilation as well. - Also fixes warnings being reported again when optimizing IR.
babe3d9 to
fe4c52e
Compare
Extends #15228.
The original PR handled only the Yul AST produced from Solidity sources. This one addresses the issue more comprehensively, by moving reparsing of optimized IR to
YulStackso that it has effect on pure Yul compilation as well. In Yul mode the affected artifacts are not limited to the AST - source locations and debug comments in EVM assembly output are also affected.Also fixes a small bug in
YulStackthat made it report warnings twice (i.e. ones reported in unoptimized code and then the same warnings from optimized code).