Skip to content

Commit

Permalink
parser: Disallow fixed-length strings as BYREF vars/params/results
Browse files Browse the repository at this point in the history
fixes part of #650

References or pointers to fixed-length strings are not possible in FB
because we have no way to encode the string length in the pointer dtype.
We can only store fixed-length string length on symbols, not on
expressions, which would be needed when dereferencing such a pointer.
Also, currently, taking the address of a fixed-length string produces an
"unbounded" Zstring Ptr.

Previously the string length was just ignored on BYREF symbols, so it seems
best to disallow it to avoid confusion, especially since it doesn't look
like it will be implemented properly soon (though of course that could
still be done).
  • Loading branch information
dkl committed Oct 28, 2015
1 parent dc1380f commit e859301
Show file tree
Hide file tree
Showing 14 changed files with 33 additions and 2 deletions.
1 change: 1 addition & 0 deletions changelog.txt
Expand Up @@ -11,6 +11,7 @@ Version 1.05.0
- FileAttr() was still broken for 64bit - the result value was truncated to 32bit
- 1.04.0 regression: Under -gen gcc -asm att, support for gcc-style inline asm was broken
- ld was warning about unsupported linker options on OS X
- BYREF fixed-length strings (e.g. BYREF myParameter AS ZSTRING * 10) now trigger a compiler error since they are unsupported


Version 1.04.0
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/error.bas
Expand Up @@ -407,7 +407,8 @@ declare function hMakeParamDesc _
@"Reference not initialized", _
@"Incompatible reference initializer", _
@"Array of references - not supported yet", _
@"Invalid CASE range, start value is greater than the end value" _
@"Invalid CASE range, start value is greater than the end value", _
@"Fixed-length string combined with BYREF (not supported)" _
}


Expand Down
1 change: 1 addition & 0 deletions src/compiler/error.bi
Expand Up @@ -326,6 +326,7 @@ enum FB_ERRMSG
FB_ERRMSG_INCOMPATIBLEREFINIT
FB_ERRMSG_ARRAYOFREFS
FB_ERRMSG_INVALIDCASERANGE
FB_ERRMSG_BYREFFIXSTR

FB_ERRMSGS
end enum
Expand Down
1 change: 1 addition & 0 deletions src/compiler/parser-decl-proc-params.bas
Expand Up @@ -393,6 +393,7 @@ private function hParamDecl _
options or= FB_SYMBTYPEOPT_ALLOWFORWARD
end if
options and= not FB_SYMBTYPEOPT_CHECKSTRPTR
options or= FB_SYMBTYPEOPT_ISBYREF
end if

if( cSymbolType( dtype, subtype, 0, options ) = FALSE ) then
Expand Down
6 changes: 6 additions & 0 deletions src/compiler/parser-decl-symbtype.bas
Expand Up @@ -613,6 +613,12 @@ function cSymbolType _

end select

'' STRING * N can't be allowed with BYREF or pointers, because
'' we can't represent the * N on expression data types.
if( options and FB_SYMBTYPEOPT_ISBYREF ) then
errReport( FB_ERRMSG_BYREFFIXSTR, TRUE )
end if

'' const?
if( is_const ) then
dtype = typeSetIsConst( dtype )
Expand Down
1 change: 1 addition & 0 deletions src/compiler/parser-decl-var.bas
Expand Up @@ -44,6 +44,7 @@ sub hSymbolType _
dim as integer options = FB_SYMBTYPEOPT_DEFAULT
if( is_byref ) then
options and= not FB_SYMBTYPEOPT_CHECKSTRPTR
options or= FB_SYMBTYPEOPT_ISBYREF
end if

'' parse the symbol type (INTEGER, STRING, etc...)
Expand Down
1 change: 1 addition & 0 deletions src/compiler/parser-proc.bas
Expand Up @@ -396,6 +396,7 @@ sub cProcRetType _

'' Then allow BYREF AS Z/WSTRING as the type
options and= not FB_SYMBTYPEOPT_CHECKSTRPTR
options or= FB_SYMBTYPEOPT_ISBYREF
end if

if( cSymbolType( dtype, subtype, 0, options ) = FALSE ) then
Expand Down
1 change: 1 addition & 0 deletions src/compiler/parser.bi
Expand Up @@ -196,6 +196,7 @@ enum FB_SYMBTYPEOPT

FB_SYMBTYPEOPT_CHECKSTRPTR = &h00000001
FB_SYMBTYPEOPT_ALLOWFORWARD = &h00000002
FB_SYMBTYPEOPT_ISBYREF = &h00000004

FB_SYMBTYPEOPT_DEFAULT = FB_SYMBTYPEOPT_CHECKSTRPTR
end enum
Expand Down
3 changes: 3 additions & 0 deletions tests/string/byref-fixlen-1.bas
@@ -0,0 +1,3 @@
' TEST_MODE : COMPILE_ONLY_FAIL

declare sub f(byref z as zstring * 10)
3 changes: 3 additions & 0 deletions tests/string/byref-fixlen-2.bas
@@ -0,0 +1,3 @@
' TEST_MODE : COMPILE_ONLY_FAIL

dim byref z as zstring * 10 = "hi"
5 changes: 5 additions & 0 deletions tests/string/byref-fixlen-3.bas
@@ -0,0 +1,5 @@
' TEST_MODE : COMPILE_ONLY_FAIL

function f() byref as zstring * 10
return "hi"
end function
3 changes: 3 additions & 0 deletions tests/string/byval-fixlen-1.bas
@@ -0,0 +1,3 @@
' TEST_MODE : COMPILE_ONLY_FAIL

declare sub f(byval z as zstring * 10)
5 changes: 5 additions & 0 deletions tests/string/byval-fixlen-2.bas
@@ -0,0 +1,5 @@
' TEST_MODE : COMPILE_ONLY_FAIL

function f() as zstring * 10
return "hi"
end function
1 change: 0 additions & 1 deletion todo.txt
Expand Up @@ -21,7 +21,6 @@ o Dim Byref
which we don't need. The temp vars from the reference var initializer are in the same
scope as the reference var, and it should be enough to just remove their TEMP flag.
- allow BYVAL initialization, like byref results/params
- disallow [Z/W]String * N with Dim Byref (same problem as with byref params, see bug #650)
- allow BYREF fields; but they must be initialized in a constructor - what syntax to use for that?
@a = b works, but feels like a hack. Otherwise, a new syntax for field initialization is needed,
like initializer lists in C++
Expand Down

0 comments on commit e859301

Please sign in to comment.