New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix dim shared byref initializer check #87
Conversation
Looks good to deal with the const initializer checks. My only recommendation is, that after this PR is merged, is to close 814, 822, 842, and start a new ticket for the following: bug ticket 822 has this example:
So we can still arrive at a failed assertion |
The CONST code path in hFlushExprStatic() used the symbol type as-is, instead of converting to pointer type for references. Thus the type looked different and it attempted the astNewCONV() which could easily fail (because the init expression is a pointer, while the symbol could be anything, e.g. struct/string).
Ok, that one is also interesting. Turns out the CONST code path (as opposed to the OFFSET code path) in hFlushExprStatic() didn't consider that a ref actually is a pointer and tried to do astNewCONV() from the type-casted null pointer initree (pointer type) to the symbol type (struct). The new commit should fix that. |
You make it look so easy. I struggled with this for days. You are at about the spot I got stuck trying to convert the LHS sym to just a pointer. x86 emitter doesn't know what to do with FB_DATATYPE_STRUCT in EMITVARINII. |
In ten years I have never seen ".invalid" come up in x86 -gen gas. Could use dtype = FB_DATATYPE_STRUCT to mean reference to struct. i.e. only time would ever pass STRUCT is that it is a ref to STRUCT. Maybe. In emit_x86.bas:EMITVARINII()
Will allow this...
to succeed. |
I can't think of a test case for this though, CONSTness should have been checked before already, it shouldn't matter here when emitting. Also the full type is only used for an astNewCONV() which allows casting away CONSTness etc. anyways.
src/compiler/ast-node-typeini.bas
Outdated
var sdtype = symbGetType( sym ) | ||
var sfulldtype = symbGetType( sym ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sfulldtype
has same value as sdtype
throughout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops; fixed it.
src/compiler/ast-node-typeini.bas
Outdated
if( symbIsRef( sym ) ) then | ||
'' Initializers for references initialize the pointer, | ||
'' not an object of the symbol's type. | ||
sdtype = typeAddrOf( sdtype ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if this is removed....
@@ -543,7 +551,7 @@ private sub hFlushExprStatic( byval n as ASTNODE ptr, byval basesym as FBSYMBOL | |||
else | |||
'' different types? | |||
if( edtype <> sdtype ) then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... then this should be if( edtype <> sfulldtype ) then
There is a lower level issue going on here in either x86 IR or x86 emitter. -gen gcc seems to handle it this change OK, but -gen gas does not. My previous comment is incorrect about replacing ".invalid" for structures in the x86 emitter. For example, this succeeds for
but will give other ASM errors when emitted. |
global ref initializers were not checked for being non-constant, but that can actually matter. For example when trying to initialize a ref from another ref, the second ref will try to copy the first ref's value, which is a non-constant initializer that isn't possible without generating a global constructor.
So for now I think the best solution is to disallow the case - at least fbc doesn't crash anymore.