chapel icon indicating copy to clipboard operation
chapel copied to clipboard

[Bug]: Calling an `extern proc` with an invalid number of arguments results in an internal error

Open jabraham17 opened this issue 1 year ago • 1 comments

Summary of Problem

Description: Incorrectly specifying and calling an extern function results in an internal error with the LLVM backend. If CHPL_DEVELOPER is set or --verify is used, the internal error is replaced by a LLVM verification error.

Using the C backend gets a nicer error during codegen: too few arguments to function call, single argument 'x' was not specified. However since this error comes from the C backend compiler, there error is about foo.c instead of foo.chpl.

Steps to Reproduce

Source Code:

foo.chpl

require "lib.h";
extern proc func();
func();

lib.h

void func(int x);

lib.c

void func(int x) { }

Compile command: chpl foo.chpl lib.c

Configuration Information

  • Output of chpl --version: 2.2 prerelease
  • Output of $CHPL_HOME/util/printchplenv --anonymize:
CHPL_TARGET_PLATFORM: darwin
CHPL_TARGET_COMPILER: llvm
CHPL_TARGET_ARCH: arm64
CHPL_TARGET_CPU: native *
CHPL_LOCALE_MODEL: flat
CHPL_COMM: none
CHPL_TASKS: qthreads
CHPL_LAUNCHER: none
CHPL_TIMERS: generic
CHPL_UNWIND: none
CHPL_MEM: jemalloc
CHPL_ATOMICS: cstdlib
CHPL_GMP: system *
CHPL_HWLOC: system *
CHPL_RE2: bundled *
CHPL_LLVM: system
CHPL_AUX_FILESYS: none
  • Back-end compiler and version, e.g. gcc --version or clang --version: LLVM 18

jabraham17 avatar Aug 09 '24 12:08 jabraham17

It would be difficult to improve the situation for the C back-end without having our compiler parse .h files and validate that extern declarations match the C declarations.

The LLVM back-end effectively does this, (which is presumably what results in the internal error in developer/verify mode?), so seems more directly addressable.

bradcray avatar Aug 12 '24 22:08 bradcray

A similar case that results in the same kind of internal errors occurs when the argument types don't match

egg.chpl:

use CTypes;
require "egg.h";
extern proc egg(ref x: real);
var x: real = 1;
egg(x);

egg.h:

static void egg(double x) {}

With --verify, results in the following error

Operand is null
  call void @egg(<null operand!>) #0
egg.chpl:1: internal error: LLVM function verification failed [codegen/cg-symbol.cpp:3179]

Note that if var x was an int, the program successfully compiles with llvm, because the llvm backend silently allows passing a pointer to an int. But if the C backend is used, that case is also caught

jabraham17 avatar May 22 '25 19:05 jabraham17

I've thrown a "user issue" tag on here since the latest example Jade cites was motivated by a user issue reported on Discord.

bradcray avatar May 22 '25 20:05 bradcray