julelang / jule

Effective programming language to build efficient, fast, reliable and safe software while maintaining simplicity
https://jule.dev
BSD 3-Clause "New" or "Revised" License
129 stars 13 forks source link

Error when trying to build jule with gcc-13 #106

Open mingodad opened 2 months ago

mingodad commented 2 months ago

Description

When trying to build jule with g++-13 I'm getting the error shown bellow (with clang-17 no error):

./build-dad.sh
error: overflow the limit of data-type
  --> julec-ir/jule-master/std/jule/lex/token.jule:118:5
  118 | Na,
  panic: std::strings: repeat: integer buffer size overflow
location: julec-ir/jule-master/std/strings/strings.jule:17:9
-----------------------------------------------------------------------
An unexpected error occurred while compiling JuleC. Check errors above.

Searching for occurrencies of OverflowLimits I found:

julec-ir/jule-master/std/jule/build/log.jule:110:    OverflowLimits: `overflow the limit of data-type`,
julec-ir/jule-master/std/jule/sema/eval.jule:816:                self.pushErr(s.Token, LogMsg.OverflowLimits)
julec-ir/jule-master/std/jule/sema/eval.jule:955:            self.pushErr(i.Token, LogMsg.OverflowLimits)
julec-ir/jule-master/std/jule/sema/eval.jule:973:                self.pushErr(i.Token, LogMsg.OverflowLimits)
julec-ir/jule-master/std/jule/sema/eval.jule:1016:                self.pushErr(errorToken, LogMsg.OverflowLimits)
julec-ir/jule-master/std/jule/sema/eval.jule:4222:            ret LogMsg.OverflowLimits
julec-ir/jule-master/std/jule/sema/sema.jule:1198:                self.pushErr(item.Token, LogMsg.OverflowLimits)
julec-ir/jule-master/std/jule/sema/type.jule:1262:                self.pushErr(decl.Size.Token, LogMsg.OverflowLimits)
julec-ir/jule-master/std/jule/sema/type2.jule:278:                self.pushErr(LogMsg.OverflowLimits)
julec-ir/jule-master/std/jule/sema/type2.jule:283:                self.pushErr(LogMsg.OverflowLimits)

I believe that the error is raised here https://github.com/julelang/jule/blob/28675df917365cd072b47db021b358981f693bca/std/jule/sema/sema.jule#L1198

Would be nice if the line number of the self.pushErr appeared on the error message.

Expected behavior

No errors

Current behavior

No response

Additional information

Nothing

mingodad commented 2 months ago

I'm getting the same error with gcc-9, both gcc-13 and gcc-9 on Ubuntu-18.04.

mingodad commented 2 months ago

Also would be nice if the sizes that trigger the error/panic could be shown here: https://github.com/julelang/jule/blob/6638e5d30c5473db8f33f523a51e43662a65c492/std/strings/strings.jule#L16-L19

mingodad commented 2 months ago

After add a printf like debug code in https://github.com/julelang/jule/blob/6638e5d30c5473db8f33f523a51e43662a65c492/std/strings/strings.jule#L16-L19

    if len(s) > int.Max/n {
        outln("== len(s)=")
        outln( len(s))
        outln("  int.Max/n=")
        outln(n)
        outln(int.Max/n)
        panic("std::strings: repeat: integer buffer size overflow")
    }

I'm getting this output:

./build-dad.sh
error: overflow the limit of data-type
  --> /home/mingo/dev/c/A_programming-languages/julec-ir/jule-master/std/jule/lex/token.jule:118:5
  118 | Na,
  == len(s)=
1
  int.Max/n=
3
-3074457345618258602
panic: std::strings: repeat: integer buffer size overflow
location: /home/mingo/dev/c/A_programming-languages/julec-ir/jule-master/std/strings/strings.jule:22:9
-----------------------------------------------------------------------
An unexpected error occurred while compiling JuleC. Check errors above.
mingodad commented 2 months ago

I've also added int.Max to the output now:

    if len(s) > int.Max/n {
        outln("== len(s)=")
        outln( len(s))
        outln("  int.Max/n=")
        outln(n)
        outln(int.Max)
        outln(int.Max/n)
        panic("std::strings: repeat: integer buffer size overflow")
    }
./build-dad.sh
error: overflow the limit of data-type
  --> /home/mingo/dev/c/A_programming-languages/julec-ir/jule-master/std/jule/lex/token.jule:118:5
  118 | Na,
  == len(s)=
1
  int.Max/n=
3
-9223372036854775808
-3074457345618258602
panic: std::strings: repeat: integer buffer size overflow
location: /home/mingo/dev/c/A_programming-languages/julec-ir/jule-master/std/strings/strings.jule:23:9
-----------------------------------------------------------------------
mertcandav commented 2 months ago

Hi.

CI/CD is not reports this problem on Ubuntu. Also I tried on Ubuntu 24.04 with gcc-13. I just download source code from master, get latest IR and compiled with it. it works as expected

Could you explain in detail the steps you took and help me figure out how to experience the problem?

mingodad commented 2 months ago

Here is my replacement for https://github.com/julelang/jule/blob/master/src/julec/build.sh :

#!/bin/bash
# Copyright 2023-2024 The Jule Programming Language.
# Use of this source code is governed by a BSD 3-Clause
# license that can be found in the LICENSE file.

if [ -f ./main.jule ]; then
  #clang-17-env myvalgrind ./../../bin/julec --opt-deadcode -o ./../../bin/julec_dev .
  #clang-17-env ./../../bin/julec --opt-deadcode -o ./../../bin/julec_dev-clang .
  gcc-13-env ./../../bin/julec --compiler gcc --opt-deadcode -o ./../../bin/julec_dev-gcc .
  #gcc-13-env ./../../bin/julec --compiler gcc --opt-deadcode -o ./../../bin/julec_dev-gcc2 .
  #./../../bin/julec --compiler gcc --opt-deadcode -o ./../../bin/julec_dev-gcc2 .
else
  echo "error: working directory is not source directory"
  exit
fi

if [ $? -eq 0 ]; then
  echo "Compilation successful!"
else
  echo "-----------------------------------------------------------------------"
  echo "An unexpected error occurred while compiling JuleC. Check errors above."
fi

Looking a the output of outln(int.Max) shown in previous comment -9223372036854775808 somehow int.Max is getting the value of int.Min.

The steps on Ubuntu 18.04 :

mertcandav commented 2 months ago

I have an idea to fix. In addition, the -compiler gcc flag uses g++ for compilation. Can you pass also --compiler-path g++-13 to compiler to be sure compiler is using g++-13 for C++ compiler.

Your command would be like: cc-13-env ./../../bin/julec --compiler gcc --compiler-path g++-13 --opt-deadcode -o ./../../bin/julec_dev-gcc .

mingodad commented 2 months ago

There is any way to get a stack trace from the panic in ulec-ir/jule-master/std/strings/strings.jule:17:9 ?

mertcandav commented 2 months ago

Jule is not supports stack traces yet. So unfortunately no. Maybe you can segfault to get stack trace with LLDB or GDB, but this method required editing the IR. Also this documentation may help you to use LLDB or GDB with jule.

mingodad commented 2 months ago

It gives the same error, here is my gcc-13-env :

MyPrefix=$HOME/local/gcc-13
export PATH=$MyPrefix/bin:$PATH
export LD_LIBRARY_PATH=$MyPrefix/lib64:$LD_LIBRARY_PATH
export CXXFLAGS="-I$MyPrefix/include/c++/13.2.0"
export LDFLAGS="-L$MyPrefix/lib64"
$*
mingodad commented 2 months ago

Even compiling with --disable-safety doesn't work in this case. What's the equivalent of abort() in C/C++ that does enable gdb to take control, can I add inline C/C++ code ?

Something like:

    if len(s) > int.Max/n {
        outln("== len(s)=")
    outln( s)
        outln( len(s))
        outln("  int.Max/n=")
        outln(n)
        outln(int.Max)
        outln(int.Max/n)
inline "C" { abort(); }
        panic("std::strings: repeat: integer buffer size overflow")
    }
mertcandav commented 2 months ago

Yes you can call the abort function.

Add this into source code like function declaration:

cpp fn abort()

Then you can call like this: cpp.abort()

mertcandav commented 2 months ago

Problem is probably caused by Min or Max functions which is provided by std::jule::types. I'll investigate this case.

mingodad commented 2 months ago

I've added a call to abort an I'm getting this stack trace that doesn't help much (any way to add line numbers to the generated C++ code ?):

./build-dad.sh
GNU gdb (Ubuntu 10.2-0ubuntu1~18.04~2) 10.2
Copyright (C) 2021 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./../../bin/julec...
(No debugging symbols found in ./../../bin/julec)
(gdb) r
Starting program: /home/mingo/dev/c/A_programming-languages/julec-ir/jule-master/bin/julec --disable-safety --compiler gcc --opt-deadcode -o ./../../bin/julec_dev-gcc .
warning: File "/home/mingo/local/gcc-13/lib64/libstdc++.so.6.0.32-gdb.py" auto-loading has been declined by your `auto-load safe-path' set to "$debugdir:$datadir/auto-load".
To enable execution of this file add
    add-auto-load-safe-path /home/mingo/local/gcc-13/lib64/libstdc++.so.6.0.32-gdb.py
line to your configuration file "/home/mingo/.gdbinit".
To completely disable this security protection add
    set auto-load safe-path /
line to your configuration file "/home/mingo/.gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual.  E.g., run from the shell:
    info "(gdb)Auto-loading safe path"
error: overflow the limit of data-type
  --> /home/mingo/dev/c/A_programming-languages/julec-ir/jule-master/std/jule/lex/token.jule:118:5
  118 | Na,
  == len(s)=

1
  int.Max/n=
3
-9223372036854775808
-3074457345618258602
panic: std::strings: repeat: integer buffer size overflow
location: /home/mingo/dev/c/A_programming-languages/julec-ir/jule-master/std/strings/strings.jule:24:9

Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51  ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff70037f1 in __GI_abort () at abort.c:79
#2  0x0000000000402ff4 in jule::panic(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ()
#3  0x000000000056c005 in _ae6b260721a7_Repeat(jule::Str, long) ()
#4  0x000000000051fd28 in static__ae6b2aac939c_LogError(_ae6b261b585b_Log&) ()
#5  0x00000000005201ad in static__ae6b2aac95cd_Log(_ae6b261b585b_Log&) ()
#6  0x0000000000520231 in static__ae6b2aac980e_PrintLogs(jule::Slice<_ae6b261b585b_Log>&) ()
#7  0x00000000005be9b9 in _ae6b2b56231d_buildIr(jule::Slice<jule::Str>&) ()
#8  0x00000000005bed90 in _ae6b2b562461_compileCommand(jule::Slice<jule::Str>&) ()
#9  0x00000000005b98a0 in entry_point() ()
#10 0x00000000005bf663 in main ()
(gdb) 
mertcandav commented 2 months ago

There is no way to print lines into C++ code. Could you transpile this source code with passing -t argument to compiler:

fn main() {
    outln(uint.Max)
    outln(int.Max)
    outln(int.Min)
    outln(f64.Max)
    outln(f64.Min)
    outln(f32.Max)
    outln(f32.Min)
}

Thus we will know the compiler's representation for this constants. The generated IR placed in dist/ir.cpp by default.

mingodad commented 2 months ago

I've added this to https://github.com/julelang/jule/blob/6638e5d30c5473db8f33f523a51e43662a65c492/std/jule/sema/sema.jule#L1192:

    fn checkEnumItemsInt(mut &self, mut &e: &Enum) {
        let prim = e.Kind.Kind.Prim()
    outln("==checkEnumItemsInt")
    outln(prim.Str())
    outln(types::Max(prim.Str()))
        let mut max = u64(types::Max(prim.Str()))

Then I get this output:

./build-dad.sh
==checkEnumItemsInt
int
9.22337e+18
==checkEnumItemsInt
int
9.22337e+18
==checkEnumItemsInt
int
9.22337e+18
==checkEnumItemsInt
int
9.22337e+18
==checkEnumItemsInt
int
9.22337e+18
==checkEnumItemsInt
int
9.22337e+18
==checkEnumItemsInt
int
9.22337e+18
==checkEnumItemsInt
uint
1.84467e+19
error: overflow the limit of data-type
  --> /home/mingo/dev/c/A_programming-languages/julec-ir/jule-master/std/jule/lex/token.jule:118:5
  118 | Na,
  == len(s)=

1
  int.Max/n=
3
-9223372036854775808
-3074457345618258602
panic: std::strings: repeat: integer buffer size overflow
location: /home/mingo/dev/c/A_programming-languages/julec-ir/jule-master/std/strings/strings.jule:24:9
-----------------------------------------------------------------------
An unexpected error occurred while compiling JuleC. Check errors above.
mingodad commented 2 months ago

Here is the translate source for your suggestion:

gcc-13-env /home/mingo/dev/c/A_programming-languages/julec-ir/jule-master/bin/julec_dev-gcc --compiler gcc  -t .
mingo@mingo-X550VX:~/dev/c/A_programming-languages/julec-ir/dad$ 
mingo@mingo-X550VX:~/dev/c/A_programming-languages/julec-ir/dad/dist$ cat ir.cpp 
// Auto generated by JuleC.
// JuleC version: jule0.0.12 @master
// Date: 8/5/2024 (DD/MM/YYYY) UTC
//
// Recomended Compile Command;
// g++ -w --std=c++17 -O0 dist/ir.cpp

#include "/home/mingo/dev/c/A_programming-languages/julec-ir/jule-master/api/jule.hpp"

void entry_point(void);

void entry_point(void) {
    jule::outln(0LLU);
    jule::outln(jule::MIN_I64);
    jule::outln(jule::MIN_I64);
    jule::outln(jule::MAX_F64);
    jule::outln(jule::MIN_F64);
    jule::outln(340282346638528860000000000000000000000.0);
    jule::outln(-340282346638528860000000000000000000000.0);
}

void __jule_call_initializers(void) {

}

int main(int argc, char *argv[], char *envp[]) {
    jule::setup_argv(argc, argv);
    jule::setup_envp(envp);

    __jule_call_initializers();
    entry_point();

    return EXIT_SUCCESS;
}
mertcandav commented 2 months ago

In your logs, maximum values of int and uint seems good. The compiler generates wrong IR as far as I see. Actually there is another bug that I can confirm exist in my machine, generates floats as double. Maybe it's the problem? I'll fix this and came back for this problem.

mingodad commented 2 months ago

Here is the output when compiled with clang-17:

/home/mingo/dev/c/A_programming-languages/julec-ir/jule-master/bin/julec-ir-clang -t .

mingo@mingo-X550VX:~/dev/c/A_programming-languages/julec-ir/dad/dist$ cat ir.cpp 
// Auto generated by JuleC.
// JuleC version: jule0.0.12 @master
// Date: 8/5/2024 (DD/MM/YYYY) UTC
//
// Recomended Compile Command;
// clang++ -Wno-everything --std=c++17 -O0 dist/ir.cpp

#include "/home/mingo/dev/c/A_programming-languages/julec-ir/jule-master/api/jule.hpp"

void entry_point(void);

void entry_point(void) {
    jule::outln(9223372036854775808LLU);
    jule::outln(jule::MIN_I64);
    jule::outln(jule::MIN_I64);
    jule::outln(jule::MAX_F64);
    jule::outln(jule::MIN_F64);
    jule::outln(340282346638528860000000000000000000000.0);
    jule::outln(-340282346638528860000000000000000000000.0);
}

void __jule_call_initializers(void) {

}

int main(int argc, char *argv[], char *envp[]) {
    jule::setup_argv(argc, argv);
    jule::setup_envp(envp);

    __jule_call_initializers();
    entry_point();

    return EXIT_SUCCESS;
}
mingodad commented 2 months ago

Both outputs seems to be wrong with outln(int.Max) gcc/clang output jule::outln(jule::MIN_I64);.

mertcandav commented 2 months ago

Yes. Clang generates good result except int.Max case. Also have float bug I said which is caused by compiler implementation.

mertcandav commented 2 months ago

I pushed a new commit which is fixes (as far as tested) floating-point literal generation. Can you repeat our last test with latest IR?

mingodad commented 2 months ago

I've just started again with a fresh clone and build that include the latest changes you've mention and the output remain the same for gcc/clang:


gcc-13-env /home/mingo/dev/c/A_programming-languages/julec-ir/jule-master/bin/julec_dev-gcc --compiler gcc -t .

mingo@mingo-X550VX:~/dev/c/A_programming-languages/julec-ir/dad/dist$ cat ir.cpp 
// Auto generated by JuleC.
// JuleC version: jule0.0.12 @master
// Date: 8/5/2024 (DD/MM/YYYY) UTC
//
// Recomended Compile Command;
// g++ -w --std=c++17 -O0 dist/ir.cpp

#include "/home/mingo/dev/c/A_programming-languages/julec-ir/jule-master/api/jule.hpp"

void entry_point(void);

void entry_point(void) {
    jule::outln(0LLU);
    jule::outln(jule::MIN_I64);
    jule::outln(jule::MIN_I64);
    jule::outln(jule::MAX_F64);
    jule::outln(jule::MIN_F64);
    jule::outln(jule::MAX_F32);
    jule::outln(jule::MIN_F32);
}

void __jule_call_initializers(void) {

}

int main(int argc, char *argv[], char *envp[]) {
    jule::setup_argv(argc, argv);
    jule::setup_envp(envp);

    __jule_call_initializers();
    entry_point();

    return EXIT_SUCCESS;
}
mingodad commented 2 months ago

Where in the code the output for outln(int.Max) to jule::outln(jule::MIN_I64); is generated ?

mertcandav commented 2 months ago

The new IR seems still buggy, but at least no more have floating-point literal bug.

Here is code generation functions for numerics:

mingodad commented 2 months ago

In this code: https://github.com/julelang/jule/blob/c85723bd352c2fd86c38d35d7dd8efadf160ee43/src/julec/obj/cxx/expr.jule#L811-L818

How can I output between comments the m.Expr literally (.toString()) ?

self.oc.write("/*")
self.oc.write(m.Expr.toString())
self.oc.write("*/")
self.expr(m.Expr) 
mertcandav commented 2 months ago

Which format will be used? As a Jule expression, we can't (we don't have required algorithms to do this). You probably thinking to print constant value of expression, please correct me if I am wrong. Here is my suggestion to do this:

    fn outlnCall(mut &self, mut m: &BuiltinOutlnCallExprModel) {
        if m.Debug && env::Production {
            ret
        }
        self.oc.write("jule::outln(")
        self.expr(m.Expr)
        self.oc.write(")")
        match type m.Expr {
        | &Const:
            let c = (&Const)(m.Expr)
            self.oc.write(" /* ")
            if c.IsI64() {
                self.oc.write(conv::FmtInt(c.ReadI64(), 10))
            } else if c.IsU64() {
                self.oc.write(conv::FmtUint(c.ReadU64(), 10))
            } else if c.IsF64() {
                self.oc.write(conv::FmtFloat(c.ReadF64(), 'f', -1, 64))
            }
            self.oc.write(" */")
        }
    }
mertcandav commented 2 months ago

With one of the last commits, Ubuntu CI/CD failed because of probably this problem. Then, I investigate the problem and pushed (488d74c) a fix to master branch. Relevant CI/CD actions works fine now. The patch probably will fix this problem too.

@mingodad Can you check if the problem still exists?