Merge remote-tracking branch 'origin/develop' into breaking

This commit is contained in:
chriseth
2020-11-03 14:05:14 +01:00
206 changed files with 1420 additions and 862 deletions
@@ -450,7 +450,7 @@ void ContractLevelChecker::checkLibraryRequirements(ContractDefinition const& _c
void ContractLevelChecker::checkBaseABICompatibility(ContractDefinition const& _contract)
{
if (_contract.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::ABIEncoderV2))
if (*_contract.sourceUnit().annotation().useABICoderV2)
return;
if (_contract.isLibrary())
@@ -469,7 +469,7 @@ void ContractLevelChecker::checkBaseABICompatibility(ContractDefinition const& _
{
solAssert(func.second->hasDeclaration(), "Function has no declaration?!");
if (!func.second->declaration().sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::ABIEncoderV2))
if (!*func.second->declaration().sourceUnit().annotation().useABICoderV2)
continue;
auto const& currentLoc = func.second->declaration().location();
@@ -489,9 +489,9 @@ void ContractLevelChecker::checkBaseABICompatibility(ContractDefinition const& _
errors,
std::string("Contract \"") +
_contract.name() +
"\" does not use ABIEncoderV2 but wants to inherit from a contract " +
"\" does not use ABI coder v2 but wants to inherit from a contract " +
"which uses types that require it. " +
"Use \"pragma experimental ABIEncoderV2;\" for the inheriting contract as well to enable the feature."
"Use \"pragma abicoder v2;\" for the inheriting contract as well to enable the feature."
);
}
+39
View File
@@ -73,6 +73,8 @@ void SyntaxChecker::endVisit(SourceUnit const& _sourceUnit)
// when reporting the warning, print the source name only
m_errorReporter.warning(3420_error, {-1, -1, _sourceUnit.location().source}, errorString);
}
if (!m_sourceUnit->annotation().useABICoderV2.set())
m_sourceUnit->annotation().useABICoderV2 = false;
m_sourceUnit = nullptr;
}
@@ -113,9 +115,45 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma)
m_sourceUnit->annotation().experimentalFeatures.insert(feature);
if (!ExperimentalFeatureWithoutWarning.count(feature))
m_errorReporter.warning(2264_error, _pragma.location(), "Experimental features are turned on. Do not use experimental features on live deployments.");
if (feature == ExperimentalFeature::ABIEncoderV2)
{
if (m_sourceUnit->annotation().useABICoderV2.set())
{
if (!*m_sourceUnit->annotation().useABICoderV2)
m_errorReporter.syntaxError(
8273_error,
_pragma.location(),
"ABI coder v1 has already been selected through \"pragma abicoder v1\"."
);
}
else
m_sourceUnit->annotation().useABICoderV2 = true;
}
}
}
}
else if (_pragma.literals()[0] == "abicoder")
{
solAssert(m_sourceUnit, "");
if (
_pragma.literals().size() != 2 ||
!set<string>{"v1", "v2"}.count(_pragma.literals()[1])
)
m_errorReporter.syntaxError(
2745_error,
_pragma.location(),
"Expected either \"pragma abicoder v1\" or \"pragma abicoder v2\"."
);
else if (m_sourceUnit->annotation().useABICoderV2.set())
m_errorReporter.syntaxError(
3845_error,
_pragma.location(),
"ABI coder has already been selected for this source unit."
);
else
m_sourceUnit->annotation().useABICoderV2 = (_pragma.literals()[1] == "v2");
}
else if (_pragma.literals()[0] == "solidity")
{
vector<Token> tokens(_pragma.tokens().begin() + 1, _pragma.tokens().end());
@@ -135,6 +173,7 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma)
}
else
m_errorReporter.syntaxError(4936_error, _pragma.location(), "Unknown pragma \"" + _pragma.literals()[0] + "\"");
return true;
}
+1
View File
@@ -39,6 +39,7 @@ namespace solidity::frontend
* - issues deprecation warnings for unary '+'
* - issues deprecation warning for throw
* - whether the msize instruction is used and the Yul optimizer is enabled at the same time.
* - selection of the ABI coder through pragmas.
*/
class SyntaxChecker: private ASTConstVisitor
{
+19 -18
View File
@@ -398,13 +398,13 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
m_errorReporter.typeError(4103_error, _var.location(), message);
}
else if (
!experimentalFeatureActive(ExperimentalFeature::ABIEncoderV2) &&
!useABICoderV2() &&
!typeSupportedByOldABIEncoder(*type(_var), _function.libraryFunction())
)
{
string message =
"This type is only supported in ABIEncoderV2. "
"Use \"pragma experimental ABIEncoderV2;\" to enable the feature.";
"This type is only supported in ABI coder v2. "
"Use \"pragma abicoder v2;\" to enable the feature.";
if (_function.isConstructor())
message +=
" Alternatively, make the contract abstract and supply the "
@@ -570,7 +570,7 @@ bool TypeChecker::visit(VariableDeclaration const& _variable)
else if (_variable.visibility() >= Visibility::Public)
{
FunctionType getter(_variable);
if (!experimentalFeatureActive(ExperimentalFeature::ABIEncoderV2))
if (!useABICoderV2())
{
vector<string> unsupportedTypes;
for (auto const& param: getter.parameterTypes() + getter.returnParameterTypes())
@@ -580,9 +580,9 @@ bool TypeChecker::visit(VariableDeclaration const& _variable)
m_errorReporter.typeError(
2763_error,
_variable.location(),
"The following types are only supported for getters in ABIEncoderV2: " +
"The following types are only supported for getters in ABI coder v2: " +
joinHumanReadable(unsupportedTypes) +
". Either remove \"public\" or use \"pragma experimental ABIEncoderV2;\" to enable the feature."
". Either remove \"public\" or use \"pragma abicoder v2;\" to enable the feature."
);
}
if (!getter.interfaceFunctionType())
@@ -695,14 +695,14 @@ bool TypeChecker::visit(EventDefinition const& _eventDef)
if (!type(*var)->interfaceType(false))
m_errorReporter.typeError(3417_error, var->location(), "Internal or recursive type is not allowed as event parameter type.");
if (
!experimentalFeatureActive(ExperimentalFeature::ABIEncoderV2) &&
!useABICoderV2() &&
!typeSupportedByOldABIEncoder(*type(*var), false /* isLibrary */)
)
m_errorReporter.typeError(
3061_error,
var->location(),
"This type is only supported in ABIEncoderV2. "
"Use \"pragma experimental ABIEncoderV2;\" to enable the feature."
"This type is only supported in ABI coder v2. "
"Use \"pragma abicoder v2;\" to enable the feature."
);
}
if (_eventDef.isAnonymous() && numIndexed > 4)
@@ -1900,7 +1900,7 @@ void TypeChecker::typeCheckABIEncodeFunctions(
bool const isPacked = _functionType->kind() == FunctionType::Kind::ABIEncodePacked;
solAssert(_functionType->padArguments() != isPacked, "ABI function with unexpected padding");
bool const abiEncoderV2 = experimentalFeatureActive(ExperimentalFeature::ABIEncoderV2);
bool const abiEncoderV2 = useABICoderV2();
// Check for named arguments
if (!_functionCall.names().empty())
@@ -2192,7 +2192,7 @@ void TypeChecker::typeCheckFunctionGeneralChecks(
_functionType->kind() == FunctionType::Kind::Creation ||
_functionType->kind() == FunctionType::Kind::Event;
if (callRequiresABIEncoding && !experimentalFeatureActive(ExperimentalFeature::ABIEncoderV2))
if (callRequiresABIEncoding && !useABICoderV2())
{
solAssert(!isVariadic, "");
solAssert(parameterTypes.size() == arguments.size(), "");
@@ -2208,8 +2208,8 @@ void TypeChecker::typeCheckFunctionGeneralChecks(
2443_error,
paramArgMap[i]->location(),
"The type of this parameter, " + parameterTypes[i]->toString(true) + ", "
"is only supported in ABIEncoderV2. "
"Use \"pragma experimental ABIEncoderV2;\" to enable the feature."
"is only supported in ABI coder v2. "
"Use \"pragma abicoder v2;\" to enable the feature."
);
}
@@ -2222,8 +2222,8 @@ void TypeChecker::typeCheckFunctionGeneralChecks(
2428_error,
_functionCall.location(),
"The type of return parameter " + toString(i + 1) + ", " + returnParameterTypes[i]->toString(true) + ", "
"is only supported in ABIEncoderV2. "
"Use \"pragma experimental ABIEncoderV2;\" to enable the feature."
"is only supported in ABI coder v2. "
"Use \"pragma abicoder v2;\" to enable the feature."
);
}
}
@@ -2340,7 +2340,7 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
{
returnTypes = typeCheckABIDecodeAndRetrieveReturnType(
_functionCall,
experimentalFeatureActive(ExperimentalFeature::ABIEncoderV2)
useABICoderV2()
);
break;
}
@@ -3414,10 +3414,11 @@ void TypeChecker::requireLValue(Expression const& _expression, bool _ordinaryAss
m_errorReporter.typeError(errorId, _expression.location(), description);
}
bool TypeChecker::experimentalFeatureActive(ExperimentalFeature _feature) const
bool TypeChecker::useABICoderV2() const
{
solAssert(m_currentSourceUnit, "");
if (m_currentContract)
solAssert(m_currentSourceUnit == &m_currentContract->sourceUnit(), "");
return m_currentSourceUnit->annotation().experimentalFeatures.count(_feature);
return *m_currentSourceUnit->annotation().useABICoderV2;
}
+1 -1
View File
@@ -168,7 +168,7 @@ private:
/// Runs type checks on @a _expression to infer its type and then checks that it is an LValue.
void requireLValue(Expression const& _expression, bool _ordinaryAssignment);
bool experimentalFeatureActive(ExperimentalFeature _feature) const;
bool useABICoderV2() const;
/// @returns the current scope that can have function or type definitions.
/// This is either a contract or a source unit.