From ad2644c52b3afbe80801322c5fe44edb59383500 Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Sat, 6 Apr 2024 17:17:51 -0300 Subject: [PATCH] Make parser accept transient as location (but not a keyword) --- Changelog.md | 1 + docs/grammar/SolidityLexer.g4 | 1 + docs/grammar/SolidityParser.g4 | 5 ++-- .../analysis/DeclarationTypeChecker.cpp | 27 +++++++++++++++++-- libsolidity/ast/AST.cpp | 4 ++- libsolidity/ast/AST.h | 2 +- libsolidity/ast/ASTJsonExporter.cpp | 2 ++ libsolidity/ast/ASTJsonImporter.cpp | 2 ++ libsolidity/ast/Types.cpp | 17 ++++++++++++ libsolidity/ast/Types.h | 2 +- libsolidity/codegen/ArrayUtils.cpp | 6 +++++ libsolidity/codegen/CompilerUtils.cpp | 9 +++++++ libsolidity/codegen/ContractCompiler.cpp | 1 + libsolidity/codegen/ExpressionCompiler.cpp | 6 +++++ libsolidity/codegen/YulUtilFunctions.cpp | 3 +++ .../codegen/ir/IRGeneratorForStatements.cpp | 13 +++++++++ libsolidity/formal/BMC.cpp | 3 +++ libsolidity/formal/CHC.cpp | 3 +++ libsolidity/formal/SMTEncoder.h | 13 +++++++++ libsolidity/interface/StorageLayout.cpp | 1 + libsolidity/parsing/Parser.cpp | 13 +++++++++ scripts/error_codes.py | 1 + .../in.sol | 10 +++++++ .../input.json | 13 +++++++++ .../output.json | 11 ++++++++ .../transient_data_location.sol | 8 ++++++ .../transient_storage_state_variable.sol | 8 ++++++ ...onstant_state_variable_named_transient.sol | 4 +++ .../constant_transient_state_variable.sol | 5 ++++ .../data_location_in_function_type_fail.sol | 3 +++ ...tion_specifier_test_external_transient.sol | 5 ++++ ...tion_specifier_test_internal_transient.sol | 5 ++++ ..._function_with_data_location_transient.sol | 19 +++++++++++++ ...tion_specifier_test_external_transient.sol | 5 ++++ ...tion_specifier_test_internal_transient.sol | 5 ++++ ...sient_data_location_function_parameter.sol | 6 +++++ ...function_parameters_location_transient.sol | 5 ++++ ...n_return_parameters_location_transient.sol | 5 ++++ ...cation_specifier_test_public_transient.sol | 5 ++++ ...n_return_parameters_location_transient.sol | 5 ++++ ...state_variable_storage_named_transient.sol | 5 ++++ .../state_variable_storage_transient.sol | 5 ++++ .../state_variable_transient_storage.sol | 5 ++++ ...transient_dynamic_array_state_variable.sol | 7 +++++ .../transient_fixed_array_state_variable.sol | 7 +++++ .../dataLocations/transient_function_type.sol | 11 ++++++++ .../transient_function_type_parameter.sol | 5 ++++ .../transient_local_variable.sol | 7 +++++ .../transient_mapping_state_variable.sol | 7 +++++ .../transient_state_variable_visibility.sol | 12 +++++++++ .../transient_struct_state_variable.sol | 12 +++++++++ .../transient_value_type_state_variables.sol | 12 +++++++++ ..._value_type_state_variables_assignment.sol | 10 +++++++ .../errors/invalid_parameter_location.sol | 5 ++++ .../events/invalid_parameter_location.sol | 5 ++++ .../events/transient_indexed_parameter.sol | 5 ++++ .../function_type_with_transient_param.sol | 8 ++++++ ...nction_type_with_param_named_transient.sol | 6 +++++ ...ent_function_type_with_transient_param.sol | 5 ++++ .../immutable_state_var_named_transient.sol | 4 +++ .../state_var_transient_data_location.sol | 5 ++++ .../modifiers/multiple_parameter_location.sol | 7 +++++ .../modifiers/transient_parameter.sol | 5 ++++ .../operators/transient_value_type.sol | 11 ++++++++ .../parsing/contract_named_transient.sol | 1 + .../transient_data_location_member.sol | 5 ++++ ...ate_variable_address_payable_transient.sol | 6 +++++ ...ate_variable_address_transient_payable.sol | 5 ++++ .../transient_as_identifier.sol | 25 +++++++++++++++++ ...nsient_as_identifier_and_data_location.sol | 6 +++++ 70 files changed, 474 insertions(+), 7 deletions(-) create mode 100644 test/cmdlineTests/storage_layout_transient_value_types/in.sol create mode 100644 test/cmdlineTests/storage_layout_transient_value_types/input.json create mode 100644 test/cmdlineTests/storage_layout_transient_value_types/output.json create mode 100644 test/libsolidity/astPropertyTests/transient_data_location.sol create mode 100644 test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol create mode 100644 test/libsolidity/syntaxTests/constants/constant_state_variable_named_transient.sol create mode 100644 test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/libraries/library_function_with_data_location_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/multiple_transient_data_location_function_parameter.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_parameters_location_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_return_parameters_location_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_return_parameters_location_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/state_variable_storage_named_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/state_variable_storage_transient.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/state_variable_transient_storage.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_function_type_parameter.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_local_variable.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_struct_state_variable.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol create mode 100644 test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol create mode 100644 test/libsolidity/syntaxTests/events/transient_indexed_parameter.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/function_type_with_transient_param.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_param_named_transient.sol create mode 100644 test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_transient_param.sol create mode 100644 test/libsolidity/syntaxTests/immutable/immutable_state_var_named_transient.sol create mode 100644 test/libsolidity/syntaxTests/immutable/state_var_transient_data_location.sol create mode 100644 test/libsolidity/syntaxTests/modifiers/transient_parameter.sol create mode 100644 test/libsolidity/syntaxTests/operators/transient_value_type.sol create mode 100644 test/libsolidity/syntaxTests/parsing/contract_named_transient.sol create mode 100644 test/libsolidity/syntaxTests/structs/transient_data_location_member.sol create mode 100644 test/libsolidity/syntaxTests/types/address/state_variable_address_payable_transient.sol create mode 100644 test/libsolidity/syntaxTests/types/address/state_variable_address_transient_payable.sol create mode 100644 test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier.sol create mode 100644 test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier_and_data_location.sol diff --git a/Changelog.md b/Changelog.md index de3fc3d6cf13..8ac9a7895f34 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,6 +1,7 @@ ### 0.8.27 (unreleased) Language Features: + * Accept declarations of state variables with ``transient`` data location (parser support only, no code generation yet). Compiler Features: diff --git a/docs/grammar/SolidityLexer.g4 b/docs/grammar/SolidityLexer.g4 index 43648ceb5d97..f994c331d536 100644 --- a/docs/grammar/SolidityLexer.g4 +++ b/docs/grammar/SolidityLexer.g4 @@ -85,6 +85,7 @@ SignedIntegerType: Storage: 'storage'; String: 'string'; Struct: 'struct'; +Transient: 'transient'; // not a real keyword True: 'true'; Try: 'try'; Type: 'type'; diff --git a/docs/grammar/SolidityParser.g4 b/docs/grammar/SolidityParser.g4 index e6d3ed7ccaea..a344fad54470 100644 --- a/docs/grammar/SolidityParser.g4 +++ b/docs/grammar/SolidityParser.g4 @@ -262,7 +262,7 @@ userDefinedValueTypeDefinition: * The declaration of a state variable. */ stateVariableDeclaration -locals [boolean constantnessSet = false, boolean visibilitySet = false, boolean overrideSpecifierSet = false] +locals [boolean constantnessSet = false, boolean visibilitySet = false, boolean overrideSpecifierSet = false, boolean locationSet = false] : type=typeName ( @@ -272,6 +272,7 @@ locals [boolean constantnessSet = false, boolean visibilitySet = false, boolean | {!$constantnessSet}? Constant {$constantnessSet = true;} | {!$overrideSpecifierSet}? overrideSpecifier {$overrideSpecifierSet = true;} | {!$constantnessSet}? Immutable {$constantnessSet = true;} + | {!$locationSet}? Transient {$locationSet = true;} )* name=identifier (Assign initialValue=expression)? @@ -419,7 +420,7 @@ inlineArrayExpression: LBrack (expression ( Comma expression)* ) RBrack; /** * Besides regular non-keyword Identifiers, some keywords like 'from' and 'error' can also be used as identifiers. */ -identifier: Identifier | From | Error | Revert | Global; +identifier: Identifier | From | Error | Revert | Global | Transient; literal: stringLiteral | numberLiteral | booleanLiteral | hexStringLiteral | unicodeStringLiteral; diff --git a/libsolidity/analysis/DeclarationTypeChecker.cpp b/libsolidity/analysis/DeclarationTypeChecker.cpp index 28c051c0a000..7e6ab98e1e24 100644 --- a/libsolidity/analysis/DeclarationTypeChecker.cpp +++ b/libsolidity/analysis/DeclarationTypeChecker.cpp @@ -407,6 +407,7 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable) { case Location::Memory: return "\"memory\""; case Location::Storage: return "\"storage\""; + case Location::Transient: return "\"transient\""; case Location::CallData: return "\"calldata\""; case Location::Unspecified: return "none"; } @@ -456,8 +457,24 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable) } else if (_variable.isStateVariable()) { - solAssert(varLoc == Location::Unspecified, ""); - typeLoc = (_variable.isConstant() || _variable.immutable()) ? DataLocation::Memory : DataLocation::Storage; + switch (varLoc) + { + case Location::Unspecified: + typeLoc = (_variable.isConstant() || _variable.immutable()) ? DataLocation::Memory : DataLocation::Storage; + break; + case Location::Transient: + if (_variable.isConstant() || _variable.immutable()) + m_errorReporter.declarationError( + 2197_error, + _variable.location(), + "Transient cannot be used as data location for constant or immutable variables." + ); + typeLoc = DataLocation::Transient; + break; + default: + solAssert(false); + break; + } } else if ( dynamic_cast(_variable.scope()) || @@ -477,6 +494,9 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable) case Location::CallData: typeLoc = DataLocation::CallData; break; + case Location::Transient: + solUnimplemented("Transient data location cannot be used in this kind of variable or parameter declaration."); + break; case Location::Unspecified: solAssert(!_variable.hasReferenceOrMappingType(), "Data location not properly set."); } @@ -497,6 +517,9 @@ void DeclarationTypeChecker::endVisit(VariableDeclaration const& _variable) m_errorReporter.fatalTypeError(9259_error, _variable.location(), "Only constants of value type and byte array type are implemented."); } + if (!type->isValueType()) + solUnimplementedAssert(typeLoc != DataLocation::Transient, "Transient data location is only supported for value types."); + _variable.annotation().type = type; } diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index bae16967595b..a3aab07fba29 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -816,7 +816,9 @@ std::set VariableDeclaration::allowedDataLocation { using Location = VariableDeclaration::Location; - if (!hasReferenceOrMappingType() || isStateVariable() || isEventOrErrorParameter()) + if (isStateVariable()) + return std::set{Location::Unspecified, Location::Transient}; + else if (!hasReferenceOrMappingType() || isEventOrErrorParameter()) return std::set{ Location::Unspecified }; else if (isCallableOrCatchParameter()) { diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index d8b178377bd8..3494ab94b9b4 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -1052,7 +1052,7 @@ class FunctionDefinition: public CallableDeclaration, public StructurallyDocumen class VariableDeclaration: public Declaration, public StructurallyDocumented { public: - enum Location { Unspecified, Storage, Memory, CallData }; + enum Location { Unspecified, Storage, Transient, Memory, CallData }; enum class Mutability { Mutable, Immutable, Constant }; static std::string mutabilityToString(Mutability _mutability) { diff --git a/libsolidity/ast/ASTJsonExporter.cpp b/libsolidity/ast/ASTJsonExporter.cpp index f94b91674bcb..69f51618e3d4 100644 --- a/libsolidity/ast/ASTJsonExporter.cpp +++ b/libsolidity/ast/ASTJsonExporter.cpp @@ -1058,6 +1058,8 @@ std::string ASTJsonExporter::location(VariableDeclaration::Location _location) return "memory"; case VariableDeclaration::Location::CallData: return "calldata"; + case VariableDeclaration::Location::Transient: + return "transient"; } // To make the compiler happy return {}; diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index 5c1d4bdc0c30..728d77c0de8b 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -1190,6 +1190,8 @@ VariableDeclaration::Location ASTJsonImporter::location(Json const& _node) return VariableDeclaration::Location::Memory; else if (storageLocStr == "calldata") return VariableDeclaration::Location::CallData; + else if (storageLocStr == "transient") + return VariableDeclaration::Location::Transient; else astAssert(false, "Unknown location declaration"); diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 028b7667326f..a37cc78a4162 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1544,6 +1544,8 @@ TypeResult ReferenceType::unaryOperatorResult(Token _operator) const return TypeProvider::emptyTuple(); case DataLocation::Storage: return isPointer() ? nullptr : TypeProvider::emptyTuple(); + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); } return nullptr; } @@ -1571,6 +1573,9 @@ std::string ReferenceType::stringForReferencePart() const return "calldata"; case DataLocation::Memory: return "memory"; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; } solAssert(false, ""); return ""; @@ -1584,6 +1589,9 @@ std::string ReferenceType::identifierLocationSuffix() const case DataLocation::Storage: id += "_storage"; break; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::Memory: id += "_memory"; break; @@ -1748,6 +1756,9 @@ BoolResult ArrayType::validForLocation(DataLocation _loc) const if (storageSizeUpperBound() >= bigint(1) << 256) return BoolResult::err("Type too large for storage."); break; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; } return true; } @@ -1828,6 +1839,9 @@ std::vector> ArrayType::makeStackItems() co case DataLocation::Storage: // byte offset inside storage value is omitted return {std::make_tuple("slot", TypeProvider::uint256())}; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; } solAssert(false, ""); } @@ -2568,6 +2582,9 @@ std::vector> StructType::makeStackItems() c return {std::make_tuple("mpos", TypeProvider::uint256())}; case DataLocation::Storage: return {std::make_tuple("slot", TypeProvider::uint256())}; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; } solAssert(false, ""); } diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 3ab4a1d97ebc..1817c97af4dd 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -70,7 +70,7 @@ inline rational makeRational(bigint const& _numerator, bigint const& _denominato return rational(_numerator, _denominator); } -enum class DataLocation { Storage, CallData, Memory }; +enum class DataLocation { Storage, Transient, CallData, Memory }; /** diff --git a/libsolidity/codegen/ArrayUtils.cpp b/libsolidity/codegen/ArrayUtils.cpp index e73ddfbae819..e653239cfa1a 100644 --- a/libsolidity/codegen/ArrayUtils.cpp +++ b/libsolidity/codegen/ArrayUtils.cpp @@ -1021,6 +1021,9 @@ void ArrayUtils::retrieveLength(ArrayType const& _arrayType, unsigned _stackDept if (_arrayType.isByteArrayOrString()) m_context.callYulFunction(m_context.utilFunctions().extractByteArrayLengthFunction(), 1, 1); break; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; } } } @@ -1118,6 +1121,9 @@ void ArrayUtils::accessIndex(ArrayType const& _arrayType, bool _doBoundsCheck, b m_context << endTag; break; } + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; } } diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index bf4f25bf289e..822d9d3dab6a 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -1024,6 +1024,9 @@ void CompilerUtils::convertType( "Invalid conversion to storage type." ); break; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::Memory: { // Copy the array to a free position in memory, unless it is already in memory. @@ -1168,6 +1171,9 @@ void CompilerUtils::convertType( "Invalid conversion to storage type." ); break; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::Memory: // Copy the array to a free position in memory, unless it is already in memory. switch (typeOnStack.location()) @@ -1207,6 +1213,9 @@ void CompilerUtils::convertType( conversionImpl(m_context); break; } + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::CallData: { if (typeOnStack.isDynamicallyEncoded()) diff --git a/libsolidity/codegen/ContractCompiler.cpp b/libsolidity/codegen/ContractCompiler.cpp index 186cebc787c3..32fb9cae7bcf 100644 --- a/libsolidity/codegen/ContractCompiler.cpp +++ b/libsolidity/codegen/ContractCompiler.cpp @@ -592,6 +592,7 @@ void ContractCompiler::initializeStateVariables(ContractDefinition const& _contr bool ContractCompiler::visit(VariableDeclaration const& _variableDeclaration) { solAssert(_variableDeclaration.isStateVariable(), "Compiler visit to non-state variable declaration."); + solUnimplementedAssert(_variableDeclaration.referenceLocation() != VariableDeclaration::Location::Transient, "Transient storage variables not supported."); CompilerContext::LocationSetter locationSetter(m_context, _variableDeclaration); m_context.startFunction(_variableDeclaration); diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index c7bc9a8263f5..6027e0404850 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -2047,6 +2047,9 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) ArrayUtils(m_context).retrieveLength(type); m_context << Instruction::SWAP1 << Instruction::POP; break; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::Memory: m_context << Instruction::MLOAD; break; @@ -2193,6 +2196,9 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess) else setLValueToStorageItem(_indexAccess); break; + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::Memory: ArrayUtils(m_context).accessIndex(arrayType); setLValue(_indexAccess, *_indexAccess.annotation().type, !arrayType.isByteArrayOrString()); diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 9d1929fe1ef6..ebf1d384aa57 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -2563,6 +2563,9 @@ std::string YulUtilFunctions::nextArrayElementFunction(ArrayType const& _type) templ("advance", toCompactHexWithPrefix(size)); break; } + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::CallData: { u256 size = _type.calldataStride(); diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 2464fefc434b..2f823fcbf65c 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -47,6 +47,7 @@ #include #include +#include #include using namespace solidity; @@ -374,6 +375,15 @@ void IRGeneratorForStatements::endVisit(VariableDeclarationStatement const& _var { setLocation(_varDeclStatement); + auto static notTransient = [](std::shared_ptr const& _varDeclaration) { + return (_varDeclaration ? _varDeclaration->referenceLocation() != VariableDeclaration::Location::Transient : true); + }; + + solUnimplementedAssert( + ranges::all_of(_varDeclStatement.declarations(), notTransient), + "Transient storage variables are not supported." + ); + if (Expression const* expression = _varDeclStatement.initialValue()) { if (_varDeclStatement.declarations().size() > 1) @@ -2314,6 +2324,9 @@ void IRGeneratorForStatements::endVisit(IndexAccess const& _indexAccess) break; } + case DataLocation::Transient: + solUnimplemented("Transient data location is only supported for value types."); + break; case DataLocation::Memory: { std::string const indexAccessFunction = m_utils.memoryArrayIndexAccessFunction(arrayType); diff --git a/libsolidity/formal/BMC.cpp b/libsolidity/formal/BMC.cpp index b1a326fc77c4..2fc24f1f66d5 100644 --- a/libsolidity/formal/BMC.cpp +++ b/libsolidity/formal/BMC.cpp @@ -184,6 +184,9 @@ bool BMC::shouldInlineFunctionCall( bool BMC::visit(ContractDefinition const& _contract) { + // Raises UnimplementedFeatureError in the presence of transient storage variables + TransientDataLocationChecker checker(_contract); + initContract(_contract); SMTEncoder::visit(_contract); diff --git a/libsolidity/formal/CHC.cpp b/libsolidity/formal/CHC.cpp index 66ebd47edb98..5e372771240a 100644 --- a/libsolidity/formal/CHC.cpp +++ b/libsolidity/formal/CHC.cpp @@ -143,6 +143,9 @@ bool CHC::visit(ContractDefinition const& _contract) if (!shouldAnalyze(_contract)) return false; + // Raises UnimplementedFeatureError in the presence of transient storage variables + TransientDataLocationChecker checker(_contract); + resetContractAnalysis(); initContract(_contract); clearIndices(&_contract); diff --git a/libsolidity/formal/SMTEncoder.h b/libsolidity/formal/SMTEncoder.h index bea3a85ef9c8..77e618fedf0a 100644 --- a/libsolidity/formal/SMTEncoder.h +++ b/libsolidity/formal/SMTEncoder.h @@ -129,6 +129,19 @@ class SMTEncoder: public ASTConstVisitor static std::set sourceDependencies(SourceUnit const& _source); protected: + struct TransientDataLocationChecker: ASTConstVisitor + { + TransientDataLocationChecker(ContractDefinition const& _contract) { _contract.accept(*this); } + + void endVisit(VariableDeclaration const& _var) + { + solUnimplementedAssert( + _var.referenceLocation() != VariableDeclaration::Location::Transient, + "Transient storage variables are not supported." + ); + } + }; + void resetSourceAnalysis(); // TODO: Check that we do not have concurrent reads and writes to a variable, diff --git a/libsolidity/interface/StorageLayout.cpp b/libsolidity/interface/StorageLayout.cpp index 7f344f6edf65..0153af1a293a 100644 --- a/libsolidity/interface/StorageLayout.cpp +++ b/libsolidity/interface/StorageLayout.cpp @@ -46,6 +46,7 @@ Json StorageLayout::generate(ContractDefinition const& _contractDef) Json StorageLayout::generate(VariableDeclaration const& _var, u256 const& _slot, unsigned _offset) { + solUnimplementedAssert(_var.referenceLocation() != VariableDeclaration::Location::Transient, "Transient storage layout is not supported yet."); Json varEntry; Type const* varType = _var.type(); diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 7e2fe030af2c..b51eb9c44099 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -885,6 +885,19 @@ ASTPointer Parser::parseVariableDeclaration( } } } + else if ( + _options.kind == VarDeclKind::State && + token == Token::Identifier && + m_scanner->currentLiteral() == "transient" && + m_scanner->peekNextToken() != Token::Assign && + m_scanner->peekNextToken() != Token::Semicolon + ) + { + if (location != VariableDeclaration::Location::Unspecified) + parserError(ErrorId{3548}, "Location already specified."); + else + location = VariableDeclaration::Location::Transient; + } else break; nodeFactory.markEndPosition(); diff --git a/scripts/error_codes.py b/scripts/error_codes.py index 24ec2b06d617..54dd00c267ce 100755 --- a/scripts/error_codes.py +++ b/scripts/error_codes.py @@ -202,6 +202,7 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False): "4591", # "There are more than 256 warnings. Ignoring the rest." # Due to 3805, the warning lists look different for different compiler builds. "1920", # Unimplemented feature error from YulStack (currently there are no UnimplementedFeatureErrors thrown by libyul) + "7053", # Unimplemented feature error (parsing stage), currently has no tests "1180", # SMTChecker, covered by CL tests "2339", # SMTChecker, covered by CL tests "2961", # SMTChecker, covered by CL tests diff --git a/test/cmdlineTests/storage_layout_transient_value_types/in.sol b/test/cmdlineTests/storage_layout_transient_value_types/in.sol new file mode 100644 index 000000000000..ba7943c6a11b --- /dev/null +++ b/test/cmdlineTests/storage_layout_transient_value_types/in.sol @@ -0,0 +1,10 @@ +//SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +contract A { + uint transient x; + uint y; + bytes32 transient b; + bytes32 c; + address transient a; + address z; +} \ No newline at end of file diff --git a/test/cmdlineTests/storage_layout_transient_value_types/input.json b/test/cmdlineTests/storage_layout_transient_value_types/input.json new file mode 100644 index 000000000000..96d71ed30ec8 --- /dev/null +++ b/test/cmdlineTests/storage_layout_transient_value_types/input.json @@ -0,0 +1,13 @@ +{ + "language": "Solidity", + "sources": { + "fileA": {"urls": ["storage_layout_transient_value_types/in.sol"]} + }, + "settings": { + "outputSelection": { + "fileA": { + "A": ["storageLayout"] + } + } + } +} diff --git a/test/cmdlineTests/storage_layout_transient_value_types/output.json b/test/cmdlineTests/storage_layout_transient_value_types/output.json new file mode 100644 index 000000000000..a446210485f9 --- /dev/null +++ b/test/cmdlineTests/storage_layout_transient_value_types/output.json @@ -0,0 +1,11 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "Transient storage layout is not supported yet.", + "message": "Transient storage layout is not supported yet.", + "severity": "error", + "type": "UnimplementedFeatureError" + } + ] +} diff --git a/test/libsolidity/astPropertyTests/transient_data_location.sol b/test/libsolidity/astPropertyTests/transient_data_location.sol new file mode 100644 index 000000000000..6a937414d6bd --- /dev/null +++ b/test/libsolidity/astPropertyTests/transient_data_location.sol @@ -0,0 +1,8 @@ +contract C { + /// TestVarDataLocation: storageLocation + /// TestVarName: name + uint transient transient; +} +// ---- +// TestVarDataLocation: transient +// TestVarName: transient diff --git a/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol b/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol new file mode 100644 index 000000000000..b2dbc8efe5c7 --- /dev/null +++ b/test/libsolidity/smtCheckerTests/unsupported/transient_storage_state_variable.sol @@ -0,0 +1,8 @@ +contract C { + uint transient x = 42; + function test() public view { assert(x == 42); } +} +// ==== +// SMTEngine: all +// ---- +// UnimplementedFeatureError 1834: Transient storage variables are not supported. diff --git a/test/libsolidity/syntaxTests/constants/constant_state_variable_named_transient.sol b/test/libsolidity/syntaxTests/constants/constant_state_variable_named_transient.sol new file mode 100644 index 000000000000..4d9873d36d07 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/constant_state_variable_named_transient.sol @@ -0,0 +1,4 @@ +contract C { + int constant public transient = 0; +} +// ---- diff --git a/test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol b/test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol new file mode 100644 index 000000000000..f9a722a1b4a8 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/constant_transient_state_variable.sol @@ -0,0 +1,5 @@ +contract C { + int constant public transient x = 0; +} +// ---- +// DeclarationError 2197: (17-52): Transient cannot be used as data location for constant or immutable variables. diff --git a/test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type_fail.sol b/test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type_fail.sol index 4e5091e8c1cf..cd46b15b0716 100644 --- a/test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type_fail.sol +++ b/test/libsolidity/syntaxTests/dataLocations/data_location_in_function_type_fail.sol @@ -2,7 +2,10 @@ library L { struct Nested { uint y; } function b(function(Nested calldata) external returns (uint)[] storage) external pure {} function d(function(Nested storage) external returns (uint)[] storage) external pure {} + function f(function(Nested transient) external returns (uint)[] storage) external pure {} } // ---- +// Warning 6162: (251-267): Naming function type parameters is deprecated. // TypeError 6651: (159-173): Data location must be "memory" or "calldata" for parameter in function, but "storage" was given. +// TypeError 6651: (251-267): Data location must be "memory" or "calldata" for parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_transient.sol b/test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_transient.sol new file mode 100644 index 000000000000..98fbb2d5ee66 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/externalFunction/function_argument_location_specifier_test_external_transient.sol @@ -0,0 +1,5 @@ +contract test { + function f(bytes transient) external; +} +// ---- +// TypeError 6651: (31-46): Data location must be "memory" or "calldata" for parameter in external function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_transient.sol b/test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_transient.sol new file mode 100644 index 000000000000..4a5b6f999d86 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/internalFunction/function_argument_location_specifier_test_internal_transient.sol @@ -0,0 +1,5 @@ +contract test { + function f(bytes transient) internal {} +} +// ---- +// TypeError 6651: (31-46): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/libraries/library_function_with_data_location_transient.sol b/test/libsolidity/syntaxTests/dataLocations/libraries/library_function_with_data_location_transient.sol new file mode 100644 index 000000000000..75253342c4e0 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/libraries/library_function_with_data_location_transient.sol @@ -0,0 +1,19 @@ +library L { + function f1(uint[] transient) private pure { } + function f2() private pure returns (uint[] transient) { } + function g1(uint[] transient) internal pure { } + function g2() internal pure returns (uint[] transient) { } + function h1(uint[] transient) public pure { } + function h2() public pure returns (uint[] transient) { } + function i1(uint[] transient) external pure { } + function i2() external pure returns (uint[] transient) { } +} +// ---- +// TypeError 6651: (28-44): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given. +// TypeError 6651: (103-119): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given. +// TypeError 6651: (141-157): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given. +// TypeError 6651: (218-234): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given. +// TypeError 6651: (256-272): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given. +// TypeError 6651: (329-345): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given. +// TypeError 6651: (367-383): Data location must be "storage", "memory" or "calldata" for parameter in external function, but none was given. +// TypeError 6651: (444-460): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_transient.sol b/test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_transient.sol new file mode 100644 index 000000000000..1dcedf49adcf --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/libraryExternalFunction/function_argument_location_specifier_test_external_transient.sol @@ -0,0 +1,5 @@ +library test { + function f(bytes transient) external {} +} +// ---- +// TypeError 6651: (30-45): Data location must be "storage", "memory" or "calldata" for parameter in external function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_transient.sol b/test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_transient.sol new file mode 100644 index 000000000000..d66fa7fadd2d --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/libraryInternalFunction/function_argument_location_specifier_test_internal_transient.sol @@ -0,0 +1,5 @@ +library test { + function f(bytes transient) internal pure {} +} +// ---- +// TypeError 6651: (30-45): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/multiple_transient_data_location_function_parameter.sol b/test/libsolidity/syntaxTests/dataLocations/multiple_transient_data_location_function_parameter.sol new file mode 100644 index 000000000000..193565b2a00d --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/multiple_transient_data_location_function_parameter.sol @@ -0,0 +1,6 @@ +contract C { + function f(uint[] transient transient x) public pure { } +} + +// ---- +// ParserError 2314: (45-54): Expected ',' but got identifier diff --git a/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_parameters_location_transient.sol b/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_parameters_location_transient.sol new file mode 100644 index 000000000000..750aa4fee522 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_parameters_location_transient.sol @@ -0,0 +1,5 @@ +contract C { + function f(uint[] transient) private pure {} +} +// ---- +// TypeError 6651: (28-44): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_return_parameters_location_transient.sol b/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_return_parameters_location_transient.sol new file mode 100644 index 000000000000..d1bf8762480f --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/privateFunction/private_function_return_parameters_location_transient.sol @@ -0,0 +1,5 @@ +contract C { + function f() private pure returns (uint[] transient) {} +} +// ---- +// TypeError 6651: (52-68): Data location must be "storage", "memory" or "calldata" for return parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_transient.sol b/test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_transient.sol new file mode 100644 index 000000000000..ce4f42f469e4 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/publicFunction/function_argument_location_specifier_test_public_transient.sol @@ -0,0 +1,5 @@ +contract test { + function f(bytes transient) public; +} +// ---- +// TypeError 6651: (31-46): Data location must be "memory" or "calldata" for parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_return_parameters_location_transient.sol b/test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_return_parameters_location_transient.sol new file mode 100644 index 000000000000..862b7d236bfa --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/publicFunction/public_function_return_parameters_location_transient.sol @@ -0,0 +1,5 @@ +contract C { + function h() public pure returns(uint[] transient) {} +} +// ---- +// TypeError 6651: (50-66): Data location must be "memory" or "calldata" for return parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/dataLocations/state_variable_storage_named_transient.sol b/test/libsolidity/syntaxTests/dataLocations/state_variable_storage_named_transient.sol new file mode 100644 index 000000000000..afa6fd250308 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/state_variable_storage_named_transient.sol @@ -0,0 +1,5 @@ +contract C { + uint storage transient; +} +// ---- +// ParserError 2314: (22-29): Expected identifier but got 'storage' diff --git a/test/libsolidity/syntaxTests/dataLocations/state_variable_storage_transient.sol b/test/libsolidity/syntaxTests/dataLocations/state_variable_storage_transient.sol new file mode 100644 index 000000000000..d3fb023e0dbd --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/state_variable_storage_transient.sol @@ -0,0 +1,5 @@ +contract C { + uint storage transient x; +} +// ---- +// ParserError 2314: (22-29): Expected identifier but got 'storage' diff --git a/test/libsolidity/syntaxTests/dataLocations/state_variable_transient_storage.sol b/test/libsolidity/syntaxTests/dataLocations/state_variable_transient_storage.sol new file mode 100644 index 000000000000..53260194d1d2 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/state_variable_transient_storage.sol @@ -0,0 +1,5 @@ +contract C { + uint transient storage x; +} +// ---- +// ParserError 2314: (32-39): Expected identifier but got 'storage' diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol new file mode 100644 index 000000000000..b82f40267edd --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_dynamic_array_state_variable.sol @@ -0,0 +1,7 @@ +contract C { + uint[] transient x; +} +// ==== +// stopAfter: analysis +// ---- +// UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol new file mode 100644 index 000000000000..3f7cec2a7588 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_fixed_array_state_variable.sol @@ -0,0 +1,7 @@ +contract C { + uint[3] transient x; +} +// ==== +// stopAfter: analysis +// ---- +// UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol b/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol new file mode 100644 index 000000000000..9deba463c195 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_function_type.sol @@ -0,0 +1,11 @@ +contract C { + function () transient f; + function (uint) external transient y; + function () transient internal fti; + function () internal transient fit; + function () internal transient internal fiti; + function () internal internal transient fiit; +} +// ==== +// stopAfter: analysis +// ---- diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_function_type_parameter.sol b/test/libsolidity/syntaxTests/dataLocations/transient_function_type_parameter.sol new file mode 100644 index 000000000000..04f20e85c050 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_function_type_parameter.sol @@ -0,0 +1,5 @@ +contract C { + function (uint transient) external y; +} +// ---- +// Warning 6162: (27-41): Naming function type parameters is deprecated. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_local_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_local_variable.sol new file mode 100644 index 000000000000..7602a4cb9208 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_local_variable.sol @@ -0,0 +1,7 @@ +contract C { + function f() public pure { + uint transient x = 0; + } +} +// ---- +// ParserError 2314: (67-68): Expected ';' but got identifier diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol new file mode 100644 index 000000000000..cd762df30e62 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_mapping_state_variable.sol @@ -0,0 +1,7 @@ +contract C { + mapping(uint => uint) transient y; +} +// ==== +// stopAfter: analysis +// ---- +// UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol b/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol new file mode 100644 index 000000000000..2579d5532fee --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_state_variable_visibility.sol @@ -0,0 +1,12 @@ +contract C { + uint public transient pubt; + uint internal transient it; + uint private transient prvt; + + uint transient public tpub; + uint transient internal ti; + uint transient private tprv; +} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_struct_state_variable.sol b/test/libsolidity/syntaxTests/dataLocations/transient_struct_state_variable.sol new file mode 100644 index 000000000000..19612b9c5728 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_struct_state_variable.sol @@ -0,0 +1,12 @@ +struct S { + uint x; + address a; +} + +contract C { + S transient s; +} +// ==== +// stopAfter: analysis +// ---- +// UnimplementedFeatureError 1834: Transient data location is only supported for value types. diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol new file mode 100644 index 000000000000..55faa1495d99 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables.sol @@ -0,0 +1,12 @@ +contract D { } + +contract C { + address transient a; + bool transient b; + D transient d; + uint transient x; + bytes32 transient y; +} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol new file mode 100644 index 000000000000..10dad9e32fe9 --- /dev/null +++ b/test/libsolidity/syntaxTests/dataLocations/transient_value_type_state_variables_assignment.sol @@ -0,0 +1,10 @@ +contract D { } + +contract C { + int transient x = -99; + address transient a = address(0xABC); + bool transient b = x > 0 ? false : true; +} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/errors/invalid_parameter_location.sol b/test/libsolidity/syntaxTests/errors/invalid_parameter_location.sol index a116188d2375..38f1bd9af5b8 100644 --- a/test/libsolidity/syntaxTests/errors/invalid_parameter_location.sol +++ b/test/libsolidity/syntaxTests/errors/invalid_parameter_location.sol @@ -10,7 +10,12 @@ contract test { contract test { error e1(string calldata a); } +==== Source: D ==== +contract test { + error e1(string transient a); +} // ---- // ParserError 2314: (A:36-43): Expected ',' but got 'storage' // ParserError 2314: (B:36-42): Expected ',' but got 'memory' // ParserError 2314: (C:36-44): Expected ',' but got 'calldata' +// ParserError 2314: (D:46-47): Expected ',' but got identifier diff --git a/test/libsolidity/syntaxTests/events/invalid_parameter_location.sol b/test/libsolidity/syntaxTests/events/invalid_parameter_location.sol index 04ee9b7bc4b6..1f13bbf9085e 100644 --- a/test/libsolidity/syntaxTests/events/invalid_parameter_location.sol +++ b/test/libsolidity/syntaxTests/events/invalid_parameter_location.sol @@ -10,7 +10,12 @@ contract test { contract test { event e1(string calldata a); } +==== Source: D ==== +contract test { + event e1(string transient a); +} // ---- // ParserError 2314: (A:36-43): Expected ',' but got 'storage' // ParserError 2314: (B:36-42): Expected ',' but got 'memory' // ParserError 2314: (C:36-44): Expected ',' but got 'calldata' +// ParserError 2314: (D:46-47): Expected ',' but got identifier diff --git a/test/libsolidity/syntaxTests/events/transient_indexed_parameter.sol b/test/libsolidity/syntaxTests/events/transient_indexed_parameter.sol new file mode 100644 index 000000000000..718451de2fb6 --- /dev/null +++ b/test/libsolidity/syntaxTests/events/transient_indexed_parameter.sol @@ -0,0 +1,5 @@ +contract C { + event e(string indexed transient a); +} +// ---- +// ParserError 2314: (50-51): Expected ',' but got identifier diff --git a/test/libsolidity/syntaxTests/functionTypes/function_type_with_transient_param.sol b/test/libsolidity/syntaxTests/functionTypes/function_type_with_transient_param.sol new file mode 100644 index 000000000000..b38e37177ea1 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/function_type_with_transient_param.sol @@ -0,0 +1,8 @@ +contract C { + function (uint transient) external y; + function (uint[] transient) external z; +} +// ---- +// Warning 6162: (27-41): Naming function type parameters is deprecated. +// Warning 6162: (69-85): Naming function type parameters is deprecated. +// TypeError 6651: (69-85): Data location must be "memory" or "calldata" for parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_param_named_transient.sol b/test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_param_named_transient.sol new file mode 100644 index 000000000000..fd28841431d0 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_param_named_transient.sol @@ -0,0 +1,6 @@ +contract C { + function (uint transient) external transient y; +} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_transient_param.sol b/test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_transient_param.sol new file mode 100644 index 000000000000..74e5b3413d54 --- /dev/null +++ b/test/libsolidity/syntaxTests/functionTypes/transient_function_type_with_transient_param.sol @@ -0,0 +1,5 @@ +contract C { + function (uint transient x) external transient y; +} +// ---- +// ParserError 2314: (42-43): Expected ',' but got identifier diff --git a/test/libsolidity/syntaxTests/immutable/immutable_state_var_named_transient.sol b/test/libsolidity/syntaxTests/immutable/immutable_state_var_named_transient.sol new file mode 100644 index 000000000000..c0ac3a8abb3c --- /dev/null +++ b/test/libsolidity/syntaxTests/immutable/immutable_state_var_named_transient.sol @@ -0,0 +1,4 @@ +contract C { + address public immutable transient; +} +// ---- diff --git a/test/libsolidity/syntaxTests/immutable/state_var_transient_data_location.sol b/test/libsolidity/syntaxTests/immutable/state_var_transient_data_location.sol new file mode 100644 index 000000000000..a3d93848d9a2 --- /dev/null +++ b/test/libsolidity/syntaxTests/immutable/state_var_transient_data_location.sol @@ -0,0 +1,5 @@ +contract C { + uint public immutable transient x; +} +// ---- +// DeclarationError 2197: (17-50): Transient cannot be used as data location for constant or immutable variables. diff --git a/test/libsolidity/syntaxTests/modifiers/multiple_parameter_location.sol b/test/libsolidity/syntaxTests/modifiers/multiple_parameter_location.sol index e264a593ff2c..24bb1cc32e7d 100644 --- a/test/libsolidity/syntaxTests/modifiers/multiple_parameter_location.sol +++ b/test/libsolidity/syntaxTests/modifiers/multiple_parameter_location.sol @@ -8,6 +8,12 @@ contract A { modifier mod7(string calldata storage a) { _; } modifier mod8(string calldata memory a) { _; } modifier mod9(string calldata calldata a) { _; } + modifier modA(string transient storage a) { _; } + modifier modB(string transient memory a) { _; } + modifier modC(string transient calldata a) { _; } + modifier modD(string storage transient a) { _; } + modifier modE(string memory transient a) { _; } + modifier modF(string calldata transient a) { _; } } // ---- // ParserError 3548: (46-53): Location already specified. @@ -19,3 +25,4 @@ contract A { // ParserError 3548: (350-357): Location already specified. // ParserError 3548: (402-408): Location already specified. // ParserError 3548: (453-461): Location already specified. +// ParserError 2314: (507-514): Expected ',' but got 'storage' diff --git a/test/libsolidity/syntaxTests/modifiers/transient_parameter.sol b/test/libsolidity/syntaxTests/modifiers/transient_parameter.sol new file mode 100644 index 000000000000..be90ca54dc39 --- /dev/null +++ b/test/libsolidity/syntaxTests/modifiers/transient_parameter.sol @@ -0,0 +1,5 @@ +contract A { + modifier mod2(uint[] transient) { _; } +} +// ---- +// TypeError 6651: (31-47): Data location must be "storage", "memory" or "calldata" for parameter in function, but none was given. diff --git a/test/libsolidity/syntaxTests/operators/transient_value_type.sol b/test/libsolidity/syntaxTests/operators/transient_value_type.sol new file mode 100644 index 000000000000..3d83fe240798 --- /dev/null +++ b/test/libsolidity/syntaxTests/operators/transient_value_type.sol @@ -0,0 +1,11 @@ +contract C { + int transient x; + function f() public view returns (int) { + int y = x; + int w = -x; + return (x + w) * (y / x); + } +} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/parsing/contract_named_transient.sol b/test/libsolidity/syntaxTests/parsing/contract_named_transient.sol new file mode 100644 index 000000000000..853396f21bb5 --- /dev/null +++ b/test/libsolidity/syntaxTests/parsing/contract_named_transient.sol @@ -0,0 +1 @@ +contract transient {} diff --git a/test/libsolidity/syntaxTests/structs/transient_data_location_member.sol b/test/libsolidity/syntaxTests/structs/transient_data_location_member.sol new file mode 100644 index 000000000000..110d4969a6cc --- /dev/null +++ b/test/libsolidity/syntaxTests/structs/transient_data_location_member.sol @@ -0,0 +1,5 @@ +struct S { + int transient x; +} +// ---- +// ParserError 2314: (29-30): Expected ';' but got identifier diff --git a/test/libsolidity/syntaxTests/types/address/state_variable_address_payable_transient.sol b/test/libsolidity/syntaxTests/types/address/state_variable_address_payable_transient.sol new file mode 100644 index 000000000000..0cab967225c5 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/address/state_variable_address_payable_transient.sol @@ -0,0 +1,6 @@ +contract C { + address payable transient a; +} +// ==== +// stopAfter: parsing +// ---- diff --git a/test/libsolidity/syntaxTests/types/address/state_variable_address_transient_payable.sol b/test/libsolidity/syntaxTests/types/address/state_variable_address_transient_payable.sol new file mode 100644 index 000000000000..16d8adb493f8 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/address/state_variable_address_transient_payable.sol @@ -0,0 +1,5 @@ +contract C { + address transient payable a; +} +// ---- +// ParserError 2314: (35-42): Expected identifier but got 'payable' diff --git a/test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier.sol b/test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier.sol new file mode 100644 index 000000000000..ced189faf061 --- /dev/null +++ b/test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier.sol @@ -0,0 +1,25 @@ +contract C { + function transient() public pure { } +} + +error CustomError(uint transient); +event e1(uint transient); +event e2(uint indexed transient); + +struct S { + int transient; +} + +contract D { + function f() public pure returns (uint) { + uint transient = 1; + return transient; + } + + function g(int transient) public pure { } + + modifier m(address transient) { + _; + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier_and_data_location.sol b/test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier_and_data_location.sol new file mode 100644 index 000000000000..532df5ba00a3 --- /dev/null +++ b/test/libsolidity/syntaxTests/variableDeclaration/transient_as_identifier_and_data_location.sol @@ -0,0 +1,6 @@ +contract C { + uint transient transient; +} +// ==== +// stopAfter: parsing +// ----