aboutsummaryrefslogtreecommitdiff
path: root/src/compiler/base.zc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/base.zc')
-rw-r--r--src/compiler/base.zc30
1 files changed, 23 insertions, 7 deletions
diff --git a/src/compiler/base.zc b/src/compiler/base.zc
index dc786b5..32549d4 100644
--- a/src/compiler/base.zc
+++ b/src/compiler/base.zc
@@ -958,6 +958,27 @@ int cerr(char* msg) {
if (fchk && live) serr(msg);
return 0;
}
+// how an owner ended, from end_owner's record: the use, the owner, what ended it and where.
+// "r: used after it was given away; r borrows t, and t was freed on line 5 (t declared on line 4)"
+int ended_message(char* use, word info, char* root, int cause) {
+ char* owner = root; int why = 0; char* whom = 0;
+ if (info) { owner = info[0]; why = info[3]; whom = info[4]; }
+ rt.put_s(use); rt.put_s(": used after it was given away; ");
+ if (!rt.eq_w(use, owner)) { rt.put_s(use); rt.put_s(" borrows "); rt.put_s(owner); rt.put_s(", and "); }
+ rt.put_s(owner);
+ if (why == 1) rt.put_s(" was freed");
+ else if (why == 2) { rt.put_s(" was given to "); rt.put_s(whom); rt.put_s("'s .d parameter"); }
+ else if (why == 3) { rt.put_s(" was moved into "); rt.put_s(whom); }
+ else if (why == 4) { rt.put_s(" was stored into "); rt.put_s(whom); }
+ else if (why == 5) rt.put_s(" was returned");
+ else if (why == 6) rt.put_s(" was stored in a global or untracked memory");
+ else if (why == 7) rt.put_s(" was freed by reassigning it");
+ else if (why == 8) rt.put_s(" was pushed into an array");
+ else rt.put_s(" was transferred");
+ rt.put_s(" on line "); rt.put_n(cause & 0xFFFFFF);
+ if (info && info[1]) { rt.put_s(" ("); if (!rt.eq_w(use, owner)) { rt.put_s(owner); rt.put_c(' '); } rt.put_s("declared on line "); rt.put_n(info[1] & 0xFFFFFF); rt.put_c(')'); }
+ return 0;
+}
// report an analyzer error about local i, named in the message.
int cerrn(int i, char* msg) {
int root = i, cause = 0; word info = 0;
@@ -967,13 +988,8 @@ int cerrn(int i, char* msg) {
if (!info && local_end_info) info = local_end_info[root];
if (info) cause = info[2]; else if (local_ended) cause = local_ended[root];
}
- if (cause && !panic && !dry) {
- errat(); rt.put_s(lname[i]); rt.put_s(": "); rt.put_s(msg);
- rt.put_s("; owner "); if (info) rt.put_s(info[0]); else rt.put_s(lname[root]);
- rt.put_s(" was transferred on line "); rt.put_n(cause & 0xFFFFFF);
- if (info && info[1]) { rt.put_s(" (declared on line "); rt.put_n(info[1] & 0xFFFFFF); rt.put_c(')'); }
- errend();
- } else serrn(lname[i], msg);
+ if (cause && !panic && !dry) { errat(); ended_message(lname[i], info, lname[root], cause); errend(); }
+ else serrn(lname[i], msg);
}
return 0;
}