mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Checks for uninitialized access to calldata variables.
This commit is contained in:
parent
fb40a8abb8
commit
33450619b1
@ -94,7 +94,10 @@ void ControlFlowAnalyzer::checkUninitializedAccess(CFGNode const* _entry, CFGNod
|
||||
case VariableOccurrence::Kind::Return:
|
||||
if (unassignedVariables.count(&variableOccurrence.declaration()))
|
||||
{
|
||||
if (variableOccurrence.declaration().type()->dataStoredIn(DataLocation::Storage))
|
||||
if (
|
||||
variableOccurrence.declaration().type()->dataStoredIn(DataLocation::Storage) ||
|
||||
variableOccurrence.declaration().type()->dataStoredIn(DataLocation::CallData)
|
||||
)
|
||||
// Merely store the unassigned access. We do not generate an error right away, since this
|
||||
// path might still always revert. It is only an error if this is propagated to the exit
|
||||
// node of the function (i.e. there is a path with an uninitialized access).
|
||||
@ -135,13 +138,16 @@ void ControlFlowAnalyzer::checkUninitializedAccess(CFGNode const* _entry, CFGNod
|
||||
if (variableOccurrence->occurrence())
|
||||
ssl.append("The variable was declared here.", variableOccurrence->declaration().location());
|
||||
|
||||
bool isStorage = variableOccurrence->declaration().type()->dataStoredIn(DataLocation::Storage);
|
||||
m_errorReporter.typeError(
|
||||
3464_error,
|
||||
variableOccurrence->occurrence() ?
|
||||
*variableOccurrence->occurrence() :
|
||||
variableOccurrence->declaration().location(),
|
||||
ssl,
|
||||
string("This variable is of storage pointer type and can be ") +
|
||||
"This variable is of " +
|
||||
string(isStorage ? "storage" : "calldata") +
|
||||
" pointer type and can be " +
|
||||
(variableOccurrence->kind() == VariableOccurrence::Kind::Return ? "returned" : "accessed") +
|
||||
" without prior assignment, which would lead to undefined behaviour."
|
||||
);
|
||||
|
@ -0,0 +1,10 @@
|
||||
contract C {
|
||||
function f(uint[] calldata _c) public pure {
|
||||
uint[] calldata c;
|
||||
if (_c[2] > 10)
|
||||
c = _c;
|
||||
c[2];
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// TypeError: (141-142): This variable is of calldata pointer type and can be accessed without prior assignment, which would lead to undefined behaviour.
|
@ -0,0 +1,11 @@
|
||||
contract C {
|
||||
function f(uint[] calldata _c) public pure {
|
||||
uint[] calldata c;
|
||||
if (_c[2] > 10)
|
||||
c = _c;
|
||||
else
|
||||
c = _c;
|
||||
c[2];
|
||||
}
|
||||
}
|
||||
// ----
|
@ -0,0 +1,16 @@
|
||||
contract C {
|
||||
function g() internal pure returns (bytes calldata) {
|
||||
return msg.data;
|
||||
}
|
||||
function h(uint[] calldata _c) internal pure {
|
||||
uint[] calldata c;
|
||||
c = _c;
|
||||
c[2];
|
||||
}
|
||||
function i(uint[] calldata _c) internal pure {
|
||||
uint[] calldata c;
|
||||
(c) = _c;
|
||||
c[2];
|
||||
}
|
||||
}
|
||||
// ----
|
Loading…
Reference in New Issue
Block a user