Skip to content

fix: resolve isoltest crash on interactive update#16438

Open
JPier34 wants to merge 2 commits intoargotorg:developfrom
JPier34:fix/isoltest-crash-16337
Open

fix: resolve isoltest crash on interactive update#16438
JPier34 wants to merge 2 commits intoargotorg:developfrom
JPier34:fix/isoltest-crash-16337

Conversation

@JPier34
Copy link
Contributor

@JPier34 JPier34 commented Feb 3, 2026

Summary

Fixes a crash in isoltest when using the interactive update feature (pressing 'u' to accept updated expectations).

Fixes #16337

Problem

When isoltest runs with a test file, CompilerStack::lastContractName() may fail to find the contract because mainSourceFile can differ from the actual key in m_sources. This mismatch causes lastContractName() to return an empty string, leading to a crash when the test framework attempts to use the contract name.

Solution

Added a fallback search in CompilerStack::lastContractName(): if the specified source is not found in m_sources, iterate over all sources to find a valid contract name. This ensures that even if there's a source name mismatch, the function will still return the correct contract name.

Changes

  • libsolidity/interface/CompilerStack.cpp: Added fallback logic in lastContractName() to search all sources when specified source is not found
  • test/tools/isoltest.cpp: Added explicit flush() and close() after writing updated test files to prevent potential I/O race conditions
  • test/libsolidity/semanticTests/test_issue_16337.sol: Added minimal test case to verify the fix

When using isoltest's interactive update feature (pressing 'u' to accept
new expectations), the tool would crash with "Contract '' not found" error
during the re-run of the updated test.

Root cause: In lastContractName(), when the specified source name doesn't
match any key in m_sources (e.g., due to source name mismatch between
mainSourceFile and actual source keys), the function returned an empty
string, causing the "Contract '' not found" error.

Changes:
- CompilerStack.cpp: Add fallback search across all sources when the
  specified source is not found in m_sources
- isoltest.cpp: Add explicit flush() and close() after writing updated
  test file to ensure complete write before re-read

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@github-actions
Copy link

github-actions bot commented Feb 3, 2026

Thank you for your contribution to the Solidity compiler! A team member will follow up shortly.

If you haven't read our contributing guidelines and our review checklist before, please do it now, this makes the reviewing process and accepting your contribution smoother.

If you have any questions or need our help, feel free to post them in the PR or talk to us directly on the #solidity-dev channel on Matrix.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a crash in isoltest when using the interactive update feature (pressing 'u' to accept updated expectations). The crash occurred when CompilerStack::lastContractName() couldn't find a contract because the mainSourceFile name didn't match the actual keys in the m_sources map, particularly in multi-source test files.

Changes:

  • Added fallback logic in CompilerStack::lastContractName() to search all sources when the specified source is not found
  • Added explicit flush() and close() calls after writing updated test files in isoltest to prevent potential I/O race conditions
  • Added a basic regression test case

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
libsolidity/interface/CompilerStack.cpp Added fallback search logic and null check for AST in lastContractName() to handle source name mismatches
test/tools/isoltest.cpp Added explicit flush and close operations to ensure test file is fully written before rerun
test/libsolidity/semanticTests/test_issue_16337.sol Added minimal test case (though it doesn't reproduce the multi-source scenario from the issue)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 882 to 885
break;
}
if (!contractName.empty())
break;
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The fallback logic returns the first contract found across all sources, which is inconsistent with the function name lastContractName and its original behavior. When the specified source is not found, the fallback should iterate through all contracts across all sources (like the original code when _sourceName is nullopt) to return the last contract, not break after finding the first one. Remove the break statements on lines 882 and 885 to maintain consistency with the original behavior.

Suggested change
break;
}
if (!contractName.empty())
break;
}

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed.
I will refactor lastContractName() so it first tries the requested source when available, and falls back to scanning all sources when the requested source is missing or has no contracts.
This keeps normal behavior unchanged while preventing the interactive-update crash path.

Comment on lines 1 to 5
contract TestContract {
function getValue() public pure returns (uint256) {
return 42;
}
}
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The test case doesn't reproduce the actual issue described in #16337. The issue occurs with multi-source files where the mainSourceFile name doesn't match the key in m_sources (e.g., module_function_deployed.sol with mod.sol and main.sol). This single-file test won't trigger the fallback logic path that was added to fix the crash. Consider adding a test similar to module_function_deployed.sol structure to verify the fix works correctly.

Suggested change
contract TestContract {
function getValue() public pure returns (uint256) {
return 42;
}
}
// ==== Source: mod.sol ====
library Mod {
function value() internal pure returns (uint256) {
return 42;
}
}
// ==== Source: main.sol ====
import "mod.sol";
contract TestContract {
function getValue() public pure returns (uint256) {
return Mod.value();
}
}

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion.
I will also update the test to be explicitly multi-source (==== Source: ... ==== with an import) so it now validates the same class of scenario behind issue #16337, not just a single-file path.

Comment on lines 1 to 7
contract TestContract {
function getValue() public pure returns (uint256) {
return 42;
}
}
// ----
// getValue() -> 0x2a
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

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

The test file is placed in the root of semanticTests directory, but all other semantic tests are organized into subdirectories. Since the issue being tested is related to multi-source compilation (as evident from the referenced module_function_deployed.sol), consider moving this test to the multiSource subdirectory for better organization and consistency with the existing test structure.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, agreed. Sorry for that.
I will move this regression test under semanticTests/multiSource/ to match the existing semantic test organization and keep the multi-source related coverage grouped consistently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

isoltest crashes on interactive update in module_function_deployed.sol

1 participant

Comments