23
23
#include < libsolidity/analysis/PostTypeContractLevelChecker.h>
24
24
25
25
#include < fmt/format.h>
26
+ #include < libsolidity/analysis/ConstantEvaluator.h>
26
27
#include < libsolidity/ast/AST.h>
27
28
#include < libsolidity/ast/ASTUtils.h>
28
29
#include < libsolidity/ast/TypeProvider.h>
@@ -101,8 +102,10 @@ void PostTypeContractLevelChecker::checkStorageLayoutSpecifier(ContractDefinitio
101
102
}
102
103
103
104
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
+ )
106
109
{
107
110
m_errorReporter.typeError (
108
111
6396_error,
@@ -112,18 +115,39 @@ void PostTypeContractLevelChecker::checkStorageLayoutSpecifier(ContractDefinitio
112
115
return ;
113
116
}
114
117
115
- if (rationalType->isFractional ())
118
+ rational baseSlotRationalValue;
119
+ if (auto const integerType = dynamic_cast <IntegerType const *>(baseSlotExpressionType))
116
120
{
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 ();
123
147
}
124
- solAssert (rationalType->value ().denominator () == 1 );
125
148
126
- bigint baseSlot = rationalType->value ().numerator ();
149
+ solAssert (baseSlotRationalValue.denominator () == 1 );
150
+ bigint baseSlot = baseSlotRationalValue.numerator ();
127
151
if (!(0 <= baseSlot && baseSlot <= std::numeric_limits<u256>::max ()))
128
152
{
129
153
m_errorReporter.typeError (
0 commit comments