From a8d0ef4bad8f77b737b2004d7d2e855598ef1286 Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 24 Jan 2019 14:40:22 +0100 Subject: [PATCH] Allow indexed structs in events with encoder v2. --- libsolidity/analysis/TypeChecker.cpp | 10 ---------- libsolidity/codegen/ExpressionCompiler.cpp | 13 +++++++++---- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 4b1f28cda..ed0af3642 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -578,17 +578,7 @@ bool TypeChecker::visit(EventDefinition const& _eventDef) for (ASTPointer const& var: _eventDef.parameters()) { if (var->isIndexed()) - { numIndexed++; - if ( - _eventDef.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::ABIEncoderV2) && - dynamic_cast(type(*var).get()) - ) - m_errorReporter.typeError( - var->location(), - "Indexed reference types cannot yet be used with ABIEncoderV2." - ); - } if (!type(*var)->canLiveOutsideStorage()) m_errorReporter.typeError(var->location(), "Type is required to live outside storage."); if (!type(*var)->interfaceType(false)) diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index c1079ed32..942363461 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -731,6 +731,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) } arguments.front()->accept(*this); utils().fetchFreeMemoryPointer(); + solAssert(function.parameterTypes().front()->isValueType(), ""); utils().packedEncode( {arguments.front()->annotation().type}, {function.parameterTypes().front()} @@ -744,28 +745,32 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) _functionCall.expression().accept(*this); auto const& event = dynamic_cast(function.declaration()); unsigned numIndexed = 0; + TypePointers paramTypes = function.parameterTypes(); // All indexed arguments go to the stack for (unsigned arg = arguments.size(); arg > 0; --arg) if (event.parameters()[arg - 1]->isIndexed()) { ++numIndexed; arguments[arg - 1]->accept(*this); - if (auto const& arrayType = dynamic_pointer_cast(function.parameterTypes()[arg - 1])) + if (auto const& referenceType = dynamic_pointer_cast(paramTypes[arg - 1])) { utils().fetchFreeMemoryPointer(); utils().packedEncode( {arguments[arg - 1]->annotation().type}, - {arrayType} + {referenceType} ); utils().toSizeAfterFreeMemoryPointer(); m_context << Instruction::KECCAK256; } else + { + solAssert(paramTypes[arg - 1]->isValueType(), ""); utils().convertType( *arguments[arg - 1]->annotation().type, - *function.parameterTypes()[arg - 1], + *paramTypes[arg - 1], true ); + } } if (!event.isAnonymous()) { @@ -782,7 +787,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall) { arguments[arg]->accept(*this); nonIndexedArgTypes.push_back(arguments[arg]->annotation().type); - nonIndexedParamTypes.push_back(function.parameterTypes()[arg]); + nonIndexedParamTypes.push_back(paramTypes[arg]); } utils().fetchFreeMemoryPointer(); utils().abiEncode(nonIndexedArgTypes, nonIndexedParamTypes);