From 8775e77305f84117827f1e6165c4d3776c51f667 Mon Sep 17 00:00:00 2001
From: Yoichi Hirai <i@yoichihirai.com>
Date: Fri, 9 Jun 2017 15:35:27 +0200
Subject: Add a warning about a varialbe of the name of an instruction

---
 libsolidity/analysis/NameAndTypeResolver.cpp | 22 ++++++++++++++++++++++
 libsolidity/analysis/NameAndTypeResolver.h   |  3 +++
 libsolidity/analysis/ReferencesResolver.cpp  |  2 ++
 3 files changed, 27 insertions(+)

(limited to 'libsolidity')

diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp
index 2742dcf2..aac90311 100644
--- a/libsolidity/analysis/NameAndTypeResolver.cpp
+++ b/libsolidity/analysis/NameAndTypeResolver.cpp
@@ -26,6 +26,8 @@
 #include <libsolidity/analysis/TypeChecker.h>
 #include <libsolidity/interface/ErrorReporter.h>
 
+#include <boost/algorithm/string.hpp>
+
 using namespace std;
 
 namespace dev
@@ -232,6 +234,26 @@ vector<Declaration const*> NameAndTypeResolver::cleanedDeclarations(
 	return uniqueFunctions;
 }
 
+void NameAndTypeResolver::warnVariablesNamedLikeInstructions()
+{
+	for (auto const& instruction: c_instructions)
+	{
+		string const instructionName{boost::algorithm::to_lower_copy(instruction.first)};
+		auto declarations = nameFromCurrentScope(instructionName);
+		for (Declaration const* const declaration: declarations)
+		{
+			solAssert(!!declaration, "");
+			if (dynamic_cast<MagicVariableDeclaration const* const>(declaration))
+				// Don't warn the user for what the user did not.
+				continue;
+			m_errorReporter.warning(
+				declaration->location(),
+				"Variable is shadowed in inline assembly by an instruction of the same name"
+			);
+		}
+	}
+}
+
 bool NameAndTypeResolver::resolveNamesAndTypesInternal(ASTNode& _node, bool _resolveInsideCode)
 {
 	if (ContractDefinition* contract = dynamic_cast<ContractDefinition*>(&_node))
diff --git a/libsolidity/analysis/NameAndTypeResolver.h b/libsolidity/analysis/NameAndTypeResolver.h
index 0441867d..84628778 100644
--- a/libsolidity/analysis/NameAndTypeResolver.h
+++ b/libsolidity/analysis/NameAndTypeResolver.h
@@ -90,6 +90,9 @@ public:
 		std::vector<Declaration const*> const& _declarations
 	);
 
+	/// Generate and store warnings about variables that are named like instructions.
+	void warnVariablesNamedLikeInstructions();
+
 private:
 	/// Internal version of @a resolveNamesAndTypes (called from there) throws exceptions on fatal errors.
 	bool resolveNamesAndTypesInternal(ASTNode& _node, bool _resolveInsideCode = true);
diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp
index edf2fc02..2a5f27df 100644
--- a/libsolidity/analysis/ReferencesResolver.cpp
+++ b/libsolidity/analysis/ReferencesResolver.cpp
@@ -162,6 +162,8 @@ void ReferencesResolver::endVisit(ArrayTypeName const& _typeName)
 
 bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly)
 {
+	m_resolver.warnVariablesNamedLikeInstructions();
+
 	// Errors created in this stage are completely ignored because we do not yet know
 	// the type and size of external identifiers, which would result in false errors.
 	// The only purpose of this step is to fill the inline assembly annotation with
-- 
cgit v1.2.3