target/ppc/kvm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
GCC 16 tightens diagnostics around const correctness and now correctly
rejects attempts to modify strings referenced through const-qualified
pointers. In kvm_ppc_register_host_cpu_type(), ppc_cpu_aliases[i].model
is defined as const char *, but the code was using strstr() on it and
then modifying the returned pointer in-place to strip
POWERPC_CPU_TYPE_SUFFIX.
This results in a write through a pointer derived from const data,
triggering a build failure with GCC 16:
error: assignment discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
suffix = strstr(ppc_cpu_aliases[i].model, POWERPC_CPU_TYPE_SUFFIX);
^
Fix this by duplicating the model string into a mutable buffer using
g_strdup(), storing it in the alias table, and then performing the
suffix truncation on the mutable copy.
This preserves the existing behavior while avoiding modification of
const data and ensures compatibility with newer compilers.
No functional change intended.
Signed-off-by: Amit Machhiwal <amachhiw@linux.ibm.com>
---
target/ppc/kvm.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 25c28ad089c6..e71e5c0117da 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -2654,10 +2654,12 @@ static int kvm_ppc_register_host_cpu_type(void)
dc = DEVICE_CLASS(ppc_cpu_get_family_class(pvr_pcc));
for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
if (g_ascii_strcasecmp(ppc_cpu_aliases[i].alias, dc->desc) == 0) {
+ char *model;
char *suffix;
- ppc_cpu_aliases[i].model = g_strdup(object_class_get_name(oc));
- suffix = strstr(ppc_cpu_aliases[i].model, POWERPC_CPU_TYPE_SUFFIX);
+ model = g_strdup(object_class_get_name(oc));
+ ppc_cpu_aliases[i].model = model;
+ suffix = strstr(model, POWERPC_CPU_TYPE_SUFFIX);
if (suffix) {
*suffix = 0;
}
base-commit: ac0cc20ad2fe0b8df2e5d9458e90a095ac711ab1
--
2.50.1 (Apple Git-155)
Hi Amit,
Thanks for reporting this an proposing a fix. My review comments below:
Amit Machhiwal <amachhiw@linux.ibm.com> writes:
> GCC 16 tightens diagnostics around const correctness and now correctly
> rejects attempts to modify strings referenced through const-qualified
> pointers. In kvm_ppc_register_host_cpu_type(), ppc_cpu_aliases[i].model
> is defined as const char *, but the code was using strstr() on it and
> then modifying the returned pointer in-place to strip
> POWERPC_CPU_TYPE_SUFFIX.
>
> This results in a write through a pointer derived from const data,
> triggering a build failure with GCC 16:
>
> error: assignment discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
> suffix = strstr(ppc_cpu_aliases[i].model, POWERPC_CPU_TYPE_SUFFIX);
> ^
>
This looks more like an aliasing issue for the pointer returned by
g_strdup and it being used between const and non-const contexts.
> Fix this by duplicating the model string into a mutable buffer using
> g_strdup(), storing it in the alias table, and then performing the
> suffix truncation on the mutable copy.
>
> This preserves the existing behavior while avoiding modification of
> const data and ensures compatibility with newer compilers.
I think the better approach would be to avoid modifying the value
returned by g_strdup before its assigned to 'ppc_cpu_alias[i].model'
struct member.
>
> No functional change intended.
>
> Signed-off-by: Amit Machhiwal <amachhiw@linux.ibm.com>
> ---
> target/ppc/kvm.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> index 25c28ad089c6..e71e5c0117da 100644
> --- a/target/ppc/kvm.c
> +++ b/target/ppc/kvm.c
> @@ -2654,10 +2654,12 @@ static int kvm_ppc_register_host_cpu_type(void)
> dc = DEVICE_CLASS(ppc_cpu_get_family_class(pvr_pcc));
> for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
> if (g_ascii_strcasecmp(ppc_cpu_aliases[i].alias, dc->desc) == 0) {
> + char *model;
> char *suffix;
>
> - ppc_cpu_aliases[i].model = g_strdup(object_class_get_name(oc));
> - suffix = strstr(ppc_cpu_aliases[i].model, POWERPC_CPU_TYPE_SUFFIX);
> + model = g_strdup(object_class_get_name(oc));
while we are at it lets also handle ENOMEM error and trickle it back to arch_kvm_init()
> + ppc_cpu_aliases[i].model = model;
> + suffix = strstr(model, POWERPC_CPU_TYPE_SUFFIX);
> if (suffix) {
> *suffix = 0;
> }
>
> base-commit: ac0cc20ad2fe0b8df2e5d9458e90a095ac711ab1
> --
> 2.50.1 (Apple Git-155)
>
>
I have done the above proposed changes in a separate patch which i will
post in some time.
--
Cheers
~ Vaibhav
On Mon, May 04, 2026 at 07:13:44PM +0530, Amit Machhiwal wrote:
> GCC 16 tightens diagnostics around const correctness and now correctly
> rejects attempts to modify strings referenced through const-qualified
> pointers. In kvm_ppc_register_host_cpu_type(), ppc_cpu_aliases[i].model
> is defined as const char *, but the code was using strstr() on it and
> then modifying the returned pointer in-place to strip
> POWERPC_CPU_TYPE_SUFFIX.
>
> This results in a write through a pointer derived from const data,
> triggering a build failure with GCC 16:
>
> error: assignment discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
> suffix = strstr(ppc_cpu_aliases[i].model, POWERPC_CPU_TYPE_SUFFIX);
> ^
>
> Fix this by duplicating the model string into a mutable buffer using
> g_strdup(), storing it in the alias table, and then performing the
> suffix truncation on the mutable copy.
>
> This preserves the existing behavior while avoiding modification of
> const data and ensures compatibility with newer compilers.
>
> No functional change intended.
>
> Signed-off-by: Amit Machhiwal <amachhiw@linux.ibm.com>
> ---
> target/ppc/kvm.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> index 25c28ad089c6..e71e5c0117da 100644
> --- a/target/ppc/kvm.c
> +++ b/target/ppc/kvm.c
> @@ -2654,10 +2654,12 @@ static int kvm_ppc_register_host_cpu_type(void)
> dc = DEVICE_CLASS(ppc_cpu_get_family_class(pvr_pcc));
> for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
> if (g_ascii_strcasecmp(ppc_cpu_aliases[i].alias, dc->desc) == 0) {
> + char *model;
> char *suffix;
>
> - ppc_cpu_aliases[i].model = g_strdup(object_class_get_name(oc));
> - suffix = strstr(ppc_cpu_aliases[i].model, POWERPC_CPU_TYPE_SUFFIX);
> + model = g_strdup(object_class_get_name(oc));
> + ppc_cpu_aliases[i].model = model;
> + suffix = strstr(model, POWERPC_CPU_TYPE_SUFFIX);
> if (suffix) {
> *suffix = 0;
> }
>
A const char * variable is ideally supposed to point to an immutable
string. But even with this fix, the string that
"ppc_cpu_aliases[i].model" points to is being changed after assignment.
Would the below diff (untested) be a better fix?
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 41bd03ec2a..a84e4b4636 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -2654,13 +2654,14 @@ static int kvm_ppc_register_host_cpu_type(void)
dc = DEVICE_CLASS(ppc_cpu_get_family_class(pvr_pcc));
for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
if (strcasecmp(ppc_cpu_aliases[i].alias, dc->desc) == 0) {
- char *suffix;
+ char *suffix, *model;
- ppc_cpu_aliases[i].model = g_strdup(object_class_get_name(oc));
- suffix = strstr(ppc_cpu_aliases[i].model, POWERPC_CPU_TYPE_SUFFIX);
+ model = g_strdup(object_class_get_name(oc));
+ suffix = strstr(model, POWERPC_CPU_TYPE_SUFFIX);
if (suffix) {
*suffix = 0;
}
+ ppc_cpu_aliases[i].model = model;
break;
}
}
Hi Gautam,
Thanks for taking a look. Please find my response inline below:
On 2026/05/08 10:50 AM, Gautam Menghani wrote:
> On Mon, May 04, 2026 at 07:13:44PM +0530, Amit Machhiwal wrote:
> > GCC 16 tightens diagnostics around const correctness and now correctly
> > rejects attempts to modify strings referenced through const-qualified
> > pointers. In kvm_ppc_register_host_cpu_type(), ppc_cpu_aliases[i].model
> > is defined as const char *, but the code was using strstr() on it and
> > then modifying the returned pointer in-place to strip
> > POWERPC_CPU_TYPE_SUFFIX.
> >
> > This results in a write through a pointer derived from const data,
> > triggering a build failure with GCC 16:
> >
> > error: assignment discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
> > suffix = strstr(ppc_cpu_aliases[i].model, POWERPC_CPU_TYPE_SUFFIX);
> > ^
> >
> > Fix this by duplicating the model string into a mutable buffer using
> > g_strdup(), storing it in the alias table, and then performing the
> > suffix truncation on the mutable copy.
> >
> > This preserves the existing behavior while avoiding modification of
> > const data and ensures compatibility with newer compilers.
> >
> > No functional change intended.
> >
> > Signed-off-by: Amit Machhiwal <amachhiw@linux.ibm.com>
> > ---
> > target/ppc/kvm.c | 6 ++++--
> > 1 file changed, 4 insertions(+), 2 deletions(-)
> >
> > diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> > index 25c28ad089c6..e71e5c0117da 100644
> > --- a/target/ppc/kvm.c
> > +++ b/target/ppc/kvm.c
> > @@ -2654,10 +2654,12 @@ static int kvm_ppc_register_host_cpu_type(void)
> > dc = DEVICE_CLASS(ppc_cpu_get_family_class(pvr_pcc));
> > for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
> > if (g_ascii_strcasecmp(ppc_cpu_aliases[i].alias, dc->desc) == 0) {
> > + char *model;
> > char *suffix;
> >
> > - ppc_cpu_aliases[i].model = g_strdup(object_class_get_name(oc));
> > - suffix = strstr(ppc_cpu_aliases[i].model, POWERPC_CPU_TYPE_SUFFIX);
> > + model = g_strdup(object_class_get_name(oc));
> > + ppc_cpu_aliases[i].model = model;
> > + suffix = strstr(model, POWERPC_CPU_TYPE_SUFFIX);
> > if (suffix) {
> > *suffix = 0;
> > }
> >
>
> A const char * variable is ideally supposed to point to an immutable
> string. But even with this fix, the string that
> "ppc_cpu_aliases[i].model" points to is being changed after assignment.
Thanks, I get your point. The write in my version is to the mutable buffer
returned by g_strdup(), so it is not strictly a const write. I had originally
trimmed the duplicated buffer before assigning it to ppc_cpu_aliases[i].model,
but later reordered it to stay closer to the existing flow. Still, I agree with
the suggested cleaner ordering. I will update it in the next revision.
Thanks,
Amit
> Would the below diff (untested) be a better fix?
>
> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> index 41bd03ec2a..a84e4b4636 100644
> --- a/target/ppc/kvm.c
> +++ b/target/ppc/kvm.c
> @@ -2654,13 +2654,14 @@ static int kvm_ppc_register_host_cpu_type(void)
> dc = DEVICE_CLASS(ppc_cpu_get_family_class(pvr_pcc));
> for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
> if (strcasecmp(ppc_cpu_aliases[i].alias, dc->desc) == 0) {
> - char *suffix;
> + char *suffix, *model;
>
> - ppc_cpu_aliases[i].model = g_strdup(object_class_get_name(oc));
> - suffix = strstr(ppc_cpu_aliases[i].model, POWERPC_CPU_TYPE_SUFFIX);
> + model = g_strdup(object_class_get_name(oc));
> + suffix = strstr(model, POWERPC_CPU_TYPE_SUFFIX);
> if (suffix) {
> *suffix = 0;
> }
> + ppc_cpu_aliases[i].model = model;
> break;
> }
> }
© 2016 - 2026 Red Hat, Inc.