Skip to content

Conversation

@cameel
Copy link
Collaborator

@cameel cameel commented Sep 20, 2021

Fixes #11932.

@cameel cameel requested a review from chriseth September 20, 2021 16:31
@cameel cameel self-assigned this Sep 20, 2021
@chriseth
Copy link
Contributor

I have the impression that AsmParser needs some more changes, but I might be wrong.

We have three modes for AsmParser:

  1. native yul mode - irLocation and originalLocation should always point to the locations generated from the scanner ignoring the annotations
  2. location override: This is used for snippets of yul code generated from solidity code in the old codegen. It probably makes sense for both to point at the solidity source location. We could also make the ir location point at the scanner location, but we probably don't have the actual source anymore at the point where we generate a potential parser error.
  3. from comments: ir location points at scanner, original location is taken from comments

It might very well be that your code already accomplishes the above. If this is the case, it might be worth refactoring it at a later point in time to make the distinction clearer - especially if it is possible in 2) for the ir location to point at the scanner locations - in this case we can make it always point at the scanner locations.

@cameel
Copy link
Collaborator Author

cameel commented Sep 20, 2021

I'll take a deeper look at that tomorrow. For now in a few places I wasn't really sure which location to take but just went with it to get it to a state where it compiles, with the intention to do one more pass through the code after that. Judging by test failures, I must have chosen wrong in some places :)

@cameel cameel force-pushed the separate-yul-and-sol-locations-in-debug-info branch from 6fcae57 to 54ffd68 Compare September 21, 2021 14:29
Comment on lines 98 to 104
langutil::SourceLocation currentLocation() const override
{
if (m_useSourceLocationFrom == UseSourceLocationFrom::Scanner)
return ParserBase::currentLocation();
return m_locationOverride;
if (m_useSourceLocationFrom == UseSourceLocationFrom::LocationOverride)
return m_locationOverride;

return ParserBase::currentLocation();
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ICE is gone but still not all errors from #11932 (comment) have locations. This might still be using the original location in places where IR location should be used.

There was actually an extra bug here. Location override was overriding current location even when location from comments was selected. This resulted in empty location in errors reported from AsmParser.cpp. See test/libyul/yulSyntaxTests/invalid/literals_on_stack_disallowed_with_debug_info.yul.

Comment on lines 69 to +70
case UseSourceLocationFrom::LocationOverride:
return DebugData::create(m_locationOverride);
return DebugData::create(m_locationOverride, m_locationOverride);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. location override: This is used for snippets of yul code generated from solidity code in the old codegen. It probably makes sense for both to point at the solidity source location.

I think that m_locationOverride for both is the most consistent. If I use current location for nativeLocation instead, Parser will be reporting errors at m_locationOverride but AsmAnalyzer (which, I'm assuming gets locations from nativeLocation in the AST) will be be reporting them at the current location.

We could also make the ir location point at the scanner location, but we probably don't have the actual source anymore at the point where we generate a potential parser error.

Errors are processed and reported from within CompilerContext::appendInlineAssembly() which still has the original snippet. To check that I introduced an error to one of the generated sources and there were no failing assertions and messages seemed to be pointing at the correct location in the snippet - even when nativeLocation was set to the current location rather than the override.

But there's still the problem with inconsistent location in errors I mentioned above. We can change that but we should then also change error messages to consistently use one kind of locations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It probably doesn't matter too much, because these will all lead to internal compiler errors anyway.

Comment on lines 412 to 413
{
solAssert(m_currentNode && m_inlineAssembly, "");
m_currentNode->location = langutil::SourceLocation::smallestCovering(m_currentNode->location, locationOf(_statement));
m_currentNode->location = langutil::SourceLocation::smallestCovering(m_currentNode->location, nativeLocationOf(_statement));
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing this to originLocationOf() does not break any tests so I think we don't have coverage for this in case where Yul source has debug info annotations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to check: nativeLocationOf(_statement) always returns a "proper" source location, no matter in which mode the parser was used, right?

What I'm a bit worried about is the possibility of the location being the same when we use appendAssembly in the old code generator and supply two different snippets (that would not have a different name) but two yul ast items have the same native locations inside these snippets.

IIRC, location is not only used for informational purposes, but to check equality in the source - is this the case here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah wait, this is only about inline assembly here (and not compiler-generated assembly for helper routines), so native location and origin location should be the same anyway. Maybe assert that?

Copy link
Collaborator Author

@cameel cameel Sep 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to check: nativeLocationOf(_statement) always returns a "proper" source location, no matter in which mode the parser was used, right?

Yes.

IIRC, location is not only used for informational purposes, but to check equality in the source - is this the case here?

Yeah, it looks like it's using it to disambiguate the stuff it adds to variableOccurrences.

What I'm a bit worried about is the possibility of the location being the same when we use appendAssembly in the old code generator and supply two different snippets (that would not have a different name) but two yul ast items have the same native locations inside these snippets.

I don't really understand this. We're not storing snippets in debug info or passing them around. Or do you mean the inline assembly snippets we compile with the location override? I'm also not sure what the consequences of these locations being the same would be.

Ah wait, this is only about inline assembly here (and not compiler-generated assembly for helper routines), so native location and origin location should be the same anyway. Maybe assert that?

Ah, you're right. It's in libsolidity so it must be. Assertions added.

Comment on lines -174 to +177
Json::Value ASTJsonConverter::inlineAssemblyIdentifierToJson(pair<yul::Identifier const* ,InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const
Json::Value ASTJsonConverter::inlineAssemblyIdentifierToJson(pair<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const
{
Json::Value tuple(Json::objectValue);
tuple["src"] = sourceLocationToString(_info.first->debugData->location);
tuple["src"] = sourceLocationToString(nativeLocationOf(*_info.first));
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing this to originLocationOf() does not break any tests so but I guess this is because we cannot have debug info annotations in inline assembly?

@cameel cameel marked this pull request as ready for review September 21, 2021 14:54
{

Json::Value AsmJsonConverter::operator()(Block const& _node) const
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to store both locations in the asm ast?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like something that could be useful to tools. I think it should be properly introduced in a standalone PR though. We need to agree on the name (maybe "origin"?) and decide if we want other debug info here, like AST ID. Also needs some tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be in the same PR - we are changing the value of "location" in the case of code that has @use-src.
origin sounds good.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are changing the value of "location" in the case of code that has @use-src.

I wanted to say that we are not because there are no changes in test output, but you're right, there should have been some changes. So either something's wrong or, more likely, we do not have coverage for this.

Anyway, I'm out of time now so I'll be doing that change tomorrow. I'll do it in the same PR if I manage to before the release but I still think a separate PR would be more convenient - this one is pretty much a bugfix for the fact that these locations changed in 0.8.6 and is basically finished.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I'm fine with either, but it seems that there is a problem in the ast export and re-import anyway...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. I think that the problem is that the origin location is not preserved in AST nodes in inline assembly when you export and reimport the AST (https://github.com/ethereum/solidity/pull/11998/files#r713769635). So it's exactly what you pointed out but it's not enough to add it to JSON, we also need to import that information back.

I'm going to remove the assertions from this PR and add them in the one that extends the AST instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course, anything you add to the json export also has to be added to the json import :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I knew there was a catch somewhere :P

Anyway, I'm going to actually push one more change. I'll make the importer use the "src" location for both native and origin location - I'm not not sure if adding "origin" actually makes sense since it has to include file index and I only have one when compiling inline assembly - and there it's the same as "src" anyway.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So either something's wrong or, more likely, we do not have coverage for this.

And this turns out to be because without #9590 there's no way to output the Yul AST (other than for inline assembly or generated sources and we can't have debug info annotations there). So naturally it does not get tested.

@cameel cameel force-pushed the separate-yul-and-sol-locations-in-debug-info branch from 54ffd68 to 9e6280e Compare September 21, 2021 16:03
@chriseth
Copy link
Contributor

commandline tests are failing.

@cameel
Copy link
Collaborator Author

cameel commented Sep 22, 2021

Yeah, I'm working on that.

Comment on lines 245 to 249
m_errorReporter.declarationError(
4718_error,
_identifier.debugData->location,
nativeLocationOf(_identifier),
"Multiple matching identifiers. Resolving overloaded identifiers is not supported."
);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The assertion I added for this is actually failing during AST export and reimport of syntaxTests/inlineAssembly/storage_reference_old_shadow.sol:

contract C {
    uint[] x;
    fallback() external {
        uint y_slot = 2;
        uint y_offset = 3;
        uint[] storage y = x;
        assembly {
            pop(y_slot)
            pop(y_offset)
        }
        y[0] = 2;
    }
}
// ----

This is why CLI tests are failing. BTW the error handling for AST import is swallowing errors at multiple levels (both in solc and in the test script), which makes it harder to debug than it should be.

@cameel cameel force-pushed the separate-yul-and-sol-locations-in-debug-info branch from 9e6280e to 03d5b71 Compare September 22, 2021 10:21
chriseth
chriseth previously approved these changes Sep 22, 2021
@cameel cameel force-pushed the separate-yul-and-sol-locations-in-debug-info branch from 03d5b71 to fc7e8c5 Compare September 22, 2021 11:18
@cameel cameel mentioned this pull request Sep 22, 2021
1 task
@chriseth chriseth merged commit bcdaa0c into develop Sep 22, 2021
@chriseth chriseth deleted the separate-yul-and-sol-locations-in-debug-info branch September 22, 2021 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ICE when the file name in @use-src annotation does not match the name of the file passed to --strict-assembly

3 participants