Skip to content

Commit 7711a8e

Browse files
Merge pull request #15001 from ethereum/transientStorageParserHack
Enable parser to accept `transient` as data location or identifier
2 parents a5f5eac + ad2644c commit 7711a8e

File tree

70 files changed

+474
-7
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+474
-7
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
### 0.8.27 (unreleased)
22

33
Language Features:
4+
* Accept declarations of state variables with ``transient`` data location (parser support only, no code generation yet).
45

56

67
Compiler Features:

docs/grammar/SolidityLexer.g4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ SignedIntegerType:
8585
Storage: 'storage';
8686
String: 'string';
8787
Struct: 'struct';
88+
Transient: 'transient'; // not a real keyword
8889
True: 'true';
8990
Try: 'try';
9091
Type: 'type';

docs/grammar/SolidityParser.g4

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ userDefinedValueTypeDefinition:
262262
* The declaration of a state variable.
263263
*/
264264
stateVariableDeclaration
265-
locals [boolean constantnessSet = false, boolean visibilitySet = false, boolean overrideSpecifierSet = false]
265+
locals [boolean constantnessSet = false, boolean visibilitySet = false, boolean overrideSpecifierSet = false, boolean locationSet = false]
266266
:
267267
type=typeName
268268
(
@@ -272,6 +272,7 @@ locals [boolean constantnessSet = false, boolean visibilitySet = false, boolean
272272
| {!$constantnessSet}? Constant {$constantnessSet = true;}
273273
| {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;}
274274
| {!$constantnessSet}? Immutable {$constantnessSet = true;}
275+
| {!$locationSet}? Transient {$locationSet = true;}
275276
)*
276277
name=identifier
277278
(Assign initialValue=expression)?
@@ -419,7 +420,7 @@ inlineArrayExpression: LBrack (expression ( Comma expression)* ) RBrack;
419420
/**
420421
* Besides regular non-keyword Identifiers, some keywords like 'from' and 'error' can also be used as identifiers.
421422
*/
422-
identifier: Identifier | From | Error | Revert | Global;
423+
identifier: Identifier | From | Error | Revert | Global | Transient;
423424

424425
literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral;
425426

libsolidity/analysis/DeclarationTypeChecker.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable)
407407
{
408408
case Location::Memory: return "\"memory\"";
409409
case Location::Storage: return "\"storage\"";
410+
case Location::Transient: return "\"transient\"";
410411
case Location::CallData: return "\"calldata\"";
411412
case Location::Unspecified: return "none";
412413
}
@@ -456,8 +457,24 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable)
456457
}
457458
else if (_variable.isStateVariable())
458459
{
459-
solAssert(varLoc == Location::Unspecified, "");
460-
typeLoc = (_variable.isConstant() || _variable.immutable()) ? DataLocation::Memory : DataLocation::Storage;
460+
switch (varLoc)
461+
{
462+
case Location::Unspecified:
463+
typeLoc = (_variable.isConstant() || _variable.immutable()) ? DataLocation::Memory : DataLocation::Storage;
464+
break;
465+
case Location::Transient:
466+
if (_variable.isConstant() || _variable.immutable())
467+
m_errorReporter.declarationError(
468+
2197_error,
469+
_variable.location(),
470+
"Transient cannot be used as data location for constant or immutable variables."
471+
);
472+
typeLoc = DataLocation::Transient;
473+
break;
474+
default:
475+
solAssert(false);
476+
break;
477+
}
461478
}
462479
else if (
463480
dynamic_cast<StructDefinition const*>(_variable.scope()) ||
@@ -477,6 +494,9 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable)
477494
case Location::CallData:
478495
typeLoc = DataLocation::CallData;
479496
break;
497+
case Location::Transient:
498+
solUnimplemented("Transient data location cannot be used in this kind of variable or parameter declaration.");
499+
break;
480500
case Location::Unspecified:
481501
solAssert(!_variable.hasReferenceOrMappingType(), "Data location not properly set.");
482502
}
@@ -497,6 +517,9 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable)
497517
m_errorReporter.fatalTypeError(9259_error, _variable.location(), "Only constants of value type and byte array type are implemented.");
498518
}
499519

520+
if (!type->isValueType())
521+
solUnimplementedAssert(typeLoc != DataLocation::Transient, "Transient data location is only supported for value types.");
522+
500523
_variable.annotation().type = type;
501524
}
502525

libsolidity/ast/AST.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -816,7 +816,9 @@ std::set<VariableDeclaration::Location> VariableDeclaration::allowedDataLocation
816816
{
817817
using Location = VariableDeclaration::Location;
818818

819-
if (!hasReferenceOrMappingType() || isStateVariable() || isEventOrErrorParameter())
819+
if (isStateVariable())
820+
return std::set<Location>{Location::Unspecified, Location::Transient};
821+
else if (!hasReferenceOrMappingType() || isEventOrErrorParameter())
820822
return std::set<Location>{ Location::Unspecified };
821823
else if (isCallableOrCatchParameter())
822824
{

libsolidity/ast/AST.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1052,7 +1052,7 @@ class FunctionDefinition: public CallableDeclaration, public StructurallyDocumen
10521052
class VariableDeclaration: public Declaration, public StructurallyDocumented
10531053
{
10541054
public:
1055-
enum Location { Unspecified, Storage, Memory, CallData };
1055+
enum Location { Unspecified, Storage, Transient, Memory, CallData };
10561056
enum class Mutability { Mutable, Immutable, Constant };
10571057
static std::string mutabilityToString(Mutability _mutability)
10581058
{

libsolidity/ast/ASTJsonExporter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,6 +1058,8 @@ std::string ASTJsonExporter::location(VariableDeclaration::Location _location)
10581058
return "memory";
10591059
case VariableDeclaration::Location::CallData:
10601060
return "calldata";
1061+
case VariableDeclaration::Location::Transient:
1062+
return "transient";
10611063
}
10621064
// To make the compiler happy
10631065
return {};

libsolidity/ast/ASTJsonImporter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,6 +1190,8 @@ VariableDeclaration::Location ASTJsonImporter::location(Json const& _node)
11901190
return VariableDeclaration::Location::Memory;
11911191
else if (storageLocStr == "calldata")
11921192
return VariableDeclaration::Location::CallData;
1193+
else if (storageLocStr == "transient")
1194+
return VariableDeclaration::Location::Transient;
11931195
else
11941196
astAssert(false, "Unknown location declaration");
11951197

libsolidity/ast/Types.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,6 +1544,8 @@ TypeResult ReferenceType::unaryOperatorResult(Token _operator) const
15441544
return TypeProvider::emptyTuple();
15451545
case DataLocation::Storage:
15461546
return isPointer() ? nullptr : TypeProvider::emptyTuple();
1547+
case DataLocation::Transient:
1548+
solUnimplemented("Transient data location is only supported for value types.");
15471549
}
15481550
return nullptr;
15491551
}
@@ -1571,6 +1573,9 @@ std::string ReferenceType::stringForReferencePart() const
15711573
return "calldata";
15721574
case DataLocation::Memory:
15731575
return "memory";
1576+
case DataLocation::Transient:
1577+
solUnimplemented("Transient data location is only supported for value types.");
1578+
break;
15741579
}
15751580
solAssert(false, "");
15761581
return "";
@@ -1584,6 +1589,9 @@ std::string ReferenceType::identifierLocationSuffix() const
15841589
case DataLocation::Storage:
15851590
id += "_storage";
15861591
break;
1592+
case DataLocation::Transient:
1593+
solUnimplemented("Transient data location is only supported for value types.");
1594+
break;
15871595
case DataLocation::Memory:
15881596
id += "_memory";
15891597
break;
@@ -1748,6 +1756,9 @@ BoolResult ArrayType::validForLocation(DataLocation _loc) const
17481756
if (storageSizeUpperBound() >= bigint(1) << 256)
17491757
return BoolResult::err("Type too large for storage.");
17501758
break;
1759+
case DataLocation::Transient:
1760+
solUnimplemented("Transient data location is only supported for value types.");
1761+
break;
17511762
}
17521763
return true;
17531764
}
@@ -1828,6 +1839,9 @@ std::vector<std::tuple<std::string, Type const*>> ArrayType::makeStackItems() co
18281839
case DataLocation::Storage:
18291840
// byte offset inside storage value is omitted
18301841
return {std::make_tuple("slot", TypeProvider::uint256())};
1842+
case DataLocation::Transient:
1843+
solUnimplemented("Transient data location is only supported for value types.");
1844+
break;
18311845
}
18321846
solAssert(false, "");
18331847
}
@@ -2568,6 +2582,9 @@ std::vector<std::tuple<std::string, Type const*>> StructType::makeStackItems() c
25682582
return {std::make_tuple("mpos", TypeProvider::uint256())};
25692583
case DataLocation::Storage:
25702584
return {std::make_tuple("slot", TypeProvider::uint256())};
2585+
case DataLocation::Transient:
2586+
solUnimplemented("Transient data location is only supported for value types.");
2587+
break;
25712588
}
25722589
solAssert(false, "");
25732590
}

libsolidity/ast/Types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ inline rational makeRational(bigint const& _numerator, bigint const& _denominato
7070
return rational(_numerator, _denominator);
7171
}
7272

73-
enum class DataLocation { Storage, CallData, Memory };
73+
enum class DataLocation { Storage, Transient, CallData, Memory };
7474

7575

7676
/**

0 commit comments

Comments
 (0)