From a823de2d5863efb45e6d0a9d11e41f511687b831 Mon Sep 17 00:00:00 2001
From: Lefteris Karapetsas <lefteris@refu.co>
Date: Thu, 15 Oct 2015 14:37:11 +0200
Subject: push() for byte arrays also properly implemented

---
 libsolidity/ExpressionCompiler.cpp        | 10 ++++++----
 test/libsolidity/SolidityEndToEndTest.cpp | 19 ++++++++++---------
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp
index 2d3126c8..85302afc 100644
--- a/libsolidity/ExpressionCompiler.cpp
+++ b/libsolidity/ExpressionCompiler.cpp
@@ -624,7 +624,6 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
 			break;
 		}
 		case Location::ByteArrayPush:
-			solAssert(false, "Not properly implemented yet");
 		case Location::ArrayPush:
 		{
 			_functionCall.expression().accept(*this);
@@ -651,12 +650,15 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
 			arguments[0]->accept(*this);
 			// stack: newLength storageSlot slotOffset argValue
 			TypePointer type = arguments[0]->annotation().type;
-			utils().convertType(*type, *type->mobileType());
-			type = type->mobileType();
+			utils().convertType(*type, *arrayType->baseType());
+			type = arrayType->baseType();
 			utils().moveToStackTop(1 + type->sizeOnStack());
 			utils().moveToStackTop(1 + type->sizeOnStack());
 			// stack: newLength argValue storageSlot slotOffset
-			StorageItem(m_context, *paramType).storeValue(*type, _functionCall.location(), true);
+			if (function.location() == Location::ArrayPush)
+				StorageItem(m_context, *paramType).storeValue(*type, _functionCall.location(), true);
+			else
+				StorageByteArrayElement(m_context).storeValue(*type, _functionCall.location(), true);
 			break;
 		}
 		default:
diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp
index 96a426dd..c71c9a58 100644
--- a/test/libsolidity/SolidityEndToEndTest.cpp
+++ b/test/libsolidity/SolidityEndToEndTest.cpp
@@ -3495,26 +3495,27 @@ BOOST_AUTO_TEST_CASE(array_push)
 	compileAndRun(sourceCode);
 	BOOST_CHECK(callContractFunction("test()") == encodeArgs(5, 4, 3, 3));
 }
-#if 0 // reactivate once ByteArrayPush is properly implemented
+
 BOOST_AUTO_TEST_CASE(byte_array_push)
 {
 	char const* sourceCode = R"(
 		contract c {
 			bytes data;
-			function test() returns (byte x, byte y, byte z, uint l) {
-				data.push(5);
-				x = data[0];
+			function test() returns (bool x) {
+				if (data.push(5) != 1)  return true;
+				if (data[0] != 5) return true;
 				data.push(4);
-				y = data[1];
-				l = data.push(3);
-				z = data[2];
+				if (data[1] != 4) return true;
+				uint l = data.push(3);
+				if (data[2] != 3) return true;
+				if (l != 3) return true;
 			}
 		}
 	)";
 	compileAndRun(sourceCode);
-	BOOST_CHECK(callContractFunction("test()") == encodeArgs(5, 4, 3, 3));
+	BOOST_CHECK(callContractFunction("test()") == encodeArgs(false));
 }
-#endif
+
 BOOST_AUTO_TEST_CASE(external_array_args)
 {
 	char const* sourceCode = R"(
-- 
cgit v1.2.3