Skip to content

Commit 0d68b8c

Browse files
Allow constants in custom storage layout expression
1 parent 96290f8 commit 0d68b8c

File tree

1 file changed

+37
-12
lines changed

1 file changed

+37
-12
lines changed

libsolidity/analysis/PostTypeContractLevelChecker.cpp

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <libsolidity/analysis/PostTypeContractLevelChecker.h>
2424

2525
#include <fmt/format.h>
26+
#include <libsolidity/analysis/ConstantEvaluator.h>
2627
#include <libsolidity/ast/AST.h>
2728
#include <libsolidity/ast/ASTUtils.h>
2829
#include <libsolidity/ast/TypeProvider.h>
@@ -101,29 +102,53 @@ void PostTypeContractLevelChecker::checkStorageLayoutSpecifier(ContractDefinitio
101102
}
102103

103104
auto const* baseSlotExpressionType = type(baseSlotExpression);
104-
auto const* rationalType = dynamic_cast<RationalNumberType const*>(baseSlotExpressionType);
105-
if (!rationalType)
105+
if (
106+
!dynamic_cast<IntegerType const*>(baseSlotExpressionType) &&
107+
!dynamic_cast<RationalNumberType const*>(baseSlotExpressionType)
108+
)
106109
{
107110
m_errorReporter.typeError(
108111
6396_error,
109112
baseSlotExpression.location(),
110-
"The base slot of the storage layout must evaluate to a rational number."
113+
"The base slot of the storage layout must evaluate to an integer number."
111114
);
112115
return;
113116
}
114117

115-
if (rationalType->isFractional())
118+
rational baseSlotRationalValue;
119+
if (auto const integerType = dynamic_cast<IntegerType const*>(baseSlotExpressionType))
116120
{
117-
m_errorReporter.typeError(
118-
1763_error,
119-
baseSlotExpression.location(),
120-
"The base slot of the storage layout must evaluate to an integer."
121-
);
122-
return;
121+
std::optional<ConstantEvaluator::TypedRational> typedRational = ConstantEvaluator::evaluate(m_errorReporter, baseSlotExpression);
122+
if (!typedRational)
123+
{
124+
m_errorReporter.typeError(
125+
1505_error,
126+
baseSlotExpression.location(),
127+
"The base slot expression contains elements that are not yet supported "
128+
"by the internal constant evaluator and therefore cannot be evaluated at compilation time."
129+
);
130+
return;
131+
}
132+
baseSlotRationalValue = typedRational->value;
133+
}
134+
else
135+
{
136+
auto const* rationalType = dynamic_cast<RationalNumberType const*>(baseSlotExpressionType);
137+
solAssert(rationalType);
138+
if (rationalType->isFractional())
139+
{
140+
m_errorReporter.typeError(
141+
1763_error,
142+
baseSlotExpression.location(),
143+
"The base slot of the storage layout must evaluate to an integer."
144+
);
145+
return;
146+
}
147+
baseSlotRationalValue = rationalType->value();
123148
}
124-
solAssert(rationalType->value().denominator() == 1);
125149

126-
bigint baseSlot = rationalType->value().numerator();
150+
solAssert(baseSlotRationalValue.denominator() == 1);
151+
bigint baseSlot = baseSlotRationalValue.numerator();
127152
if (!(0 <= baseSlot && baseSlot <= std::numeric_limits<u256>::max()))
128153
{
129154
m_errorReporter.typeError(

0 commit comments

Comments
 (0)