You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add const checking for elements of tuple formals (#16041)
Add const checking for elements of tuple formals (#16041)
This PR adjusts the compiler to emit errors when a const element of
a tuple formal is modified. Prior to this PR the compiler would
compile programs such as the following without incident:
```chapel
record r { var x: int = 0; }
proc modifyDefaultIntentFormal(tup) {
tup[1] = new r(128);
}
proc test() {
const a = (0, new r(0));
modifyDefaultIntentFormal(a);
writeln(a);
}
test();
```
The call to `modifyDefaultIntentFormal` incorrectly modifies the
second element of the tuple formal `tup`. Because `tup` has the
default argument intent, its second element should be passed by
`const ref` (because it is a record). Any modification of `tup[1]`
within the body of `modifyDefaultIntentFormal` should emit an error.
---
- Add a function `checkTupleFormalUses` to `lateConstCheck`. This
method checks to make sure the constness of `const ref` tuple
elements is not violated. If a field should be const but is set to
`QUAL_REF` by `cullOverReferences`, then emit an error. The
location that is reported is an imprecise guess - future work
should make this reporting as precise as possible and provide more
context for the use.
- Use a set of `FnSymbol*` in the `for_formals_actuals` loop in
`lateConstCheck` so that `const ref` elements of tuple formals are
checked once per function instead of once per call.
- Add a function `checkTupleFormalToActual` to `lateConstCheck`. This
function checks ref/ref-if-modified elements of tuple formals. If
the element is ref (or inferred to be ref) and the actual element
is const, then emit an error. If the element is ref-if-modified,
then provide an imprecise hint about where it is used. Future work
should make this hint more precise.
- Infer the concrete intent of blank tuple formals that contain
single/sync/atomic elements to be `INTENT_REF_MAYBE_CONST`. The
blank intent for single/sync/atomic elements is `ref`. It does not
make sense to infer the intent of the entire tuple as `INTENT_REF`
if it contains such an element, so mimic what we do for blank
intent tuples containing arrays.
- Fix a bug in `CullRefCtx::collectTuplesAndRefMaybeConstArgs` that
caused the compiler to collect a _reference_ to a tuple for
analysis instead of the tuple itself.
- Adjust `CullRefCtx::checkTupleCastCall` to only collect the LHS of
a tuple cast call as a dependency if it contains `ref` elements.
If the LHS is a value tuple, the compiler need not be concerned
with how it is used.
- In `CullRefCtx::checkAccessorLikeCall`, do not add the LHS as a
dependency if it is known to be constant. Any misuse of a const LHS
should have already been reported in a previous pass.
- In `CullRefCtx::checkRefMaybeConstFormal`, escape early if the
function being called has flag `FLAG_REF_TO_CONST_WHEN_CONST_THIS`
and the actual is a `const` method receiver. Otherwise, we add a
false dependency that the compiler may consider a "setting" use.
- Add debugging tools to `lateConstCheck`.
- Clean up `lateConstCheck` by moving calls to skip into a function
`isCallToSkip`. Additional "light" refactoring might help with
integrating new code into the rest of the pass.
- Adjust the IO proc <~> for writing channels so that the element to
write is `const`.
- Adjust the tests `types/tuple/dinan/pining_for_lisp.chpl` and
`pining_for_lisp_ver2.chpl` so that their `car` and `cdr` functions
return `const ref` instead of `ref`.
- Add two tests to `types/tuple/const` that verify that the constness
of tuple elements is respected for blank/const tuples of almost
every element type. Future work should adjust the tests for tuples
of sync/single when those are permitted in tuples. Future work
should adjust the tests for tuples containing `dmap`, if possible.
---
Future work:
- Adjust `cullOverReferences` to store field index in addition to
`ASTNode*` in the `reasonNotConst` map, and then use this
information to print out more accurate error messages in
`checkTupleFormalUses` and `checkTupleFormalToActual`.
- Better integrate error reporting for tuples with existing error
reporting in `lateConstCheck`.
- Do const checking for tuple elements of tuples.
- Add tests checking constness for tuples containing `sync` and
`single` when appropriate.
---
Testing:
- [x] ALL on linux64 when CHPL_COMM=none
- [x] ALL on linux64 when CHPL_COMM=gasnet
---
Reviewed by @mppf. Thanks!
0 commit comments