Check for import without pragma and add cmdline test

This commit is contained in:
Nikola Matic 2022-10-18 16:10:33 +02:00
parent ad5d528255
commit 2a07761fc6
9 changed files with 50 additions and 12 deletions

View File

@ -108,7 +108,7 @@ public:
void populateHomonyms(std::back_insert_iterator<Homonyms> _it) const;
private:
/// Disables autoPopulateStdlib in _settinsg if "pragma stdlib" is active in m_selfNode.
/// Disables autoPopulateStdlib in _settings if "pragma stdlib" is active in m_selfNode.
void updateSettingsBasedOnStdlibPragma(ResolvingSettings& _settings) const;
ASTNode const* m_selfNode = nullptr;

View File

@ -181,12 +181,6 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma)
else if (_pragma.literals()[0] == "stdlib")
{
solAssert(m_sourceUnit, "");
if (m_evmVersion < EVMVersion::constantinople())
m_errorReporter.syntaxError(
6634_error,
_pragma.location(),
"\"pragma stdlib\" requires Constantinople EVM version at the minimum."
);
m_sourceUnit->annotation().useStdlib = true;
}
else

View File

@ -309,8 +309,13 @@ public:
int64_t _id,
SourceLocation const& _location,
std::vector<Token> _tokens,
std::vector<ASTString> _literals
): ASTNode(_id, _location), m_tokens(std::move(_tokens)), m_literals(std::move(_literals))
std::vector<ASTString> _literals,
bool useStdLib = false
):
ASTNode(_id, _location),
m_tokens(std::move(_tokens)),
m_literals(std::move(_literals)),
m_useStdLib(useStdLib)
{}
void accept(ASTVisitor& _visitor) override;
@ -319,12 +324,16 @@ public:
std::vector<Token> const& tokens() const { return m_tokens; }
std::vector<ASTString> const& literals() const { return m_literals; }
bool useStdLib() const { return m_useStdLib; }
private:
/// Sequence of tokens following the "pragma" keyword.
std::vector<Token> m_tokens;
/// Sequence of literals following the "pragma" keyword.
std::vector<ASTString> m_literals;
/// Indicates whether the standard library has been activated via this pragma
bool const m_useStdLib;
};
/**

View File

@ -84,6 +84,7 @@
#include <boost/algorithm/string/replace.hpp>
#include <range/v3/view/concat.hpp>
#include <range/v3/algorithm/any_of.hpp>
#include <utility>
#include <map>
@ -374,6 +375,20 @@ bool CompilerStack::parse()
auto it = solidity::solstdlib::sources.find(import->path());
if (it != solidity::solstdlib::sources.end())
{
auto useStdLib = [&]() {
auto const pragmas = ASTNode::filteredNodes<PragmaDirective>(source.ast->nodes());
return ranges::any_of(pragmas, [](PragmaDirective const* pragma) {
return pragma->useStdLib();
});
};
if (!useStdLib())
solThrow(
CompilerError,
"Given source file not found: " + import->path() + ". " +
"If you want to enable the standard library, you may do so with 'pragma stdlib;'."
);
auto [name, content] = *it;
m_sources[name].charStream = make_unique<CharStream>(content, name);
sourcesToParse.push_back(name);

View File

@ -210,6 +210,7 @@ ASTPointer<PragmaDirective> Parser::parsePragmaDirective()
expectToken(Token::Pragma);
vector<string> literals;
vector<Token> tokens;
bool useStdLib = false;
do
{
Token token = m_scanner->currentToken();
@ -229,7 +230,18 @@ ASTPointer<PragmaDirective> Parser::parsePragmaDirective()
nodeFactory.markEndPosition();
expectToken(Token::Semicolon);
if (literals.size() >= 1 && literals[0] == "solidity")
if (!literals.empty() && literals[0] == "stdlib")
{
if (m_evmVersion < EVMVersion::constantinople())
m_errorReporter.syntaxError(
6634_error,
nodeFactory.location(),
"\"pragma stdlib\" requires Constantinople EVM version at the minimum."
);
useStdLib = true;
}
if (!literals.empty() && literals[0] == "solidity")
{
parsePragmaVersion(
nodeFactory.location(),
@ -238,7 +250,7 @@ ASTPointer<PragmaDirective> Parser::parsePragmaDirective()
);
}
return nodeFactory.createNode<PragmaDirective>(tokens, literals);
return nodeFactory.createNode<PragmaDirective>(tokens, literals, useStdLib);
}
ASTPointer<ImportDirective> Parser::parseImportDirective()
@ -1118,7 +1130,6 @@ ASTPointer<TypeName> Parser::parseTypeName()
unsigned secondSize;
tie(firstSize, secondSize) = m_scanner->currentTokenInfo();
ElementaryTypeNameToken elemTypeName(token, firstSize, secondSize);
ASTNodeFactory nodeFactory(*this);
nodeFactory.markEndPosition();
advance();
auto stateMutability = elemTypeName.token() == Token::Address

View File

@ -0,0 +1 @@
Error: Given source file not found: std/cryptography.sol. If you want to enable the standard library, you may do so with 'pragma stdlib;'.

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,7 @@
import { ecrecover } from "std/cryptography.sol";
contract C {
function f(bytes32 h, uint8 v, bytes32 r, bytes32 s) public returns (address addr) {
return ecrecover(h, v, r, s);
}
}