aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/analysis
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2016-10-25 21:31:36 +0800
committerchriseth <c@ethdev.com>2016-10-25 21:32:37 +0800
commit2353da71c77dd235b35d16e7e024fa62408df610 (patch)
tree756604eaddf853a77c1fb04248f2305e1a33739a /libsolidity/analysis
parentaf6afb0415761b53721f89c7f65064807f41cbd3 (diff)
parente3761bdf928e6a06e6620bc1b570d44264d24734 (diff)
downloaddexon-solidity-2353da71c77dd235b35d16e7e024fa62408df610.tar
dexon-solidity-2353da71c77dd235b35d16e7e024fa62408df610.tar.gz
dexon-solidity-2353da71c77dd235b35d16e7e024fa62408df610.tar.bz2
dexon-solidity-2353da71c77dd235b35d16e7e024fa62408df610.tar.lz
dexon-solidity-2353da71c77dd235b35d16e7e024fa62408df610.tar.xz
dexon-solidity-2353da71c77dd235b35d16e7e024fa62408df610.tar.zst
dexon-solidity-2353da71c77dd235b35d16e7e024fa62408df610.zip
Merge remote-tracking branch 'origin/develop' into release
Diffstat (limited to 'libsolidity/analysis')
-rw-r--r--libsolidity/analysis/GlobalContext.cpp2
-rw-r--r--libsolidity/analysis/SemVerHandler.h6
-rw-r--r--libsolidity/analysis/SyntaxChecker.cpp19
-rw-r--r--libsolidity/analysis/TypeChecker.cpp34
4 files changed, 47 insertions, 14 deletions
diff --git a/libsolidity/analysis/GlobalContext.cpp b/libsolidity/analysis/GlobalContext.cpp
index a7ffcfad..d075949e 100644
--- a/libsolidity/analysis/GlobalContext.cpp
+++ b/libsolidity/analysis/GlobalContext.cpp
@@ -48,6 +48,8 @@ m_magicVariables(vector<shared_ptr<MagicVariableDeclaration const>>{make_shared<
make_shared<FunctionType>(strings{"uint256", "uint256", "uint256"}, strings{"uint256"}, FunctionType::Location::MulMod)),
make_shared<MagicVariableDeclaration>("sha3",
make_shared<FunctionType>(strings(), strings{"bytes32"}, FunctionType::Location::SHA3, true)),
+ make_shared<MagicVariableDeclaration>("keccak256",
+ make_shared<FunctionType>(strings(), strings{"bytes32"}, FunctionType::Location::SHA3, true)),
make_shared<MagicVariableDeclaration>("log0",
make_shared<FunctionType>(strings{"bytes32"}, strings{}, FunctionType::Location::Log0)),
make_shared<MagicVariableDeclaration>("log1",
diff --git a/libsolidity/analysis/SemVerHandler.h b/libsolidity/analysis/SemVerHandler.h
index 3c110b19..e3b642db 100644
--- a/libsolidity/analysis/SemVerHandler.h
+++ b/libsolidity/analysis/SemVerHandler.h
@@ -40,6 +40,12 @@ struct SemVerVersion
std::string prerelease;
std::string build;
+ unsigned major() const { return numbers[0]; }
+ unsigned minor() const { return numbers[1]; }
+ unsigned patch() const { return numbers[2]; }
+
+ bool isPrerelease() const { return !prerelease.empty(); }
+
explicit SemVerVersion(std::string const& _versionString = "0.0.0");
};
diff --git a/libsolidity/analysis/SyntaxChecker.cpp b/libsolidity/analysis/SyntaxChecker.cpp
index a95b4879..dbaa15ed 100644
--- a/libsolidity/analysis/SyntaxChecker.cpp
+++ b/libsolidity/analysis/SyntaxChecker.cpp
@@ -52,13 +52,22 @@ void SyntaxChecker::endVisit(SourceUnit const& _sourceUnit)
{
if (!m_versionPragmaFound)
{
+ string errorString("Source file does not specify required compiler version!");
+ SemVerVersion recommendedVersion{string(VersionString)};
+ if (!recommendedVersion.isPrerelease())
+ errorString +=
+ "Consider adding \"pragma solidity ^" +
+ to_string(recommendedVersion.major()) +
+ string(".") +
+ to_string(recommendedVersion.minor()) +
+ string(".") +
+ to_string(recommendedVersion.patch());
+ string(";\"");
+
auto err = make_shared<Error>(Error::Type::Warning);
*err <<
errinfo_sourceLocation(_sourceUnit.location()) <<
- errinfo_comment(
- string("Source file does not specify required compiler version! ") +
- string("Consider adding \"pragma solidity ^") + VersionNumber + string(";\".")
- );
+ errinfo_comment(errorString);
m_errors.push_back(err);
}
}
@@ -67,7 +76,7 @@ bool SyntaxChecker::visit(PragmaDirective const& _pragma)
{
solAssert(!_pragma.tokens().empty(), "");
solAssert(_pragma.tokens().size() == _pragma.literals().size(), "");
- if (_pragma.tokens()[0] != Token::Identifier && _pragma.literals()[0] != "solidity")
+ if (_pragma.tokens()[0] != Token::Identifier || _pragma.literals()[0] != "solidity")
syntaxError(_pragma.location(), "Unknown pragma \"" + _pragma.literals()[0] + "\"");
else
{
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index ae7c13c8..46f4f7f6 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -609,6 +609,8 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
return false;
pushes = 1;
}
+ else
+ return false;
for (unsigned i = 0; i < pushes; ++i)
_assembly.append(u256(0)); // just to verify the stack height
}
@@ -716,11 +718,10 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
{
if (ref->dataStoredIn(DataLocation::Storage))
{
- auto err = make_shared<Error>(Error::Type::Warning);
- *err <<
- errinfo_sourceLocation(varDecl.location()) <<
- errinfo_comment("Uninitialized storage pointer. Did you mean '<type> memory " + varDecl.name() + "'?");
- m_errors.push_back(err);
+ warning(
+ varDecl.location(),
+ "Uninitialized storage pointer. Did you mean '<type> memory " + varDecl.name() + "'?"
+ );
}
}
varDecl.accept(*this);
@@ -879,6 +880,10 @@ bool TypeChecker::visit(Conditional const& _conditional)
TypePointer trueType = type(_conditional.trueExpression())->mobileType();
TypePointer falseType = type(_conditional.falseExpression())->mobileType();
+ if (!trueType)
+ fatalTypeError(_conditional.trueExpression().location(), "Invalid mobile type.");
+ if (!falseType)
+ fatalTypeError(_conditional.falseExpression().location(), "Invalid mobile type.");
TypePointer commonType = Type::commonType(trueType, falseType);
if (!commonType)
@@ -985,10 +990,16 @@ bool TypeChecker::visit(TupleExpression const& _tuple)
types.push_back(type(*components[i]));
if (_tuple.isInlineArray())
solAssert(!!types[i], "Inline array cannot have empty components");
- if (i == 0 && _tuple.isInlineArray())
- inlineArrayType = types[i]->mobileType();
- else if (_tuple.isInlineArray() && inlineArrayType)
- inlineArrayType = Type::commonType(inlineArrayType, types[i]->mobileType());
+ if (_tuple.isInlineArray())
+ {
+ if ((i == 0 || inlineArrayType) && !types[i]->mobileType())
+ fatalTypeError(components[i]->location(), "Invalid mobile type.");
+
+ if (i == 0)
+ inlineArrayType = types[i]->mobileType();
+ else if (inlineArrayType)
+ inlineArrayType = Type::commonType(inlineArrayType, types[i]->mobileType());
+ }
}
else
types.push_back(TypePointer());
@@ -1375,6 +1386,11 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
}
else if (exprType->category() == Type::Category::FixedBytes)
annotation.isLValue = false;
+ else if (TypeType const* typeType = dynamic_cast<decltype(typeType)>(exprType.get()))
+ {
+ if (ContractType const* contractType = dynamic_cast<decltype(contractType)>(typeType->actualType().get()))
+ annotation.isLValue = annotation.referencedDeclaration->isLValue();
+ }
return false;
}