LLVM ERROR: Broken module found / Duplicate integer as switch case
iErik opened this issue · comments
Context
- Operating System: NixOS Unstable
- Odin version: dev-2024-06 (Slightly modified to run on LLVM 17 and with a pre-compiled stb vendor library, since
vendor:stb
by default it doesn't seem to work out of the box on Linux) odin report
:
Odin: dev-2024-06
OS: NixOS 24.11 (Vicuna), Linux 6.9.5-zen1
CPU: AMD Ryzen 9 7950X 16-Core Processor
RAM: 31228 MiB
Backend: LLVM 17.0.6
Odin build instructions in Nix:
{ lib
, fetchFromGitHub
, llvmPackages_17
, makeBinaryWrapper
, libiconv
, which
}:
let
llvmPackages = llvmPackages_17;
inherit (llvmPackages) stdenv;
in stdenv.mkDerivation rec {
pname = "odin";
version = "dev-2024-06";
src = fetchFromGitHub {
owner = "odin-lang";
repo = "Odin";
rev = version;
hash = "sha256-JGTC+Gi5mkHQHvd5CmEzrhi1muzWf1rUN4f5FT5K5vc=";
};
nativeBuildInputs = [
makeBinaryWrapper which
];
buildInputs = [ ] ;
LLVM_CONFIG = "${llvmPackages.llvm.dev}/bin/llvm-config";
postPatch = ''
substituteInPlace build_odin.sh \
--replace-fail '-framework System' '-lSystem'
patchShebangs build_odin.sh
'';
dontConfigure = true;
buildFlags = [
"release"
];
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp odin $out/bin/odin
mkdir -p $out/share
cp -r base $out/share/base
cp -r core $out/share/core
cp -r vendor $out/share/vendor
wrapProgram $out/bin/odin \
--prefix PATH : ${lib.makeBinPath (with llvmPackages; [
bintools
llvm
clang
lld
])} \
--set-default ODIN_ROOT $out/share
runHook postInstall
'';
postBuild = lib.optionalString stdenv.isLinux ''
make -C vendor/stb/src
make -C vendor/cgltf/src
'';
meta = with lib; {
description = "A fast, concise, readable, pragmatic and open sourced programming language";
mainProgram = "odin";
homepage = "https://odin-lang.org/";
license = licenses.bsd3;
maintainers = with maintainers; [ luc65r astavie znaniye ];
platforms = platforms.x86_64 ++ [ "aarch64-darwin" ];
};
}
Expected Behavior
The following code should cast the variable listener.handler
from ListenerProc
(union
) to MouseButtonHandler
(#type proc
)
onMouseButton :: proc (
window: Window,
button, action, mod: c.int
) {
scene := cast(^Scene) glfw.GetWindowUserPointer(window)
for &listener in scene.listeners {
if type_of(listener.handler) == MouseButtonHandler {
listener.handler.(MouseButtonHandler)(
scene, listener.dataPtr, window,
button, action, mod)
}
}
}
Listener :: struct {
dataPtr: rawptr,
handler: ListenerProc
}
ListenerProc :: union {
MouseMoveHandler,
MouseButtonHandler,
MouseEnterHandler,
KeyEventHandler,
CharEventHandler,
ScrollHandler,
FramebufferSizeHandler
}
MouseMoveHandler :: #type proc (
scene: ^Scene,
dataPtr: rawptr,
win: Window,
xPos, yPos: f64)
MouseButtonHandler :: #type proc (
scene: ^Scene,
dataPtr: rawptr,
win: Window,
button: MouseButton,
action: ButtonAction,
mods: c.int)
MouseEnterHandler :: #type proc (
scene: ^Scene,
dataPtr: rawptr,
win: Window,
entered: bool)
KeyEventHandler :: #type proc (
scene: ^Scene,
dataPtr: rawptr,
win: Window,
key, scancode, action, mods: c.int)
CharEventHandler :: #type proc (
scene: ^Scene,
dataPtr: rawptr,
win: Window,
codepoint: rune)
ScrollHandler :: #type proc (
scene: ^Scene,
dataPtr: rawptr,
win: Window,
xOffset, yOffset: f64)
FramebufferSizeHandler :: #type proc (
scene: ^Scene,
dataPtr: rawptr,
win: Window,
width, height: c.int)
Current Behavior
Compiler gives me the following error when I try to run the code with odin run:
Duplicate integer as switch case
switch i64 %4, label %bfalse [
i64 0, label %bcase
i64 1, label %bcase1
i64 2, label %bcase2
i64 3, label %bcase3
i64 4, label %bcase4
i64 5, label %bcase5
i64 1, label %bcase6
i64 7, label %bcase7
]
i64 1
LLVM ERROR: Broken module found, compilation aborted!
This happens whenever I try to cast a variable of type ListenerProc
to any type within the union. I found out that this happens because two #type procs
inside the ListenerProc
union have the same function signature:
ScrollHandler :: #type proc (
scene: ^Scene,
dataPtr: rawptr,
win: Window,
xOffset, yOffset: f64)
And
MouseMoveHandler :: #type proc (
scene: ^Scene,
dataPtr: rawptr,
win: Window,
xPos, yPos: f64)
The code works as intended if either of these proc
types are omitted in the ListenerProc
union. The compiler understands both of them to be the same despite being distinct type definitions, and when both are present within the same union
type it thinks that one of the union
values is duplicated