summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/passes/GlobalTypeOptimization.cpp25
1 files changed, 18 insertions, 7 deletions
diff --git a/src/passes/GlobalTypeOptimization.cpp b/src/passes/GlobalTypeOptimization.cpp
index e35e30ac8..0baecdf43 100644
--- a/src/passes/GlobalTypeOptimization.cpp
+++ b/src/passes/GlobalTypeOptimization.cpp
@@ -203,13 +203,24 @@ struct GlobalTypeOptimization : public Pass {
// visibility, so do that here: we can only become immutable if the
// parent can as well.
auto super = type.getDeclaredSuperType();
- if (super && !canBecomeImmutable.count(*super)) {
- // No entry in canBecomeImmutable means nothing in the parent can
- // become immutable. We don't need to check the specific field index,
- // because visibility affects them all equally (i.e., if it is public
- // then no field can be changed, and if it is private then this field
- // can be changed, and perhaps more).
- continue;
+ if (super) {
+ // The super may not contain the field, which is fine, so only check
+ // here if the field does exist in both.
+ if (i < super->getStruct().fields.size()) {
+ // No entry in canBecomeImmutable means nothing in the parent can
+ // become immutable, so check for both that and for an entry with
+ // "false".
+ auto iter = canBecomeImmutable.find(*super);
+ if (iter == canBecomeImmutable.end()) {
+ continue;
+ }
+ // The vector is grown only when needed to contain a "true" value,
+ // so |i| being out of bounds indicates "false".
+ auto& superVec = iter->second;
+ if (i >= superVec.size() || !superVec[i]) {
+ continue;
+ }
+ }
}
// No set exists. Mark it as something we can make immutable.