diff --git a/Changelog.md b/Changelog.md index 837c0f1b9..fa4e46800 100644 --- a/Changelog.md +++ b/Changelog.md @@ -19,6 +19,7 @@ Bugfixes: * NatSpec: Do not consider ``////`` and ``/***`` as NatSpec comments. * Type Checker: Fix internal error related to ``using for`` applied to non-libraries. * Type Checker: Do not disallow assigning to calldata variables. + * Type Checker: Disallow constructor parameters with ``calldata`` data location. * Wasm backend: Fix code generation for for-loops with pre statements. * Yul: Fix source location of variable multi-assignment. diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index f3f79f451..cba5bccc3 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -588,6 +588,15 @@ bool VariableDeclaration::isInternalCallableParameter() const return false; } +bool VariableDeclaration::isConstructorParameter() const +{ + if (!isCallableOrCatchParameter()) + return false; + if (auto const* function = dynamic_cast(scope())) + return function->isConstructor(); + return false; +} + bool VariableDeclaration::isLibraryFunctionParameter() const { if (!isCallableOrCatchParameter()) @@ -622,7 +631,7 @@ set VariableDeclaration::allowedDataLocations() c set locations{ Location::Memory }; if (isInternalCallableParameter() || isLibraryFunctionParameter() || isTryCatchParameter()) locations.insert(Location::Storage); - if (!isTryCatchParameter()) + if (!isTryCatchParameter() && !isConstructorParameter()) locations.insert(Location::CallData); return locations; diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 88c3e1beb..34fefeb0a 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -928,6 +928,7 @@ public: /// @returns true if this variable is a parameter or return parameter of an internal function /// or a function type of internal visibility. bool isInternalCallableParameter() const; + bool isConstructorParameter() const; /// @returns true iff this variable is a parameter(or return parameter of a library function bool isLibraryFunctionParameter() const; /// @returns true if the type of the variable does not need to be specified, i.e. it is declared diff --git a/test/libsolidity/syntaxTests/constructor/calldata_constructor_args.sol b/test/libsolidity/syntaxTests/constructor/calldata_constructor_args.sol new file mode 100644 index 000000000..c4ce52102 --- /dev/null +++ b/test/libsolidity/syntaxTests/constructor/calldata_constructor_args.sol @@ -0,0 +1,5 @@ +contract C { + constructor(uint[] calldata) public {} +} +// ---- +// TypeError 6651: (29-44): Data location must be "memory" for parameter in function, but "calldata" was given.