ponyc icon indicating copy to clipboard operation
ponyc copied to clipboard

ponyc Segmentation Fault (core dumped) when given broken code.

Open redvers opened this issue 4 years ago • 5 comments

While trying to understand error messages and precedence I may have triggered a compiler bug. I completely did it myself so please feel free to just close it if it is not useful.

The root error of course is that I'm trying to shr greater than the size of the datastructure. The error for that is straightforward.

When I try to print the result, I get the expected argument not subtype of parameter.

When I try to call string() on the expression which is illegal - the compiler core dumps.

actor Main
  new create(env: Env) =>
    let y: U32 val = 1
//    let y31: U32 val = y.shr(32)    // (compile fail) shift amount greater than type width
//    let unk = y.shr(32)             // (compile fail) shift amount greater than type width
//    env.out.print(y.shr(32))        // (compile fail) argument not a subtype of parameter
      env.out.print(y.shr(33).string())   // Compiler Dumps Core

Error:

[nix-shell:~/projects/pony/notjs]$ ponyc .
Building builtin -> /nix/store/i31sdrkcnjsxaw1fn98mdmnglnrm9z87-ponyc-0.31.0/lib/pony/0.31.0/packages/builtin
Building . -> /home/red/projects/pony/notjs
Generating
 Reachability
 Selector painting
 Data prototypes
 Data types
 Function prototypes
 Functions
 Descriptors
Optimising
Stack dump:
0.      Running pass 'Interprocedural Sparse Conditional Constant Propagation' on module 'notjs'.
Segmentation fault (core dumped)

I had a friend on (not)NixOS confirm too.

(like I said - self inflicted)

Pony version:

0.31.0 [release]
compiled with: llvm 7.1.0 -- gcc (GCC) 8.3.0
Defaults: pic=false

I'm compiling 0.32.0 to test too...

redvers avatar Oct 09 '19 22:10 redvers

@redvers can you run ponyc --version and add the output to your report? Thanks.

SeanTAllen avatar Oct 09 '19 23:10 SeanTAllen

Done above - also - I installed 0.32.0 too with the same result:

0.32.0 [release]
compiled with: llvm 7.1.0 -- gcc (GCC) 8.3.0
Defaults: pic=false

Red

redvers avatar Oct 10 '19 02:10 redvers

Thanks for the detailed issue ticket!

As you show, there is an edge case of some kind in which the compiler's logic for statically checking the number of bits to shift against the type width, so that this check isn't happening as it should, or isn't happening correctly, when it is specified inline with the .string() suffix.

That is, when we generate LLVM code for the shr method, we have two approaches for doing so:

  • if the number of bits is a constant value (like an integer literal), we check it against the type width at compile time and issue a compile error if warranted (the "shift amount greater than type width" error mentioned above)
  • otherwise, the number of bits is not known at compile time and must be checked at runtime, so we generate slightly slower code that will check the number of bits at runtime before shifting, so that it is clamped to be at most equal to the maximum value we allow.

See the code here: https://github.com/ponylang/ponyc/blob/70d471d2394c8c3c6f6e952b70f69e19db9f0569/src/libponyc/codegen/genoperator.c#L727-L786

Obviously, since it is a literal integer we expect it to take the first path here and catch the issue at compile time, but for some reason in this edge case it is not. I suspect that is resulting in an LLVM undef or poison value being generated as the result, breaking later LLVM optimizations.

Since I'm familiar with this part of the code I'll assign myself and try to take a look at this soon.

jemc avatar Oct 15 '19 16:10 jemc

@jemc should we remove you from this issue and add "help wanted"?

SeanTAllen avatar Jan 27 '22 06:01 SeanTAllen

Yes, I'll un-assign myself, but if anyone wants help understanding the LLVM code gen stuff in this area of the compiler I'd be happy to assist in that way.

jemc avatar Jan 29 '22 16:01 jemc