Open YashasSamaga opened 6 years ago
I've had the release compiler crash a few times while playing with destructors and other operators. Every time changing literally nothing and instantly recompiling fixed it. I could not reproduce the crash reliably ever.
Do you still have the code with you?
It makes sense that the compiler crashes sometimes and sometimes not as accessing garbage locations (which is what I think is causing this) is undefined behavior.
I might do. But as I said, because it was not consistent I can't easilly confirm that the code I still have is triggering it unless I get lucky.
OK, I just spammed F5 on this code and it eventually crashed:
// This is a comment
// uncomment the line below if you want to write a filterscript
//#define FILTERSCRIPT
#include <a_samp>
#include <amx_assembly\amx_memory>
new bool:DESTRUCT_Tag = true;
#define __COMPILER_ALL_DESTRUCTORS 0
#if __COMPILER_ALL_DESTRUCTORS
#define EXPLICIT_RETURN_REQUIRED
#else
#define EXPLICIT_RETURN_REQUIRED , ExplicitReturnRequired:explicit_return_required = ExplicitReturnRequired:0
stock operator~(ExplicitReturnRequired:dummy[], size)
{
#pragma unused dummy, size
}
#endif
Tag:operator=(Tag:a);
//#pragma option -a
//Func2(b[3][4])
//{
//}
Tag:Func0()
{
new Tag:a = Tag:0;
return a;
}
Tag:Func1(Tag:b EXPLICIT_RETURN_REQUIRED)
{
// static Tag:a[2][3][4];
// Func2(a[0]);
if (DESTRUCT_Tag)
return b;
// printf("%d", _:b);
return b;
}
Tag:Func2(Tag:b EXPLICIT_RETURN_REQUIRED)
{
// printf("%d", _:b);
return;
}
#define DESTRUCTOR_REQUIRED(%0)%1) %0%1 EXPLICIT_RETURN_REQUIRED
operator~(Tag:a[], size)
{
if (DESTRUCT_Tag)
printf("bye: %d %d %d", size, ref(_:a), _:a[0]);
DESTRUCT_Tag = true;
}
Tag:operator=(Tag:a)
{
printf("assign %d", _:a);
DESTRUCT_Tag = false;
return a;
}
main()
{
printf("0");
new Tag:a;
new Tag:b[10];
++a;
printf("1");
Func1(Func0());
Func2(Func1(a));
printf("2");
Func2(Func1(Tag:0));
printf("3");
--a;
return;
}
I'm not too inclined to reduce it further, since it is hard to confirm on any given change.
Despite that, I did it anyway. This is the most minimal repro I could manage, if there is anything smaller, everything I tested didn't crash within 40 compiles, while the mean was about 1 in 10 compiles crashing:
ref(...)
{
#emit load.s.pri 12
#emit retn
}
Tag:operator=(Tag:a);
Tag:Func0()
{
new Tag:a = Tag:0;
return a;
}
operator~(Tag:a[], size)
{
ref(_:a);
}
Tag:operator=(Tag:a)
{
return a;
}
main()
{
Func0();
}
(Not even any includes needed).
Got it down even further:
Func(a[])
{
}
Tag:operator=(Tag:a);
operator~(Tag:a[], size)
{
Func(_:a);
}
Tag:operator=(Tag:a)
{
return a;
}
main()
{
new Tag:a = Tag:0;
}
I just use pawno and spam ESC/F5 repeatedly. It now takes about 20 compiles to crash, but does. The most I got at one stage (maybe I should have posted that stage explicitly) was nearly 3/4 compiles crashing.
Maybe I should have documented how I did that, as so few people seem to know what a minimal repro is..
I'm sure I got it to crash once without the operator forward, but couldn't reproduce that in about 100 compiles.
It seems to crash most reliably after changing the code and recompiling.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
The assertions which fail are inside
max_stacksize_recurse
:assert(sym->refer[i]->ident==iFUNCTN);
(line 4637,sc1.c
)assert(sym->ident==iFUNCTN);
(line 4630,sc1.c
)The list of referrers
sym->reffers
appears to be filled with garbage. http://tinyimg.io/i/J91Ue4e.pngThe
+
operator seems to be fine. The garbage is present for-
operator only.I am not sure why the compiler does not crash in release build.