aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/analysis
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/analysis')
-rw-r--r--libsolidity/analysis/StaticAnalyzer.cpp36
-rw-r--r--libsolidity/analysis/SyntaxChecker.cpp17
-rw-r--r--libsolidity/analysis/TypeChecker.cpp106
-rw-r--r--libsolidity/analysis/TypeChecker.h2
-rw-r--r--libsolidity/analysis/ViewPureChecker.cpp38
-rw-r--r--libsolidity/analysis/ViewPureChecker.h1
6 files changed, 48 insertions, 152 deletions
diff --git a/libsolidity/analysis/StaticAnalyzer.cpp b/libsolidity/analysis/StaticAnalyzer.cpp
index c7440565..323282ca 100644
--- a/libsolidity/analysis/StaticAnalyzer.cpp
+++ b/libsolidity/analysis/StaticAnalyzer.cpp
@@ -150,36 +150,18 @@ bool StaticAnalyzer::visit(ExpressionStatement const& _statement)
bool StaticAnalyzer::visit(MemberAccess const& _memberAccess)
{
- bool const v050 = m_currentContract->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
-
if (MagicType const* type = dynamic_cast<MagicType const*>(_memberAccess.expression().annotation().type.get()))
{
if (type->kind() == MagicType::Kind::Message && _memberAccess.memberName() == "gas")
- {
- if (v050)
- m_errorReporter.typeError(
- _memberAccess.location(),
- "\"msg.gas\" has been deprecated in favor of \"gasleft()\""
- );
- else
- m_errorReporter.warning(
- _memberAccess.location(),
- "\"msg.gas\" has been deprecated in favor of \"gasleft()\""
- );
- }
- if (type->kind() == MagicType::Kind::Block && _memberAccess.memberName() == "blockhash")
- {
- if (v050)
- m_errorReporter.typeError(
- _memberAccess.location(),
- "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\""
- );
- else
- m_errorReporter.warning(
- _memberAccess.location(),
- "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\""
- );
- }
+ m_errorReporter.typeError(
+ _memberAccess.location(),
+ "\"msg.gas\" has been deprecated in favor of \"gasleft()\""
+ );
+ else if (type->kind() == MagicType::Kind::Block && _memberAccess.memberName() == "blockhash")
+ m_errorReporter.typeError(
+ _memberAccess.location(),
+ "\"block.blockhash()\" has been deprecated in favor of \"blockhash()\""
+ );
}
if (m_nonPayablePublic && !m_library)
diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp
index c408b393..63f8fac3 100644
--- a/libsolidity/analysis/SyntaxChecker.cpp
+++ b/libsolidity/analysis/SyntaxChecker.cpp
@@ -192,15 +192,9 @@ bool SyntaxChecker::visit(Throw const& _throwStatement)
bool SyntaxChecker::visit(UnaryOperation const& _operation)
{
- bool const v050 = m_sourceUnit->annotation().experimentalFeatures.count(ExperimentalFeature::V050);
-
if (_operation.getOperator() == Token::Add)
- {
- if (v050)
- m_errorReporter.syntaxError(_operation.location(), "Use of unary + is deprecated.");
- else
- m_errorReporter.warning(_operation.location(), "Use of unary + is deprecated.");
- }
+ m_errorReporter.syntaxError(_operation.location(), "Use of unary + is disallowed.");
+
return true;
}
@@ -262,14 +256,9 @@ bool SyntaxChecker::visit(FunctionTypeName const& _node)
bool SyntaxChecker::visit(VariableDeclaration const& _declaration)
{
- bool const v050 = m_sourceUnit->annotation().experimentalFeatures.count(ExperimentalFeature::V050);
-
if (!_declaration.typeName())
{
- if (v050)
- m_errorReporter.syntaxError(_declaration.location(), "Use of the \"var\" keyword is deprecated.");
- else
- m_errorReporter.warning(_declaration.location(), "Use of the \"var\" keyword is deprecated.");
+ m_errorReporter.syntaxError(_declaration.location(), "Use of the \"var\" keyword is disallowed.");
}
return true;
}
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index 500d4123..071ac9fe 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -123,10 +123,7 @@ bool TypeChecker::visit(ContractDefinition const& _contract)
m_errorReporter.typeError(function->parameterList().location(), "Fallback function cannot take parameters.");
if (!function->returnParameters().empty())
m_errorReporter.typeError(function->returnParameterList()->location(), "Fallback function cannot return values.");
- if (
- _contract.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050) &&
- function->visibility() != FunctionDefinition::Visibility::External
- )
+ if (function->visibility() != FunctionDefinition::Visibility::External)
m_errorReporter.typeError(function->location(), "Fallback function must be defined as \"external\".");
}
@@ -335,8 +332,6 @@ void TypeChecker::annotateBaseConstructorArguments(
ASTNode const* _argumentNode
)
{
- bool const v050 = _currentContract.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
-
solAssert(_baseConstructor, "");
solAssert(_argumentNode, "");
@@ -365,18 +360,11 @@ void TypeChecker::annotateBaseConstructorArguments(
ssl.append("Second constructor call is here: ", previousNode->location());
}
- if (v050)
- m_errorReporter.declarationError(
- *mainLocation,
- ssl,
- "Base constructor arguments given twice."
- );
- else
- m_errorReporter.warning(
- *mainLocation,
- "Base constructor arguments given twice.",
- ssl
- );
+ m_errorReporter.declarationError(
+ *mainLocation,
+ ssl,
+ "Base constructor arguments given twice."
+ );
}
}
@@ -460,7 +448,7 @@ void TypeChecker::overrideError(FunctionDefinition const& function, FunctionDefi
{
m_errorReporter.typeError(
function.location(),
- SecondarySourceLocation().append("Overriden function is here:", super.location()),
+ SecondarySourceLocation().append("Overridden function is here:", super.location()),
message
);
}
@@ -758,19 +746,10 @@ bool TypeChecker::visit(VariableDeclaration const& _variable)
if (!_variable.value())
m_errorReporter.typeError(_variable.location(), "Uninitialized \"constant\" variable.");
else if (!_variable.value()->annotation().isPure)
- {
- if (_variable.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050))
- m_errorReporter.typeError(
- _variable.value()->location(),
- "Initial value for constant variable has to be compile-time constant."
- );
- else
- m_errorReporter.warning(
- _variable.value()->location(),
- "Initial value for constant variable has to be compile-time constant. "
- "This will fail to compile with the next breaking version change."
- );
- }
+ m_errorReporter.typeError(
+ _variable.value()->location(),
+ "Initial value for constant variable has to be compile-time constant."
+ );
}
if (!_variable.isStateVariable())
{
@@ -1091,10 +1070,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
if (varDecl.referenceLocation() == VariableDeclaration::Location::Default)
errorText += " Did you mean '<type> memory " + varDecl.name() + "'?";
solAssert(m_scope, "");
- if (v050)
- m_errorReporter.declarationError(varDecl.location(), errorText);
- else
- m_errorReporter.warning(varDecl.location(), errorText);
+ m_errorReporter.declarationError(varDecl.location(), errorText);
}
}
else if (dynamic_cast<MappingType const*>(type(varDecl).get()))
@@ -1355,7 +1331,6 @@ bool TypeChecker::visit(Conditional const& _conditional)
bool TypeChecker::visit(Assignment const& _assignment)
{
- bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
requireLValue(_assignment.leftHandSide());
TypePointer t = type(_assignment.leftHandSide());
_assignment.annotation().type = t;
@@ -1372,25 +1347,8 @@ bool TypeChecker::visit(Assignment const& _assignment)
expectType(_assignment.rightHandSide(), *tupleType);
// expectType does not cause fatal errors, so we have to check again here.
- if (TupleType const* rhsType = dynamic_cast<TupleType const*>(type(_assignment.rightHandSide()).get()))
- {
+ if (dynamic_cast<TupleType const*>(type(_assignment.rightHandSide()).get()))
checkDoubleStorageAssignment(_assignment);
- // @todo For 0.5.0, this code shoud move to TupleType::isImplicitlyConvertibleTo,
- // but we cannot do it right now.
- if (rhsType->components().size() != tupleType->components().size())
- {
- string message =
- "Different number of components on the left hand side (" +
- toString(tupleType->components().size()) +
- ") than on the right hand side (" +
- toString(rhsType->components().size()) +
- ").";
- if (v050)
- m_errorReporter.typeError(_assignment.location(), message);
- else
- m_errorReporter.warning(_assignment.location(), message);
- }
- }
}
else if (t->category() == Type::Category::Mapping)
{
@@ -1447,14 +1405,12 @@ bool TypeChecker::visit(TupleExpression const& _tuple)
}
else
{
- bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
bool isPure = true;
TypePointer inlineArrayType;
for (size_t i = 0; i < components.size(); ++i)
{
- // Outside of an lvalue-context, the only situation where a component can be empty is (x,).
- if (!components[i] && !(i == 1 && components.size() == 2))
+ if (!components[i])
m_errorReporter.fatalTypeError(_tuple.location(), "Tuple component cannot be empty.");
else if (components[i])
{
@@ -1466,10 +1422,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple)
{
if (_tuple.isInlineArray())
m_errorReporter.fatalTypeError(components[i]->location(), "Array component cannot be empty.");
- if (v050)
- m_errorReporter.fatalTypeError(components[i]->location(), "Tuple component cannot be empty.");
- else
- m_errorReporter.warning(components[i]->location(), "Tuple component cannot be empty.");
+ m_errorReporter.typeError(components[i]->location(), "Tuple component cannot be empty.");
}
// Note: code generation will visit each of the expression even if they are not assigned from.
@@ -1507,11 +1460,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple)
if (components.size() == 1)
_tuple.annotation().type = type(*components[0]);
else
- {
- if (components.size() == 2 && !components[1])
- types.pop_back();
_tuple.annotation().type = make_shared<TupleType>(types);
- }
}
}
@@ -1856,7 +1805,7 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
if (functionType->takesArbitraryParameters())
m_errorReporter.typeError(
_functionCall.location(),
- "Named arguments cannnot be used for functions that take arbitrary parameters."
+ "Named arguments cannot be used for functions that take arbitrary parameters."
);
else if (parameterNames.size() > argumentNames.size())
m_errorReporter.typeError(_functionCall.location(), "Some argument names are missing.");
@@ -2275,11 +2224,9 @@ void TypeChecker::endVisit(ElementaryTypeNameExpression const& _expr)
void TypeChecker::endVisit(Literal const& _literal)
{
- bool const v050 = m_scope->sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050);
-
if (_literal.looksLikeAddress())
{
- // Assign type here if it even looks like an address. This prevents double error in 050 mode for invalid address
+ // Assign type here if it even looks like an address. This prevents double errors for invalid addresses
_literal.annotation().type = make_shared<IntegerType>(160, IntegerType::Modifier::Address);
string msg;
@@ -2306,20 +2253,11 @@ void TypeChecker::endVisit(Literal const& _literal)
}
if (_literal.isHexNumber() && _literal.subDenomination() != Literal::SubDenomination::None)
- {
- if (v050)
- m_errorReporter.fatalTypeError(
- _literal.location(),
- "Hexadecimal numbers cannot be used with unit denominations. "
- "You can use an expression of the form \"0x1234 * 1 day\" instead."
- );
- else
- m_errorReporter.warning(
- _literal.location(),
- "Hexadecimal numbers with unit denominations are deprecated. "
- "You can use an expression of the form \"0x1234 * 1 day\" instead."
- );
- }
+ m_errorReporter.fatalTypeError(
+ _literal.location(),
+ "Hexadecimal numbers cannot be used with unit denominations. "
+ "You can use an expression of the form \"0x1234 * 1 day\" instead."
+ );
if (_literal.subDenomination() == Literal::SubDenomination::Year)
m_errorReporter.typeError(
diff --git a/libsolidity/analysis/TypeChecker.h b/libsolidity/analysis/TypeChecker.h
index 2245abd6..8dc6b376 100644
--- a/libsolidity/analysis/TypeChecker.h
+++ b/libsolidity/analysis/TypeChecker.h
@@ -68,7 +68,7 @@ private:
void checkContractDuplicateFunctions(ContractDefinition const& _contract);
void checkContractDuplicateEvents(ContractDefinition const& _contract);
void checkContractIllegalOverrides(ContractDefinition const& _contract);
- /// Reports a type error with an appropiate message if overriden function signature differs.
+ /// Reports a type error with an appropriate message if overridden function signature differs.
/// Also stores the direct super function in the AST annotations.
void checkFunctionOverride(FunctionDefinition const& function, FunctionDefinition const& super);
void overrideError(FunctionDefinition const& function, FunctionDefinition const& super, std::string message);
diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp
index 107eb3aa..18c642c3 100644
--- a/libsolidity/analysis/ViewPureChecker.cpp
+++ b/libsolidity/analysis/ViewPureChecker.cpp
@@ -116,31 +116,22 @@ private:
bool ViewPureChecker::check()
{
- // The bool means "enforce view with errors".
- vector<pair<ContractDefinition const*, bool>> contracts;
+ vector<ContractDefinition const*> contracts;
for (auto const& node: m_ast)
{
SourceUnit const* source = dynamic_cast<SourceUnit const*>(node.get());
solAssert(source, "");
- bool enforceView = source->annotation().experimentalFeatures.count(ExperimentalFeature::V050);
- for (ContractDefinition const* c: source->filteredNodes<ContractDefinition>(source->nodes()))
- contracts.emplace_back(c, enforceView);
+ contracts += source->filteredNodes<ContractDefinition>(source->nodes());
}
// Check modifiers first to infer their state mutability.
for (auto const& contract: contracts)
- {
- m_enforceViewWithError = contract.second;
- for (ModifierDefinition const* mod: contract.first->functionModifiers())
+ for (ModifierDefinition const* mod: contract->functionModifiers())
mod->accept(*this);
- }
for (auto const& contract: contracts)
- {
- m_enforceViewWithError = contract.second;
- contract.first->accept(*this);
- }
+ contract->accept(*this);
return !m_errors;
}
@@ -232,17 +223,20 @@ void ViewPureChecker::reportMutability(StateMutability _mutability, SourceLocati
{
if (m_currentFunction && m_currentFunction->stateMutability() < _mutability)
{
- string text;
if (_mutability == StateMutability::View)
- text =
+ m_errorReporter.typeError(
+ _location,
"Function declared as pure, but this expression (potentially) reads from the "
- "environment or state and thus requires \"view\".";
+ "environment or state and thus requires \"view\"."
+ );
else if (_mutability == StateMutability::NonPayable)
- text =
+ m_errorReporter.typeError(
+ _location,
"Function declared as " +
stateMutabilityToString(m_currentFunction->stateMutability()) +
", but this expression (potentially) modifies the state and thus "
- "requires non-payable (the default) or payable.";
+ "requires non-payable (the default) or payable."
+ );
else
solAssert(false, "");
@@ -251,13 +245,7 @@ void ViewPureChecker::reportMutability(StateMutability _mutability, SourceLocati
m_currentFunction->stateMutability() == StateMutability::Pure,
""
);
- if (!m_enforceViewWithError && m_currentFunction->stateMutability() == StateMutability::View)
- m_errorReporter.warning(_location, text);
- else
- {
- m_errors = true;
- m_errorReporter.typeError(_location, text);
- }
+ m_errors = true;
}
if (_mutability > m_currentBestMutability)
m_currentBestMutability = _mutability;
diff --git a/libsolidity/analysis/ViewPureChecker.h b/libsolidity/analysis/ViewPureChecker.h
index 0b882cd8..3db52e7e 100644
--- a/libsolidity/analysis/ViewPureChecker.h
+++ b/libsolidity/analysis/ViewPureChecker.h
@@ -71,7 +71,6 @@ private:
ErrorReporter& m_errorReporter;
bool m_errors = false;
- bool m_enforceViewWithError = false;
StateMutability m_currentBestMutability = StateMutability::Payable;
FunctionDefinition const* m_currentFunction = nullptr;
std::map<ModifierDefinition const*, StateMutability> m_inferredMutability;