Report an error if immutables not assigned

This commit is contained in:
a3d4 2020-07-21 15:20:05 +02:00
parent 336fe94422
commit 5b54cfbed3
7 changed files with 48 additions and 8 deletions

View File

@ -34,6 +34,7 @@ Bugfixes:
* SMTChecker: Fix internal error when assigning to a 1-tuple.
* State Mutability: Constant public state variables are considered ``pure`` functions.
* Type Checker: Fixing deduction issues on function types when function call has named arguments.
* Immutables: Fix internal compiler error when immutables are not assigned.
### 0.6.12 (2020-07-22)

View File

@ -30,6 +30,8 @@
#include <libevmasm/ConstantOptimiser.h>
#include <libevmasm/GasMeter.h>
#include <liblangutil/Exceptions.h>
#include <fstream>
#include <json/json.h>
@ -699,12 +701,10 @@ LinkerObject const& Assembly::assemble() const
}
}
assertThrow(
immutableReferencesBySub.empty(),
AssemblyException,
"Some immutables were read from but never assigned."
);
if (!immutableReferencesBySub.empty())
throw
langutil::Error(1284_error, langutil::Error::Type::CodeGenerationError) <<
util::errinfo_comment("Some immutables were read from but never assigned, possibly because of optimization.");
if (!m_subs.empty() || !m_data.empty() || !m_auxiliaryData.empty())
// Append an INVALID here to help tests find miscompilation.

View File

@ -33,6 +33,9 @@ Error::Error(ErrorId _errorId, Type _type, SourceLocation const& _location, stri
{
switch (m_type)
{
case Type::CodeGenerationError:
m_typeName = "CodeGenerationError";
break;
case Type::DeclarationError:
m_typeName = "DeclarationError";
break;

View File

@ -78,6 +78,7 @@ class Error: virtual public util::Exception
public:
enum class Type
{
CodeGenerationError,
DeclarationError,
DocstringParsingError,
ParserError,

View File

@ -516,7 +516,17 @@ bool CompilerStack::compile()
if (auto contract = dynamic_cast<ContractDefinition const*>(node.get()))
if (isRequestedContract(*contract))
{
compileContract(*contract, otherCompilers);
try
{
compileContract(*contract, otherCompilers);
}
catch (Error const& _error)
{
if (_error.type() != Error::Type::CodeGenerationError)
throw;
m_errorReporter.error(_error.errorId(), _error.type(), SourceLocation(), _error.what());
return false;
}
if (m_generateIR || m_generateEwasm)
generateIR(*contract);
if (m_generateEwasm)

View File

@ -74,7 +74,19 @@ void SyntaxTest::parseAndAnalyze()
try
{
if (!compiler().compile())
BOOST_THROW_EXCEPTION(runtime_error("Compilation failed even though analysis was successful."));
{
ErrorList const& errors = compiler().errors();
auto codeGeneretionErrorCount = count_if(errors.cbegin(), errors.cend(), [](auto const& error) {
return error->type() == Error::Type::CodeGenerationError;
});
auto errorCount = count_if(errors.cbegin(), errors.cend(), [](auto const& error) {
return error->type() != Error::Type::Warning;
});
// failing compilation after successful analysis is a rare case,
// it assumes that errors contain exactly one error, and the error is of type Error::Type::CodeGenerationError
if (codeGeneretionErrorCount != 1 || errorCount != 1)
BOOST_THROW_EXCEPTION(runtime_error("Compilation failed even though analysis was successful."));
}
}
catch (UnimplementedFeatureError const& _e)
{

View File

@ -0,0 +1,13 @@
contract C {
uint immutable x;
constructor() {
x = 0;
while (true)
{}
}
function f() external view returns(uint) { return x; }
}
// ====
// optimize-yul: true
// ----
// CodeGenerationError 1284: Some immutables were read from but never assigned, possibly because of optimization.