From 900c56d996472cb2053b69c7104ef007c13b1e80 Mon Sep 17 00:00:00 2001
From: Alex Beregszaszi <alex@rtfs.hu>
Date: Wed, 25 Jan 2017 10:33:09 +0000
Subject: [PATCH] Do not allow shadowing inline assembly instructions with
 variables

---
 Changelog.md                        |  1 +
 libsolidity/inlineasm/AsmParser.cpp | 11 ++++++++++-
 libsolidity/inlineasm/AsmParser.h   |  1 +
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/Changelog.md b/Changelog.md
index 7dd607d8d..60def101e 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -10,6 +10,7 @@ Features:
 
 Bugfixes:
  * Code generator: Allow recursive structs.
+ * Inline assembly: reject shadowing instructions by variables.
  * Type checker: Allow multiple events of the same name (but with different arities or argument types)
 
 ### 0.4.8 (2017-01-13)
diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp
index ef3da2554..c0efb651e 100644
--- a/libsolidity/inlineasm/AsmParser.cpp
+++ b/libsolidity/inlineasm/AsmParser.cpp
@@ -130,7 +130,7 @@ assembly::Statement Parser::parseExpression()
 		return operation;
 }
 
-assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher)
+std::map<string, dev::solidity::Instruction> Parser::getInstructions()
 {
 	// Allowed instructions, lowercase names.
 	static map<string, dev::solidity::Instruction> s_instructions;
@@ -151,6 +151,12 @@ assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher)
 		// add alias for selfdestruct
 		s_instructions["selfdestruct"] = solidity::Instruction::SUICIDE;
 	}
+	return s_instructions;
+}
+
+assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher)
+{
+	map<string, dev::solidity::Instruction> s_instructions = getInstructions();
 
 	Statement ret;
 	switch (m_scanner->currentToken())
@@ -204,9 +210,12 @@ assembly::Statement Parser::parseElementaryOperation(bool _onlySinglePusher)
 
 assembly::VariableDeclaration Parser::parseVariableDeclaration()
 {
+	map<string, dev::solidity::Instruction> s_instructions = getInstructions();
 	VariableDeclaration varDecl = createWithLocation<VariableDeclaration>();
 	expectToken(Token::Let);
 	varDecl.name = m_scanner->currentLiteral();
+	if (s_instructions.count(varDecl.name))
+		fatalParserError("Cannot shadow instructions with variable declaration.");
 	expectToken(Token::Identifier);
 	expectToken(Token::Colon);
 	expectToken(Token::Assign);
diff --git a/libsolidity/inlineasm/AsmParser.h b/libsolidity/inlineasm/AsmParser.h
index 8b56ab902..764c53f66 100644
--- a/libsolidity/inlineasm/AsmParser.h
+++ b/libsolidity/inlineasm/AsmParser.h
@@ -64,6 +64,7 @@ protected:
 	Statement parseStatement();
 	/// Parses a functional expression that has to push exactly one stack element
 	Statement parseExpression();
+	std::map<std::string, dev::solidity::Instruction> getInstructions();
 	Statement parseElementaryOperation(bool _onlySinglePusher = false);
 	VariableDeclaration parseVariableDeclaration();
 	FunctionalInstruction parseFunctionalInstruction(Statement&& _instruction);