База ошибок - LuNA-Static-Analysis/LuNA-Static-Analysis-Repository GitHub Wiki
Примеры программ могут опускать некоторые элементы (наличие ФК main, объявление ФД и атомарных ФК и т.д.).
LuNA:
import printVal(real) as print; sub main(){ print(1.0); }
C++:
void printVal(int val) { // int не соответствует real printf(“%d\n”, val); }
Реакция:
вывод случайного целого числа.
LuNA:
import printstr(string) as prints; //неверно написано название подпрограммы sub main(){ print("129.0"); }
Реакция: ошибка компиляции
LuNA:
import c_init(int, name) as init; sub main(){ df x; init(1, x[1]); init(2, x[1]); }
C++:
void c_init(int val, OutputDF &df){ df.setValue(val); }
Реакция: ошибка в рантайме
Частный случай: неверный порядок аргументов при вызове.
LuNA:
import c_init(int, name) as init; sub main(){ df res; init(res[0], 10); }
Реакция: ошибка компиляции
В случае использования констант возникает ошибка компиляции, поскольку тип выражений известен. В случае же использования ФД тип значения известен лишь в рантайме. Попытка пронести string туда, где нужен int (фактически несоответствие типов LuNA и C++):
LuNA:
import printfl(real) as print; import c_init_string(string, name) as inits; sub main(){ df a; inits("text", a); print(a); }
Реакция: ошибка в рантайме
LuNA:
import c_print(real) as printFloat; sub main(){ df x; printFloat(x[0]); }
Может произойти, например, из-за неверного определения границ оператора for (обе границы достигаются):
LuNA:
init(1, x[0]); for i = 0..1 { print(x[i]); }
Реакция:
программа зависнет (один блок будет вечно ждать результатов ФВ, хотя самого ФВ нет). Стоит отметить, что ФВ независимы, и программа может частично посчитать необходимое.
LuNA:
sub solve(int size, name a, name x, name b, int iterations){ *тело* } sub main(){ solve(a, x, b, iterations); }
Реакция:
LuNA:
sub main() { df x; df y; }
Реакция:
LuNA:
C++:
Реакция:
программа срабатывает.
Две вариации. Первая — объявлено базовое имя (имя после ключевого слова "df"), которое не было более использовано для порождения ФД. Пример:
LuNA:
import print(real) as print; sub main(){ df x; print(1.0); }
Вторая вариация — ФД был инициализирован, но не был использован. Пример:
LuNA:
import init(real, name) as init; sub main(){ df x; init(1.0, x); }
Реакция:
в обоих случаях программа сработает.
LuNA:
import printa(real) as print; import printb(real) as print; sub main(){ print(1.0); }
Реакция:
программа сработает, вызовется printb (т.е. вызывается последняя функция).
LuNA:
Реакция:
LuNA:
Реакция:
LuNA:
import c_init_float(real, name) as initFloat; sub main(){ initFloat(3, a); }
Реакция:
LuNA:
import c_init_float(real, name) as initFloat; sub main(){ df a, b; initFloat(a, b); initFloat(b, a); }
Реакция:
программа зависнет.
LuNA:
import c_init_float(real, name) as init; import c_init_int(int, name) as init; sub main(){ df a; init(3, a); }
Реакция:
программа выполнится (выполнится последний импортированный ФК с этим именем, т.е. c_init_int).
LuNA:
import c_init_float(real, name) as initFloat;// c_init_float() отсутствует в ucodes.cpp sub main(){ df a; initFloat(3, a); }
Реакция:
[18.] Несоответствие границ циклов инициалиации и использования - Нижняя граница цикла использования может быть как больше, так и меньше нижней границы цикла инициализации
LuNA:
import c_init(name, int) as init;
import c_print(value) as print;
sub main() {
df x, N, M;
// Инициализация M и N
for i = N..M { init(x[i], i); }
for i = 1..M { print(x[i]); }
}
N
программа может как отработать корректно, так и зависнуть при попытке распечатать x[N]..x[0]
, если N
меньше 1, так как эти ФД не будут инициализированы.
[19.] Несоответствие границ циклов инициалиации и использования - Нижняя граница цикла использования строго меньше нижней границы цикла инициализации
LuNA:
import c_init(name, int) as init;
import c_print(value) as print;
sub main() {
df x, N, M;
// Инициализация M и N
for i = N..M { init(x[i], i); }
for i = (N - 2)..M { print(x[i]); }
}
x[N-1]
и x[N-2]
, так как эти ФД не были инициализированы.
[20.] Несоответствие границ циклов инициалиации и использования - Верхняя граница цикла использования может быть как меньше, так и больше верхней границы цикла инициализации
LuNA:
import c_init(name, int) as init;
import c_print(value) as print;
sub main() {
df x, N;
// Инициализация N
for i = 1..N { init(x[i], i); }
for i = 1..10 { print(x[i]); }
}
N
программа может как отработать корректно, так и зависнуть при попытке распечатать x[11]..x[N]
, если N
больше 10, так как эти ФД не будут инициализированы.
[21.] Несоответствие границ циклов инициалиации и использования - Верхняя граница цикла использования строго больше верхней границы цикла инициализации
LuNA:
import c_init(name, int) as init;
import c_print(value) as print;
sub main() {
df x, N;
// Инициализация N
for i = 1..N { init(x[i], i); }
for i = 1..(N+10) { print(x[i]); }
}
x[N+1]..x[N+10]
, так как эти ФД не были инициализированы.
LuNA:
import c_init(name, int) as init;
import c_print(value) as print;
sub init_1(name arr, int ind) {
init(arr[ind], 0);
}
sub main() {
df x;
for i = 0..100 {
init_1(x, 2*i+1);
}
for i = 0..66 {
print(x[3*i+1]);
}
}
Реакция: программа зависнет, так как будут использованы неинициализированные ФД.
LuNA (пример 1 - условие всегда ложно):
import c_init_float(real, name) as initFloat;
sub main(){
df a, x, y;
if 1 == 2 {
initFloat(3, a);
}
}
Реакция: Программа отработает корректно, но if вместе с его телом можно убрать без изменения поведения программы.
LuNA (пример 2 - условие всегда истинно):
import c_init_float(real, name) as initFloat;
sub main(){
df a, x, y;
if x[0] <= y || x[0] > y {
initFloat(3, a);
}
}
Реакция: Программа отработает корректно, но if можно заменить его телом без изменения поведения программы.
LuNA:
import c_print(int) as print;
sub print_if_gt_5(int n) {
if n > 5 {
print(n);
}
}
sub main() {
print_if_gt_5(7); // -> if 7 > 5
print_if_gt_5(8); // -> if 8 > 5
}
Реакция: Программа отработает корректно, но if можно заменить его телом.
LuNA:
import c_print(int) as print;
import c_init(name, int) as init;
sub main() {
df x, N;
init(x, 42);
init(N, 10);
if 0 < x < N {
print(x);
}
}
Реакция: Программа напечатает 42, хотя интуиция подсказывает, что 42 не меньше 10. Прчина в том, что в LuNA не поддерживаются цепочки сравнений, и выражение 0 < x < N
будет эквивалентно не 0 < x && x < N
, а (0 < x) < N
.
LuNA:
import c_init_float(real, name) as initFloat; sub main(){ df a, b; init(1, a + b); }
Реакция:
Частный случай — попытка инициализации luna_cast (ошибка на этапе компиляции):
LuNA:
sub main() { df x, y; init(1, x); print(x) @ { request y; }; }
Реакция:
программа зависнет в ожидании инициализации запрашиваемого ФД.
LuNA:
sub main() { df x; init(1, x) @ { req_count x = 1; }; print(x); print(x); }
Реакция:
программа зависнет в ожидании инициализации ФД, поскольку он был удален сборщиком мусора после первого использования.
LuNA:
sub main() { df x; init(1, x) --> (x); print(x); }
Реакция:
программа зависнет в ожидании инициализации ФД, поскольку он был удален сборщиком мусора вслед за инициализацией.
Уточнение: возможно это баг системы.
LuNA:
sub set_value(int val, name x) { init(1, x); } sub main() { df x, flag; set_value(1, x) >> (flag); if (flag) { print(x); } }
Реакция:
программа зависнет, поскольку значение во flag никогда не будет установлено.
LuNA:
sub print_value(name x) { print(x); } @ { locator_cyclic x => n; nfparam n; } sub main() { df x; init(1, x); print_value(x); } @ { locator_cyclic x => 0; }
Реакция:
ошибка в момент попытки выполнить ФВ:
Ошибка характерна только для приложений с числом узлов больше 1. Стоит отметить, что значение ФД будет корректно установлено, в чём можно убедиться, выполнив ФВ, где значение номера узла будет верным.
LuNA:
sub print_value(name x) { print(x); } @ { locator_cyclic x => 1; } sub main() { df x; init(1, x) @ { locator_cyclic x => 1;}; print(x); /* deadlock */ print_value(x); /* 1 */ } @ { locator_cyclic x => 0; }
Реакция:
программа зависнет.
Ошибка характерна только для приложений с числом узлов больше 1.
LuNA:
sub print_value(name x) { print(x); } @ { locator_cyclic x => n; nfparam n; } sub main() { df x; init(1, x); print_value(x) @ { nfparam n => 1; }; } @ { locator_cyclic x => 0; }
Реакция:
программа зависнет.
sub main() { main(); }
Реакция:
программа зависнет.
Ошибка возникает тогда, когда несколько циклов инициализации одного и того же индексированного ФД (потенциально) инициализируют одни и те же индексы.
Примеры:
import c_init(name, int) as init; import c_print(value) as print; sub init_1(name arr, int ind) { init(arr[ind], 0); } sub main() { df y, z, k, N, M; for i = 0..N { init_1(k, 5*i+5); } for i = M..20 { init_1(k, 5*i+5); } for i = 0..N { init_1(y, i + 1); } for i = N+1..N+10 { init_1(y, i); } for i = N..N+10 { init(z[2*i+3], 0); } for j = N+11..N+20 { init(z[j], 0); } }
Реакция:
Для циклов инициализации k
- в зависимости от значений M
и N
программа может упасть из-за повторной инициализации
k[M]..k[N]
.
Для циклов инициализации y
- y[N+1]
будет инициализирован дважды из-за смещения +1
в первом цикле.
Для циклов инициализации z
- если 2*N+23
не меньше N+11
(например, верно при N=10
), ФД y[N+11]..y[2*N+23]
будут инициализированы дважды.
Пример с let, который является фактически подстановкой на стадии компиляции:
LuNA:
sub main() { df a; let x = a + 1 { init(1.0, x[0]); } }
Реакция: ошибка компиляции
Примеры с вызовом структурированного ФК (в первом случае ФД это name, во втором real):
LuNA:
sub main() { df a; foo(a + 1); } sub foo(name f){ init(1.0, f[0]); }
Реакция: ошибка компиляции
LuNA:
import c_init_float(real, name) as init; sub main() { df a; foo(a + 1); } sub foo(real f){ init(1.0, f[0]); }
Реакция: ошибка компиляции
Ошибка возникает в ситуации, когда для некоторого ФД существуют циклы использования, но циклов инициализации либо вообще нет, либо все циклы инициализации выполняются при условиях, которые не следуют из условий цикла использования.
import c_init(name, int) as init;
import c_print(value) as print;
sub init_1(name arr, int ind) {
init(arr[ind], 0);
}
sub main() {
df x, y, z, t, k, a, N, M;
if N <= 0 {
for i = 0..10 { init_1(x, 5*i); }
}
if N > 0 {
// Init loop under condition that is not guaranteed
for i = 0..10 { print(x[i]); }
}
// No init loop
for i = 0..N { print(y[i]); }
}
Реакция:
Если цикл инициализации не выполнится, программа зависнет при попытке использовать неинициализированные индексы ФД.