Re: [PATCH v3 02/15] cpus: Add const-qualified CPU environment accessors
Philippe Mathieu-Daudé <[email protected]>
| Newsgroups | org.nongnu.qemu-arm,org.nongnu.qemu-devel,org.nongnu.qemu-riscv |
|---|---|
| Message-ID | <[email protected]> |
On 2026-08-21 13:33, Philippe Mathieu-Daudé wrote: > On 21/8/26 12:49, Philippe Mathieu-Daudé wrote: >> From: Philippe Mathieu-Daudé <[email protected]> >> >> Use _Generic() controlling-expression to add the const-qualified >> variants of cpu_env(), env_cpu() and env_archcpu(). This allows to >> safely access CPU architecture state when it should not be modified. >> >> Alias env_cpu_const() which is still used. >> >> Suggested-by: Richard Henderson <[email protected]> >> Signed-off-by: Philippe Mathieu-Daudé <[email protected]> >> Signed-off-by: Philippe Mathieu-Daudé <[email protected]> >> Reviewed-by: Marc-André Lureau <[email protected]> >> Reviewed-by: Richard Henderson <[email protected]> >> --- >> Following checkpatch.pl errors ignored: >> >> ERROR: spaces required around that ':' (ctx:VxE) >> #46: FILE: include/exec/cpu-common.h:89: >> + CPUArchState: \ >> ^ >> ERROR: spaces required around that ':' (ctx:VxE) >> #62: FILE: include/exec/cpu-common.h:101: >> + CPUArchState: \ >> ^ >> ERROR: spaces required around that ':' (ctx:VxE) >> #90: FILE: include/hw/core/cpu.h:605: >> + CPUState: \ >> ^ >> total: 3 errors, 0 warnings, 64 lines checked >> --- >> include/exec/cpu-common.h | 30 +++++++++++------------------- >> include/hw/core/cpu.h | 17 ++++++++++++----- >> 2 files changed, 23 insertions(+), 24 deletions(-) >> >> diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h >> index 6594f7fa1be..bffef677607 100644 >> --- a/include/exec/cpu-common.h >> +++ b/include/exec/cpu-common.h >> @@ -85,21 +85,11 @@ static inline bool cpu_loop_exit_requested(const >> CPUState *cpu) >> * >> * Return the ArchCPU associated with the environment. >> */ >> -static inline ArchCPU *env_archcpu(CPUArchState *env) >> -{ >> - return (void *)env - sizeof(CPUState); >> -} >> - >> -/** >> - * env_cpu_const(env) >> - * @env: The architecture environment >> - * >> - * Return the CPUState associated with the environment. >> - */ >> -static inline const CPUState *env_cpu_const(const CPUArchState *env) >> -{ >> - return (void *)env - sizeof(CPUState); >> -} >> +#define env_archcpu(env) _Generic(*(env), \ >> + CPUArchState: \ >> + (ArchCPU *)((void *)env - sizeof(CPUState)), \ >> + const CPUArchState: \ >> + (const ArchCPU *)((const void *)env - sizeof(CPUState))) > I was testing with a C17-ready compiler. Apparently C11 is ambiguous in > how it treats qualifiers inside _Generic: > > ../../target/arm/internals.h:1777:25: warning: due to lvalue conversion > of the controlling expression, association of type 'const CPUArchState' > (aka 'const struct CPUArchState') will never be selected because it is > qualified [-Wunreachable-code-generic-assoc] > 1777 | const ARMCPU *cpu = env_archcpu(env); > | ^ > include/exec/cpu-common.h:91:19: note: expanded from macro 'env_archcpu' > 91 | const CPUArchState: \ > | ^ > > Using typeof() makes it happier: > > -- >8 -- > diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h > index d67d008236f..e3a5e40899f 100644 > --- a/include/exec/cpu-common.h > +++ b/include/exec/cpu-common.h > @@ -87,6 +87,6 @@ static inline bool cpu_loop_exit_requested(const > CPUState *cpu) > */ > -#define env_archcpu(env) _Generic(*(env), \ > - CPUArchState: \ > +#define env_archcpu(env) _Generic(typeof(*env), \ > + typeof(CPUArchState): \ > (ArchCPU *)((void *)env - sizeof(CPUState)), \ > - const CPUArchState: \ > + typeof(const CPUArchState): \ > (const ArchCPU *)((const void *)env - sizeof(CPUState))) > @@ -99,6 +99,6 @@ static inline bool cpu_loop_exit_requested(const > CPUState *cpu) > */ > -#define env_cpu(env) _Generic(*(env), \ > - CPUArchState: \ > +#define env_cpu(env) _Generic(typeof(*env), \ > + typeof(CPUArchState): \ > (CPUState *)((void *)env - sizeof(CPUState)), \ > - const CPUArchState: \ > + typeof(const CPUArchState): \ > (const CPUState *)((const void *)env - sizeof(CPUState))) > diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h > index 372485a2e54..ee522e1e705 100644 > --- a/include/hw/core/cpu.h > +++ b/include/hw/core/cpu.h > @@ -602,7 +602,7 @@ QEMU_BUILD_BUG_ON(offsetof(CPUState, neg) != > */ > -#define cpu_env(cpu) _Generic(*(cpu), \ > +#define cpu_env(cpu) _Generic(typeof(*cpu), \ > /* We validate that CPUArchState follows CPUState in cpu- > target.c */ \ > - CPUState: \ > + typeof(CPUState): \ > (CPUArchState *)(cpu + 1), \ > - const CPUState: \ > + typeof(const CPUState): \ > (const CPUArchState *)(cpu + 1)) > --- No, this now fails distinctly on Ubuntu 24.04: In file included from ../accel/tcg/tcg-runtime.c:26: ../accel/tcg/tcg-runtime.c: In function ‘helper_exit_atomic’: /home/runner/work/qemu/qemu/include/exec/cpu-common.h:100:31: error: expected expression before ‘typeof’ 100 | #define env_cpu(env) _Generic(typeof(*env), \ | ^~~~~~ ../accel/tcg/tcg-runtime.c:135:26: note: in expansion of macro ‘env_cpu’ 135 | cpu_loop_exit_atomic(env_cpu(env), GETPC()); | ^~~~~~~ I'm a bit clueless. In case you want to have a look, the series is available here: https://github.com/qualcomm/qemu/commits/refs/heads/philmd/cpu_has_work_const/ Thanks, Phil.