Closed mingodad closed 1 month ago
Hi. Sure, I can add this macro.
I know, an alternative can be a symbolic link. Maybe you have by chance any best practices for paths in Linux? For example all paths to the shared libraries are hard-coded as well.
I didn't pay much attention to it so far, as I've got no complains about them.
Thank you for reply ! I'm trying right now to build/install hardcoding my desired paths and will test it then if I succed I'll try to figure out how to make it configurable and will post here what I achieve.
No luck so far and I can't even test it form the build dir. Would be nice if could have a build where the executables expect all they need to be relative to it's path.
Or an option to pass to then the path for the config/templates/lib/...
Also when building on linux there is no elt-cli
only asm64-cli
, ecv64-cli
, elena64-cli
, og64-cli
and sg64-cli
, no ide
and I can't find the info on how to build it yet.
I could get the https://github.com/ELENA-LANG/elena-lang/releases/download/v6.3.0/elena-lang-6.3.0.x64-win.zip unziped to a folder and execute the ide
with wine (the ide font size is too small, the editor font is configurable and I could get a font size of my choice).
I could compile the examples/console/helloworld but when try to execute I get:
wine elena64-ide.exe
0025:err:winedevice:async_create_driver failed to create driver L"NPF": c0000001
001e:err:winedevice:async_create_driver failed to create driver L"nsiproxy": c0000142
0046:err:module:import_dll Library elenart60_64.dll (which is needed by L"z:\\home\\xxxx\\local\\elena-win\\examples60\\console\\helloworld\\helloworld.exe") not found
0046:err:module:attach_dlls Importing dlls for L"z:\\home\\xxxx\\local\\elena-win\\examples60\\console\\helloworld\\helloworld.exe" failed, status c0000135
If I create a symbolic link to elenart60_64.dll in the same folder of helloworld.exe
then it works.
The simplest way to install all required shared files is to use the script:
for x86-64 : build/amd64/build_package_amd64.script for x86 : build/i386/build_package_i386.script for AARCH64 : build/aarch64/build_package_arm64.script for PPC64le : build/ppc64le/build_package_ppc64le.script
you have to execute them with SUDO
As for the relative paths - sure, I will do it. For Windows it is implemented like this. For Linux there is no simple solution to get a path where the executable is located. So I will add an option to provide the path where data / config files are located. But what about path to shared library?
The work on porting IDE to Linux is not yet finished. Let me know if you are interested, so I can prioritize it
What platform do you use?
Even the windows zip doesn't include the elt-cli.exe
mentioned on https://github.com/ELENA-LANG/elena-lang/wiki/ELENA-Programming-Manual#language-environment
I could get the https://github.com/ELENA-LANG/elena-lang/releases/download/v6.3.0/elena-lang-6.3.0.x64-win.zip unziped to a folder and execute the
ide
with wine (the ide font size is too small, the editor font is configurable and I could get a font size of my choice). I could compile the examples/console/helloworld but when try to execute I get:wine elena64-ide.exe 0025:err:winedevice:async_create_driver failed to create driver L"NPF": c0000001 001e:err:winedevice:async_create_driver failed to create driver L"nsiproxy": c0000142 0046:err:module:import_dll Library elenart60_64.dll (which is needed by L"z:\\home\\xxxx\\local\\elena-win\\examples60\\console\\helloworld\\helloworld.exe") not found 0046:err:module:attach_dlls Importing dlls for L"z:\\home\\xxxx\\local\\elena-win\\examples60\\console\\helloworld\\helloworld.exe" failed, status c0000135
If I create a symbolic link to elenart60_64.dll in the same folder of
helloworld.exe
then it works.
Yes, for windows, the shared library elenart60_64.dll / elenart60.dll must be located in the folder which included in PATHS or the current one. Alternatively you can copy them to WINDOWS/System32 or WINDOWS/SysWOW64 (for 64 bit version)
Even the windows zip doesn't include the
elt-cli.exe
mentioned on https://github.com/ELENA-LANG/elena-lang/wiki/ELENA-Programming-Manual#language-environment
It is in the another zip file - https://github.com/ELENA-LANG/elena-lang/releases/download/v6.3.0/elena-lang-6.3.0.x86-win.zip For simplicity, I didn't include into 64 bit version, 32 bit files.
While trying to build again and running under valgrind I'm getting this warnings:
Parsing operations/inline.l
==3521== Conditional jump or move depends on uninitialised value(s)
==3521== at 0x1E9E38: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:50)
==3521== by 0x1EC991: elena_lang::SyntaxTreeBuilder::flushAttribute(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, unsigned int&, bool, int) [clone .constprop.1] (derivation.cpp:815)
==3521== by 0x1EF721: elena_lang::SyntaxTreeBuilder::flushDescriptor(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool, bool, bool) (derivation.cpp:771)
==3521== by 0x1F68F3: elena_lang::SyntaxTreeBuilder::flushDeclaration(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1711)
==3521== by 0x1F7658: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:114)
==3521== by 0x1F78C2: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:122)
==3521== by 0x1F7A6D: elena_lang::SyntaxTreeBuilder::closeNode() (derivation.cpp:1880)
==3521== by 0x1E3D7E: elena_lang::CompilingProcess::parseModule(elena_lang::ProjectEnvironment&, elena_lang::ModuleIteratorBase&, elena_lang::SyntaxTreeBuilder&, elena_lang::ModuleScopeBase&) (compiling.cpp:499)
==3521== by 0x1E4E2E: elena_lang::CompilingProcess::buildModule(elena_lang::ProjectEnvironment&, elena_lang::ModuleIteratorBase&, elena_lang::SyntaxTree*, elena_lang::ForwardResolverBase*, elena_lang::CompilingProcess::ModuleSettings&, int, int) (compiling.cpp:576)
==3521== by 0x1E678B: elena_lang::CompilingProcess::compile(elena_lang::ProjectBase&, unsigned int, unsigned int, unsigned int, int) (compiling.cpp:680)
==3521== by 0x1E7739: elena_lang::CompilingProcess::build(elena_lang::Project&, elena_lang::LinkerBase&, unsigned int, unsigned int, unsigned int, int, elena_lang::ustr_t) (compiling.cpp:813)
==3521== by 0x11FBE8: main (elc.cpp:306)
==3521==
==3521== Conditional jump or move depends on uninitialised value(s)
==3521== at 0x1E9E38: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:50)
==3521== by 0x1EF9EE: elena_lang::SyntaxTreeBuilder::flushDescriptor(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool, bool, bool) (derivation.cpp:799)
==3521== by 0x1F68F3: elena_lang::SyntaxTreeBuilder::flushDeclaration(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1711)
==3521== by 0x1F7658: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:114)
==3521== by 0x1F78C2: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:122)
==3521== by 0x1F7A6D: elena_lang::SyntaxTreeBuilder::closeNode() (derivation.cpp:1880)
==3521== by 0x1E3D7E: elena_lang::CompilingProcess::parseModule(elena_lang::ProjectEnvironment&, elena_lang::ModuleIteratorBase&, elena_lang::SyntaxTreeBuilder&, elena_lang::ModuleScopeBase&) (compiling.cpp:499)
==3521== by 0x1E4E2E: elena_lang::CompilingProcess::buildModule(elena_lang::ProjectEnvironment&, elena_lang::ModuleIteratorBase&, elena_lang::SyntaxTree*, elena_lang::ForwardResolverBase*, elena_lang::CompilingProcess::ModuleSettings&, int, int) (compiling.cpp:576)
==3521== by 0x1E678B: elena_lang::CompilingProcess::compile(elena_lang::ProjectBase&, unsigned int, unsigned int, unsigned int, int) (compiling.cpp:680)
==3521== by 0x1E7739: elena_lang::CompilingProcess::build(elena_lang::Project&, elena_lang::LinkerBase&, unsigned int, unsigned int, unsigned int, int, elena_lang::ustr_t) (compiling.cpp:813)
==3521== by 0x11FBE8: main (elc.cpp:306)
==3521==
Parsing operations/operations.l
==3521== Conditional jump or move depends on uninitialised value(s)
==3521== at 0x1E9E38: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:50)
==3521== by 0x1E9D03: elena_lang::SyntaxTreeBuilder::flushCollection(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:61)
==3521== by 0x1E9E65: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:51)
==3521== by 0x1F6A95: elena_lang::SyntaxTreeBuilder::flushDeclaration(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1725)
==3521== by 0x1F7658: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:114)
==3521== by 0x1F78C2: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:122)
==3521== by 0x1F7A6D: elena_lang::SyntaxTreeBuilder::closeNode() (derivation.cpp:1880)
==3521== by 0x1E3D7E: elena_lang::CompilingProcess::parseModule(elena_lang::ProjectEnvironment&, elena_lang::ModuleIteratorBase&, elena_lang::SyntaxTreeBuilder&, elena_lang::ModuleScopeBase&) (compiling.cpp:499)
==3521== by 0x1E4E2E: elena_lang::CompilingProcess::buildModule(elena_lang::ProjectEnvironment&, elena_lang::ModuleIteratorBase&, elena_lang::SyntaxTree*, elena_lang::ForwardResolverBase*, elena_lang::CompilingProcess::ModuleSettings&, int, int) (compiling.cpp:576)
==3521== by 0x1E678B: elena_lang::CompilingProcess::compile(elena_lang::ProjectBase&, unsigned int, unsigned int, unsigned int, int) (compiling.cpp:680)
==3521== by 0x1E7739: elena_lang::CompilingProcess::build(elena_lang::Project&, elena_lang::LinkerBase&, unsigned int, unsigned int, unsigned int, int, elena_lang::ustr_t) (compiling.cpp:813)
==3521== by 0x11FBE8: main (elc.cpp:306)
==3521==
Compiling system'operations
saving system'operations
And moving this code :
if (!testNodeMask(node.key, SyntaxKey::TerminalMask) || !scope.ignoreTerminalInfo) {
flushCollection(writer, scope, node);
}
To:
if (!testNodeMask(node.key, SyntaxKey::TerminalMask)
|| !scope.ignoreTerminalInfo) { ///<<<!!!! Line 51
flushCollection(writer, scope, node);
}
Then the warning line changes from 50 to 51 that mean scope.ignoreTerminalInfo
is being checked without been initialized.
Maybe the uninitialized value is scope
!
After adding initialization here:
-------------------------- elenasrc3/elc/derivation.h --------------------------
index 5143257ab..38ccaf80c 100644
@@ -233,13 +233,14 @@ namespace elena_lang
_cacheWriter.newNode(SyntaxKey::Root);
}
- SyntaxTreeBuilder(SyntaxTree* target, ErrorProcessor* errorProcessor,
+ SyntaxTreeBuilder(SyntaxTree* target, ErrorProcessor* errorProcessor,
ModuleScopeBase* moduleScope, TemplateProssesorBase* templateProcessor)
: _writer(*target), _cacheWriter(_cache)
{
_errorProcessor = errorProcessor;
_moduleScope = moduleScope;
_templateProcessor = templateProcessor;
+ _noDebugInfo = false; ///<<<<!!!!! here adding initialization
_writer.clear();
_writer.newNode(SyntaxKey::Root);
Now it run a lot longer without warnings then there is this one:
Parsing operations/inline.l
Parsing operations/operations.l
Compiling system'operations
saving system'operations
Parsing operations/advanced/operations.l
Compiling system'operations'advanced
saving system'operations'advanced
Parsing inline_templates.l
Parsing object.l
Parsing basic.l
Parsing variables.l
Parsing primitives.l
Parsing enumerables.l
==4542== Invalid read of size 2
==4542== at 0x4C3D3A0: memmove (vg_replace_strmem.c:1400)
==4542== by 0x121673: memcpy (string_fortified.h:34)
==4542== by 0x121673: write (dump.cpp:82)
==4542== by 0x121673: elena_lang::MemoryDump::write(unsigned int, void const*, unsigned int) (dump.cpp:77)
==4542== by 0x1E9DC6: write (streams.h:509)
==4542== by 0x1E9DC6: writeString (streams.h:362)
==4542== by 0x1E9DC6: saveStrArgument (tree.h:130)
==4542== by 0x1E9DC6: newNode (tree.h:596)
==4542== by 0x1E9DC6: copyNewNode (syntaxtree.h:276)
==4542== by 0x1E9DC6: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:48)
==4542== by 0x1E9D13: elena_lang::SyntaxTreeBuilder::flushCollection(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:61)
==4542== by 0x1E9E75: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:51)
==4542== by 0x1EA47A: elena_lang::SyntaxTreeBuilder::copyHeader(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1231)
==4542== by 0x1F4D11: elena_lang::SyntaxTreeBuilder::flushSubScopeMember(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1250)
==4542== by 0x1F4F51: elena_lang::SyntaxTreeBuilder::flushSubScope(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1277)
==4542== by 0x1F57C4: elena_lang::SyntaxTreeBuilder::flushClassMember(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1350)
==4542== by 0x1F59D8: elena_lang::SyntaxTreeBuilder::flushClass(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1396)
==4542== by 0x1F73B1: elena_lang::SyntaxTreeBuilder::flushDeclaration(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1774)
==4542== by 0x1F7668: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:114)
==4542== Address 0x57aa27e is 60,174 bytes inside a block of size 60,224 free'd
==4542== at 0x4C3812F: realloc (vg_replace_malloc.c:1649)
==4542== by 0x1216B0: reserve (dump.cpp:52)
==4542== by 0x1216B0: reserve (dump.cpp:48)
==4542== by 0x1216B0: resize (dump.cpp:65)
==4542== by 0x1216B0: resize (dump.cpp:60)
==4542== by 0x1216B0: elena_lang::MemoryDump::write(unsigned int, void const*, unsigned int) (dump.cpp:80)
==4542== by 0x1E9DC6: write (streams.h:509)
==4542== by 0x1E9DC6: writeString (streams.h:362)
==4542== by 0x1E9DC6: saveStrArgument (tree.h:130)
==4542== by 0x1E9DC6: newNode (tree.h:596)
==4542== by 0x1E9DC6: copyNewNode (syntaxtree.h:276)
==4542== by 0x1E9DC6: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:48)
==4542== by 0x1E9D13: elena_lang::SyntaxTreeBuilder::flushCollection(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:61)
==4542== by 0x1E9E75: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:51)
==4542== by 0x1EA47A: elena_lang::SyntaxTreeBuilder::copyHeader(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1231)
==4542== by 0x1F4D11: elena_lang::SyntaxTreeBuilder::flushSubScopeMember(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1250)
==4542== by 0x1F4F51: elena_lang::SyntaxTreeBuilder::flushSubScope(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1277)
==4542== by 0x1F57C4: elena_lang::SyntaxTreeBuilder::flushClassMember(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1350)
==4542== by 0x1F59D8: elena_lang::SyntaxTreeBuilder::flushClass(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1396)
==4542== by 0x1F73B1: elena_lang::SyntaxTreeBuilder::flushDeclaration(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1774)
==4542== by 0x1F7668: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:114)
==4542== Block was alloc'd at
==4542== at 0x4C3812F: realloc (vg_replace_malloc.c:1649)
==4542== by 0x1216B0: reserve (dump.cpp:52)
==4542== by 0x1216B0: reserve (dump.cpp:48)
==4542== by 0x1216B0: resize (dump.cpp:65)
==4542== by 0x1216B0: resize (dump.cpp:60)
==4542== by 0x1216B0: elena_lang::MemoryDump::write(unsigned int, void const*, unsigned int) (dump.cpp:80)
==4542== by 0x1E9DC6: write (streams.h:509)
==4542== by 0x1E9DC6: writeString (streams.h:362)
==4542== by 0x1E9DC6: saveStrArgument (tree.h:130)
==4542== by 0x1E9DC6: newNode (tree.h:596)
==4542== by 0x1E9DC6: copyNewNode (syntaxtree.h:276)
==4542== by 0x1E9DC6: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:48)
==4542== by 0x1EC9A1: elena_lang::SyntaxTreeBuilder::flushAttribute(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, unsigned int&, bool, int) [clone .constprop.1] (derivation.cpp:815)
==4542== by 0x1EF731: elena_lang::SyntaxTreeBuilder::flushDescriptor(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool, bool, bool) (derivation.cpp:771)
==4542== by 0x1F4FE7: elena_lang::SyntaxTreeBuilder::flushClassMember(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1315)
==4542== by 0x1F59D8: elena_lang::SyntaxTreeBuilder::flushClass(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1396)
==4542== by 0x1F73B1: elena_lang::SyntaxTreeBuilder::flushDeclaration(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1774)
==4542== by 0x1F7668: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:114)
==4542== by 0x1F78D2: elena_lang::SyntaxTreeBuilder::flush(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:122)
==4542== by 0x1F7A7D: elena_lang::SyntaxTreeBuilder::closeNode() (derivation.cpp:1880)
==4542== by 0x1E3D7E: elena_lang::CompilingProcess::parseModule(elena_lang::ProjectEnvironment&, elena_lang::ModuleIteratorBase&, elena_lang::SyntaxTreeBuilder&, elena_lang::ModuleScopeBase&) (compiling.cpp:499)
==4542==
...
The key for this problem is in this part of the valgrind message:
==4542== Address 0x57aa27e is 60,174 bytes inside a block of size 60,224 free'd
==4542== at 0x4C3812F: realloc (vg_replace_malloc.c:1649)
==4542== by 0x1216B0: reserve (dump.cpp:52)
==4542== by 0x1216B0: reserve (dump.cpp:48)
==4542== by 0x1216B0: resize (dump.cpp:65)
==4542== by 0x1216B0: resize (dump.cpp:60)
Looking at this code:
void MemoryDump :: reserve(pos_t size)
{
if (size > _total) {
const pos_t newSize = align(size, SECTION_PAGE_SIZE);
void* newBuffer = realloc(_buffer, newSize);
if (newBuffer) {
_buffer = newBuffer;
_total = newSize;
}
}
}
If the call to realloc
fail this function silently hide the error and let the program continue.
Shouldn't an error somehow be returned or halt the program ?
Maybe the uninitialized value is
scope
!
- _noDebugInfo = false; ///<<<<!!!!! here adding initialization Yes, good catch. I've missed that one. And it is passed further to Scope
void SyntaxTreeBuilder :: flushDeclaration(SyntaxTreeWriter& writer, SyntaxNode node)
{
Scope scope(_noDebugInfo);
If the call to
realloc
fail this function silently hide the error and let the program continue. Shouldn't an error somehow be returned or halt the program ?
In normal circumstances it is highly unlikely, but of course better safe than sorry. I will fix it as well.
Thanks a lot.
In this code in tree.h
:
pos_t saveStrArgument(ustr_t strArgument)
{
MemoryWriter stringWriter(&_strings);
pos_t position = stringWriter.position();
stringWriter.writeString(strArgument, getlength_pos(strArgument) + 1);
return position;
}
using this from tools.h
:
inline pos_t getlength_pos(const char* s)
{
return (s == nullptr) ? 0 : (pos_t)strlen(s);
}
What happens when strArgument is NULL ? Are you trying to write 1 byte from a NULL ?
What happens when strArgument is NULL ? Are you trying to write 1 byte from a NULL ?
It will crash :) . In defense, it never did though ;) I've fixed it, Thanks a lot.
I've noticed that in derivation.h
you are passing SyntaxNode node
as value in a lot of places couldn't SyntaxNode &node
be a better choice ?
In this code from dump.cpp
:
bool MemoryDump :: write(pos_t position, const void* s, pos_t length)
{
if (position <= _used) {
resize(position + length);
memcpy(static_cast<char*>(_buffer) + position, s, length);
return true;
}
else return false;
}
bool MemoryDump :: insert(pos_t position, const void* s, pos_t length)
{
if (position <= _used) {
resize(_used + length);
memmove(get(position + length), get(position), _used - position - length);
if (s != nullptr)
memcpy(get(position), s, length);
return true;
}
else return false;
}
This test if (position <= _used) {
should not be if (position >= _used) {
?
Sorry ! Forget my previous message.
This test
if (position <= _used) {
should not beif (position >= _used) {
?
No, it is correct. I'm inserting inside the allocated buffer.
Sorry ! Forget my previous message.
Sure, no problem, Anyway thanks for your comments. It is always nice to have a fresh look. :)
I've noticed that in
derivation.h
you are passingSyntaxNode node
as value in a lot of places couldn'tSyntaxNode &node
be a better choice ?
Yes, I will review them. Sometimes it can be dangerous if the node is reassigned. I will look and modify when it is possible
In this piece of code in compiler.cpp
:
// if it is an explicit constant conversion
if (constantConversion) {
NamespaceScope* nsScope = Scope::getScope<NamespaceScope>(scope, Scope::ScopeLevel::Namespace);
addExtensionMessage(scope, scope.message, scope.getClassRef(), scope.message,
scope.getClassVisibility() != Visibility::Public);
}
g++ 9.4 emit this warning:
../elenasrc3/elc/compiler.cpp: In member function ‘void elena_lang::Compiler::declareVMTMessage(elena_lang::Compiler::MethodScope&, elena_lang::SyntaxNode, bool, bool, bool)’:
../elenasrc3/elc/compiler.cpp:3995:26: warning: unused variable ‘nsScope’ [-Wunused-variable]
3995 | NamespaceScope* nsScope = Scope::getScope<NamespaceScope>(scope, Scope::ScopeLevel::Namespace);
| ^~~~~~~
Maybe do you intended to use nsScope
instead of scope
here ?
addExtensionMessage(scope, scope.message, scope.getClassRef(), scope.message,
scope.getClassVisibility() != Visibility::Public);
Same thing as the previous message here:
else {
// HOTFIX : generate a temporal template to pass the type
SyntaxTree dummyTree;
List<SyntaxNode> parameters({});
declareTemplateParameters(scope.module, typeList, dummyTree, parameters);
ref_t templateRef = mapTemplateType(scope, terminalNode, parameters.count());
if (!templateRef)
scope.raiseError(errUnknownClass, terminalNode);
NamespaceScope* nsScope = Scope::getScope<NamespaceScope>(scope, Scope::ScopeLevel::Namespace);
return _templateProcessor->generateClassTemplate(*scope.moduleScope,
templateRef, parameters, declarationMode, nullptr);
}
Again here:
smName.append("#1");
ref_t templateReference = 0;
if (isWeakReference(*smName)) {
templateReference = scope.module->mapReference(*smName, true);
}
else templateReference = scope.moduleScope->mapFullReference(*smName, true);
NamespaceScope* nsScope = Scope::getScope<NamespaceScope>(scope, Scope::ScopeLevel::Namespace);
return _templateProcessor->generateClassTemplate(*scope.moduleScope,
templateReference, parameters, false, nullptr);
}
And here:
ref_t templateReference = 0;
if (isWeakReference(*tupleName)) {
templateReference = scope.module->mapReference(*tupleName, true);
}
else templateReference = scope.moduleScope->mapFullReference(*tupleName, true);
if (!templateReference)
scope.raiseError(errInvalidOperation, node);
NamespaceScope* nsScope = Scope::getScope<NamespaceScope>(scope, Scope::ScopeLevel::Namespace);
return _templateProcessor->generateClassTemplate(*scope.moduleScope,
templateReference, parameters, false, nullptr);
}
...
And here in compiler.h
:
Scope(Scope* parent)
{
this->parent = parent;
if (parent) {
this->module = parent->module;
this->moduleScope = parent->moduleScope;
this->compilerLogic = compilerLogic;
}
else {
this->module = nullptr;
this->moduleScope = nullptr;
this->compilerLogic = nullptr;
}
}
In file included from ../elenasrc3/elc/compiler.cpp:9:
../elenasrc3/elc/compiler.h: In constructor ‘elena_lang::Compiler::Scope::Scope(elena_lang::Compiler::Scope*)’:
../elenasrc3/elc/compiler.h:459:38: warning: ‘*<unknown>.elena_lang::Compiler::Scope::compilerLogic’ may be used uninitialized in this function [-Wmaybe-uninitialized]
459 | this->compilerLogic = compilerLogic;
| ^~~~~~~~~~~~~
Probably do you intended this ?
this->compilerLogic = parent->compilerLogic;
And in elfarmimage.cpp
:
// relocation table entry
pos_t relPosition = reltabWriter.position() - reltabOffset;
reltabWriter.writeQReference(importRef, gotPosition);
reltabWriter.writeQWord((symbolIndex << 32) + relocateType);
reltabWriter.writeQWord(0);
../elenasrc3/elc/linux/elfarmimage.cpp: In member function ‘virtual void elena_lang::ElfARM64ImageFormatter::fillElfData(elena_lang::ImageProviderBase&, elena_lang::ElfImageFormatter::ElfData&, elena_lang::pos_t, elena_lang::RelocationMap&)’:
../elenasrc3/elc/linux/elfarmimage.cpp:93:13: warning: unused variable ‘relPosition’ [-Wunused-variable]
93 | pos_t relPosition = reltabWriter.position() - reltabOffset;
| ^~~~~~~~~~~
Did you intended to use relPosition
?
g++ 9.4 emit this warning: Maybe do you intended to use
nsScope
instead ofscope
here ?
No, in most cases they are left-overs. My VS doesn't like to warn me about unused variables. :) I see them only then I compile under Linux. I've fixed bunch of them now.
Probably do you intended this ?
this->compilerLogic = parent->compilerLogi
Thanks, good catch. I've fixed it.
Did you intended to use
relPosition
?
No, I've commented it now. Probably left after debugging / porting from Intel CPU code.
As for the main topic of this issue. I've fixed the compiler code, it will now try to look for data and config files in the executable folder and use them. But paths in elc60.config file must be modified. I will think over the best and most optimal way to do it. Probably I can have two sets of config files - local with relative paths and default ones
I think that I finally found the problem reported by valgrind
:
Parsing enumerables.l
==15531== Invalid read of size 2
==15531== at 0x4C3D3A0: memmove (vg_replace_strmem.c:1400)
==15531== by 0x1386FF: elena_lang::MemoryDump::write(unsigned int, void const*, unsigned int) (dump.cpp:82)
==15531== by 0x14BA88: elena_lang::MemoryWriter::write(void const*, unsigned int) (streams.h:509)
==15531== by 0x161185: elena_lang::StreamWriter::writeString(elena_lang::ustr_t, unsigned int) (streams.h:362)
==15531== by 0x17D789: elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::saveStrArgument(elena_lang::ustr_t) (tree.h:130)
==15531== by 0x17D2BA: elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer::newNode(elena_lang::SyntaxKey, elena_lang::ustr_t) (tree.h:596)
==15531== by 0x1F7562: elena_lang::SyntaxTree::copyNewNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (syntaxtree.h:276)
==15531== by 0x1EDA6F: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:48)
==15531== by 0x1EDB4A: elena_lang::SyntaxTreeBuilder::flushCollection(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:61)
==15531== by 0x1EDACB: elena_lang::SyntaxTreeBuilder::flushNode(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:51)
==15531== by 0x1F3485: elena_lang::SyntaxTreeBuilder::copyHeader(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, bool) (derivation.cpp:1231)
==15531== by 0x1F35ED: elena_lang::SyntaxTreeBuilder::flushSubScopeMember(elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Writer&, elena_lang::SyntaxTreeBuilder::Scope&, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node, elena_lang::Tree<elena_lang::SyntaxKey, (elena_lang::SyntaxKey)0>::Node) (derivation.cpp:1250)
==15531== Address 0x57aa27e is 60,174 bytes inside a block of size 60,224 free'd
==15531== at 0x4C3812F: realloc (vg_replace_malloc.c:1649)
==15531== by 0x13861A: elena_lang::MemoryDump::reserve(unsigned int) (dump.cpp:52)
Following the call chain I arrived at syntaxtree.h
:
static void copyNewNode(SyntaxTreeWriter& writer, SyntaxNode node)
{
if (node.arg.strArgPosition != INVALID_POS) {
writer.newNode(node.key, node.identifier()); ////<<<<!!!!! Here
}
else writer.newNode(node.key, node.arg.reference);
}
The problem seem that node.identifier()
:
ustr_t identifier()
{
if (arg.strArgPosition != INVALID_POS) {
return (const char*)(_tree->_strings.get(arg.strArgPosition)); ///!!!!<<< HERE
}
else return nullptr;
}
returns a pointer inside _buffer
:
void* MemoryDump :: get(pos_t position) const
{
if (position < _used) {
return (char*)_buffer + position; ////<<<<!!! HERE
}
else return nullptr;
}
That pointer is passed to here dump.cpp
:
bool MemoryDump :: write(pos_t position, const void* s /*HERE*/, pos_t length)
{
if (position <= _used) {
resize(position + length); ///!!!<<< but _buffer can be reallocated here and invalidate the parameter "s"
memcpy(static_cast<char*>(_buffer) + position, s, length);
return true;
}
else return false;
}
The parameter s
is a pointer inside _buffer
that can be reallocated in resize(position + length);
and became invalid (use after free).
We are copying part of itself over itself, quick dirty fix can be to strdup
the return of node.identifier()
and free it after.
I've tested with this:
static void copyNewNode(SyntaxTreeWriter& writer, SyntaxNode node)
{
if (node.arg.strArgPosition != INVALID_POS) {
char *id = strdup(node.identifier());
writer.newNode(node.key, id);
free(id);
}
else writer.newNode(node.key, node.arg.reference);
}
And no valgrind warnings anymore (although there is other problems).
==16922== Memcheck, a memory error detector
==16922== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==16922== Using Valgrind-3.21.0 and LibVEX; rerun with -h for copyright info
==16922== Command: ../../bin/elena64-cli ../../src60/system/system.project
==16922==
ELENA Command-line compiler 6.5.91 (C)2005-2024 by Aleksey Rakov, ELENA-LANG Org
Project: system, Platform: Linux_AMD64, Target type: Library
Cleaning up
Parsing attributes/attributes.l
Compiling system'attributes
saving system'attributes
Parsing predefined/predefined.l
Parsing predefined/aliases.l
Compiling system'predefined
saving system'predefined
Parsing operations/inline.l
Parsing operations/operations.l
Compiling system'operations
saving system'operations
Parsing operations/advanced/operations.l
Compiling system'operations'advanced
saving system'operations'advanced
Parsing inline_templates.l
Parsing object.l
Parsing basic.l
Parsing variables.l
Parsing primitives.l
Parsing enumerables.l
Parsing strings.l
Parsing extensions.l
Parsing messaging.l
Parsing closures.l
Parsing convertors.l
Parsing pointers.l
Parsing lnx_primitives.l
Parsing dynamic.l
Parsing exceptions.l
Parsing events.l
Parsing console.l
Parsing app.l
Parsing lnx_app.l
Parsing lnx_strings.l
Parsing template_tests.l
Parsing collections/list.l
Parsing collections/queues.l
Parsing collections/tuples.l
Parsing collections/maps.l
Parsing collections/sorted_list.l
Parsing collections/template_tests.l
Parsing math/math.l
Parsing text/encoding.l
Parsing text/textbuffer.l
Parsing io/common.l
Parsing io/streamreader.l
Parsing io/streamwriter.l
Parsing io/lnx_console.l
Parsing io/files.l
Parsing io/ioexceptions.l
Parsing io/lnx_files.l
Parsing io/lnx_getfiles.l
Parsing calendar/lnx64_datetime.l
Parsing calendar/dates.l
Compiling system......
info 701: new method read<'$auto'system@Array#1&system@ByteNumber,'$auto'system@Reference#1&system@IntNumber>[3]
io/lnx_files.l(42:7): error 142: new method cannot be declared
Compiled with errors
==16922==
==16922== HEAP SUMMARY:
==16922== in use at exit: 85,257 bytes in 65 blocks
==16922== total heap usage: 799,906 allocs, 799,841 frees, 174,596,923,879 bytes allocated
==16922==
==16922== LEAK SUMMARY:
==16922== definitely lost: 12,553 bytes in 64 blocks
==16922== indirectly lost: 0 bytes in 0 blocks
==16922== possibly lost: 0 bytes in 0 blocks
==16922== still reachable: 72,704 bytes in 1 blocks
==16922== suppressed: 0 bytes in 0 blocks
==16922== Rerun with --leak-check=full to see details of leaked memory
==16922==
==16922== For lists of detected and suppressed errors, rerun with: -s
==16922== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
==17081== Memcheck, a memory error detector
==17081== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==17081== Using Valgrind-3.21.0 and LibVEX; rerun with -h for copyright info
==17081== Command: ../../bin/elena64-cli ../../src60/extensions/extensions.project
==17081==
ELENA Command-line compiler 6.5.91 (C)2005-2024 by Aleksey Rakov, ELENA-LANG Org
Project: extensions, Platform: Linux_AMD64, Target type: Library
Cleaning up
Parsing control.l
Parsing convertors.l
Parsing console.l
Parsing basic.l
Parsing tests.l
Parsing random.l
Parsing app.l
Parsing lnx_args.l
Parsing text/strings.l
Parsing text/words.l
Parsing math/functions.l
Parsing math/matrix.l
Compiling extensions
(1:8): warning 413: Unknown module 'system'
internal error 604: Base class doesn't exist
Compiled with errors
==17081==
==17081== HEAP SUMMARY:
==17081== in use at exit: 82,247 bytes in 56 blocks
==17081== total heap usage: 70,131 allocs, 70,075 frees, 1,369,167,154 bytes allocated
==17081==
==17081== LEAK SUMMARY:
==17081== definitely lost: 9,543 bytes in 55 blocks
==17081== indirectly lost: 0 bytes in 0 blocks
==17081== possibly lost: 0 bytes in 0 blocks
==17081== still reachable: 72,704 bytes in 1 blocks
==17081== suppressed: 0 bytes in 0 blocks
==17081== Rerun with --leak-check=full to see details of leaked memory
==17081==
==17081== For lists of detected and suppressed errors, rerun with: -s
==17081== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
A better solution would be to have another newNode
chain that accept a start position and end position something like:
void newNode(Key key, pos_t id_start, pos_t id_end)
Thanks for the help. I've fixed it. Please take a look and call your memory error detector again
As for the compiler error, it is already fixed in iteration34 branch. You can pull it. All the changes are there
Fixed in 6.4.4, the compiler for Linux will use the local config file if available.
Please let me know if it doesn't work for you. I will reopen issue in this case
I'm on a Ubuntu 18.04 64bits and want to install
elena
to a local folder$HOME/local/elena
but it seems that the installation folder is hardcoded to be: https://github.com/ELENA-LANG/elena-lang/blob/8938a86917d0aeabd55d417bb68f967e2b578a4e/elenasrc3/elc/linux/constants.h#L12-L18Also it's hard coded in other places too, maybe it could be wrapped with preprocessor macro to allow override like:
Is already another way to achieve it ?