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:
|
case VariableOccurrence::Kind::Return:
|
||||||
if (unassignedVariables.count(&variableOccurrence.declaration()))
|
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
|
// 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
|
// 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).
|
// 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())
|
if (variableOccurrence->occurrence())
|
||||||
ssl.append("The variable was declared here.", variableOccurrence->declaration().location());
|
ssl.append("The variable was declared here.", variableOccurrence->declaration().location());
|
||||||
|
|
||||||
|
bool isStorage = variableOccurrence->declaration().type()->dataStoredIn(DataLocation::Storage);
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
3464_error,
|
3464_error,
|
||||||
variableOccurrence->occurrence() ?
|
variableOccurrence->occurrence() ?
|
||||||
*variableOccurrence->occurrence() :
|
*variableOccurrence->occurrence() :
|
||||||
variableOccurrence->declaration().location(),
|
variableOccurrence->declaration().location(),
|
||||||
ssl,
|
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") +
|
(variableOccurrence->kind() == VariableOccurrence::Kind::Return ? "returned" : "accessed") +
|
||||||
" without prior assignment, which would lead to undefined behaviour."
|
" 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