From 35908c602b775863a198bcb09e069e1bb291b5f8 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 2 Dec 2020 18:00:04 +0100 Subject: [PATCH] Modifiers for constructors. --- libsolidity/codegen/ir/IRGenerator.cpp | 42 ++++++++++++++----- ..._calling_functions_in_creation_context.sol | 2 + .../function_modifier_for_constructor.sol | 3 +- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index fef88aeb7..ac7475a7a 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -639,7 +639,6 @@ string IRGenerator::initStateVariables(ContractDefinition const& _contract) void IRGenerator::generateImplicitConstructors(ContractDefinition const& _contract) { - // TODO reset local variables somewhere here. auto listAllParams = [&]( map> const& baseParams) -> vector { @@ -656,6 +655,7 @@ void IRGenerator::generateImplicitConstructors(ContractDefinition const& _contra ContractDefinition const* contract = _contract.annotation().linearizedBaseContracts[i]; baseConstructorParams.erase(contract); + m_context.resetLocalVariables(); m_context.functionCollector().createFunction(IRNames::implicitConstructor(*contract), [&]() { Whiskers t(R"( function () { @@ -667,16 +667,8 @@ void IRGenerator::generateImplicitConstructors(ContractDefinition const& _contra )"); vector params; if (contract->constructor()) - { - for (auto const& modifierInvocation: contract->constructor()->modifiers()) - // This can be ContractDefinition too for super arguments. That is supported. - solUnimplementedAssert( - !dynamic_cast(modifierInvocation->name().annotation().referencedDeclaration), - "Modifiers not implemented yet." - ); for (ASTPointer const& varDecl: contract->constructor()->parameters()) params += m_context.addLocalVariable(*varDecl).stackSlots(); - } t("params", joinHumanReadable(params)); vector baseParams = listAllParams(baseConstructorParams); t("baseParams", joinHumanReadable(baseParams)); @@ -695,7 +687,37 @@ void IRGenerator::generateImplicitConstructors(ContractDefinition const& _contra else t("hasNextConstructor", false); t("initStateVariables", initStateVariables(*contract)); - t("userDefinedConstructorBody", contract->constructor() ? generate(contract->constructor()->body()) : ""); + string body; + if (FunctionDefinition const* constructor = contract->constructor()) + { + vector realModifiers; + for (auto const& modifierInvocation: constructor->modifiers()) + // Filter out the base constructor calls + if (dynamic_cast(modifierInvocation->name().annotation().referencedDeclaration)) + realModifiers.emplace_back(modifierInvocation.get()); + if (realModifiers.empty()) + body = generate(constructor->body()); + else + { + for (size_t i = 0; i < realModifiers.size(); ++i) + { + ModifierInvocation const& modifier = *realModifiers.at(i); + string next = + i + 1 < realModifiers.size() ? + IRNames::modifierInvocation(*realModifiers.at(i + 1)) : + IRNames::functionWithModifierInner(*constructor); + generateModifier(modifier, *constructor, next); + } + body = + IRNames::modifierInvocation(*constructor->modifiers().at(0)) + + "(" + + joinHumanReadable(params) + + ")"; + // Now generate the actual inner function. + generateFunctionWithModifierInner(*constructor); + } + } + t("userDefinedConstructorBody", move(body)); return t.render(); }); diff --git a/test/libsolidity/semanticTests/modifiers/function_modifier_calling_functions_in_creation_context.sol b/test/libsolidity/semanticTests/modifiers/function_modifier_calling_functions_in_creation_context.sol index ebe8d6086..86eb9ffc6 100644 --- a/test/libsolidity/semanticTests/modifiers/function_modifier_calling_functions_in_creation_context.sol +++ b/test/libsolidity/semanticTests/modifiers/function_modifier_calling_functions_in_creation_context.sol @@ -45,5 +45,7 @@ contract C is A { } } +// ==== +// compileViaYul: also // ---- // getData() -> 0x4300 diff --git a/test/libsolidity/semanticTests/modifiers/function_modifier_for_constructor.sol b/test/libsolidity/semanticTests/modifiers/function_modifier_for_constructor.sol index c05f7e202..005d8cafa 100644 --- a/test/libsolidity/semanticTests/modifiers/function_modifier_for_constructor.sol +++ b/test/libsolidity/semanticTests/modifiers/function_modifier_for_constructor.sol @@ -22,6 +22,7 @@ contract C is A { _; } } - +// ==== +// compileViaYul: also // ---- // getData() -> 6