Skip to content

ami_parse_bdf() discards const from strchr() result. Build fails under C23 + glibc ≥ 2.41 (Ubuntu 26.04) #39

@amd-vserbu

Description

@amd-vserbu

Component: sw/AMI/api/src/ami.c

Summary

ami_parse_bdf() assigns the result of strchr() (called on a const char *) into a non-const char *. This silently discarded const on older toolchains, but is now a hard error when building in C23 mode against glibc ≥ 2.41, which ships C23 const-correct strchr overloads. Because api/Makefile builds with -Wall -Werror, the warning is fatal.

Affected code

sw/AMI/api/src/ami.c, ami_parse_bdf():

uint16_t ami_parse_bdf(const char *bdf)
{
    ...
    char *c = NULL;            /* line 386 */
    ...
    c = strchr(bdf, ':');      /* line 392 — const discarded here */
    if (c && ((size_t)(c - bdf) == BDF_DOMAIN_END))
        ...
}

bdf is const char *. With the C23 declaration of strchr, the return type is const char *, so assigning to char *c discards the qualifier. c is only ever used for strchr's result, a null check, and the pointer subtraction (c - bdf) — it is never used to mutate the string.

Diagnostic

ami.c:392:11: error: assignment discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
  392 |         c = strchr(bdf, ':');
      |           ^
cc1: all warnings being treated as errors

Build flags from sw/AMI/api/Makefile: -Wall -Werror, no explicit -std= (so the compiler default applies).

Root cause

The trigger is the combination of C23 mode and glibc ≥ 2.41, not a specific GCC version:

  • glibc 2.41 added C23 const-correct overloads to <string.h>: it now declares both char *strchr(char *) and const char *strchr(const char *). For a const char * argument, strchr returns const char *.
  • In C17 and earlier, <string.h> declares only the legacy char *strchr(const char *), so the assignment is valid.
  • GCC 15 defaults to C23, so it fails out of the box; earlier GCC only fails when -std=gnu23/-std=c23 is passed explicitly.

Reproduction matrix

Original code, -Wall -Werror:

Distro GCC glibc default std -std=gnu17 -std=gnu23
Ubuntu 24.04 11.5 / 12.4 / 13.3 / 14.2 2.39 pass pass pass
Ubuntu 26.04 14.3 2.43 pass pass fail
Ubuntu 26.04 15.2 2.43 fail pass fail

Minimal reproducer

#include <string.h>
#include <stddef.h>

size_t first_colon_offset(const char *s)
{
    char *c = strchr(s, ':');           /* discards const under C23 + glibc>=2.41 */
    return c ? (size_t)(c - s) : 0;
}
gcc -std=gnu23 -Wall -Werror -c repro.c   # fails on glibc >= 2.41
gcc -std=gnu17 -Wall -Werror -c repro.c   # passes

Suggested fix

Declare the cursor as const char *, which is correct in all language modes since the pointer is never used to mutate the string:

-    char *c = NULL;
+    const char *c = NULL;

This compiles cleanly across all GCC versions, glibc versions, and standard modes tested.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions