Skip to content

is54/uvselp: fix segfault by adding ANSI C prototypes#184

Open
ludomal wants to merge 1 commit into
openitu:devfrom
ludomal:fix/uvselp-knr-prototypes
Open

is54/uvselp: fix segfault by adding ANSI C prototypes#184
ludomal wants to merge 1 commit into
openitu:devfrom
ludomal:fix/uvselp-knr-prototypes

Conversation

@ludomal
Copy link
Copy Markdown
Member

@ludomal ludomal commented May 31, 2026

Fix uvselp segfault on modern compilers (GCC 6+, Clang, MSVC)

Summary

Replace K&R-style empty-parentheses function declarations in src/is54/ with proper ANSI C prototypes. This fixes segfaults/crashes that occur with any modern compiler.

Note that bit-exact output verification tests are not included because floating-point rounding produces platform-dependent results differing by more than ±1. This is pre-existing (#24) and inherent to float arithmetic, and original tests vectors could not be verified on any tested platforms (AMR64 and x86).

This PR:

Problem

The IS-54 VSELP codec uses 1990-era K&R function declarations:

/* In header files */
FTYPE EXCITE ();
FTYPE RS_RR ();
int G_QUANT ();

/* K&R function definition */
FTYPE RES_ENG (rq0, k)
     FTYPE rq0;
     FTYPE *k;
{ ... }

When FTYPE is float (the default), this triggers C default argument promotion: callers promote float arguments to double because no prototype is visible. But the function bodies expect float parameters. This ABI mismatch causes:

  • GCC 6+ / Clang on x86-64: segfault in EXCITE. gsp0 receives a garbage value because register assignments are shifted by the size mismatch
  • MSVC: assert(tmp >= 0) fails in RES_ENG (interp.c:134). rq0 receives corrupted data, producing negative values under sqrt
  • ARM64 (Apple Silicon, aarch64): bus error (EXC_BAD_ACCESS). float is passed in S registers, double in D registers, completely different register banks

Fix

Added proper ANSI C prototypes to all header files and converted K&R function definitions to ANSI style:

File Change
r_sub.h Full prototypes for 7 functions
t_sub.h Full prototypes for 12 functions
vselp.h Full prototypes for 20 functions
vselp.c Fix get_codes/put_codes function pointer declarations
interp.c Convert RES_ENG K&R definition to ANSI; fix ATORC forward decl
makec.c Convert A_SST K&R definition to ANSI; fix ATORC, ATOCOR, LEVINSON forward decls
g_quant.c Fix corr forward declaration
lag.c Fix i_resp forward declaration

The internal precision remains float (FTYPE). The fix only corrects the calling convention so arguments are passed in the correct registers/stack positions. The algorithm and arithmetic are unchanged.

Replace K&R-style empty-parentheses function declarations with proper
ANSI C prototypes. The missing prototypes caused default argument
promotion (float->double) at call sites, while function bodies expected
float parameters. This ABI mismatch causes segfaults on GCC 6+, Clang,
MSVC, and ARM64 platforms.

Convert two K&R function definitions (RES_ENG, A_SST) to ANSI style.
Fix all forward declarations in .c and .h files to include parameter
types. Fix function pointer declarations for get_codes/put_codes.

The existing tests verify the tool runs without crashing. Bit-exact
output verification is not included because floating-point rounding
produces platform-dependent results.

Fixes openitu#132, Fixes openitu#41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UVSELP: segfaults using GCC 6+ or CLANG [TESTS] uvselp: assert fails using MSVC

1 participant