Skip to content

Commit 944dc30

Browse files
committedMar 19, 2025
Allow constants in custom storage layout expression
1 parent 15696d1 commit 944dc30

File tree

1 file changed

+35
-11
lines changed

1 file changed

+35
-11
lines changed
 

‎libsolidity/analysis/PostTypeContractLevelChecker.cpp

+35-11
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,8 +102,10 @@ 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,
@@ -112,18 +115,39 @@ void PostTypeContractLevelChecker::checkStorageLayoutSpecifier(ContractDefinitio
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 cannot be evaluated during compilation."
128+
);
129+
return;
130+
}
131+
baseSlotRationalValue = typedRational->value;
132+
}
133+
else
134+
{
135+
auto const* rationalType = dynamic_cast<RationalNumberType const*>(baseSlotExpressionType);
136+
solAssert(rationalType);
137+
if (rationalType->isFractional())
138+
{
139+
m_errorReporter.typeError(
140+
1763_error,
141+
baseSlotExpression.location(),
142+
"The base slot of the storage layout must evaluate to an integer."
143+
);
144+
return;
145+
}
146+
baseSlotRationalValue = rationalType->value();
123147
}
124-
solAssert(rationalType->value().denominator() == 1);
125148

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

0 commit comments

Comments
 (0)
Failed to load comments.