GCC global-register warning suppression does not restore caller diagnostic state
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 3/5
- Tempo estimado
- 1-2 dias
- Facilidade para iniciantes
- 78/100
- Tipo de issue
- Bug
- Clareza
- Claramente especificada
- Status de atividade
- Ativa
- Domínio
- build-system, compilers
Direção de pesquisa
Inspecione os blocos de diagnóstico do GCC ao redor das global-register declarations em Zend/zend_execute.c e ext/opcache/jit/zend_jit_vm_helpers.c. Comece comparando as transições atuais de estado de pragma com o comportamento de diagnostic push/pop do GCC. O trabalho estará concluído quando cada supressão estiver limitada ao seu declaration block e a política de warnings ou erros do caller continuar efetiva depois; valide isso com os comandos de reprodução descritos na issue.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
Description
The GCC diagnostic pragmas around PHP's required global-register declarations do not restore the warning policy selected by the build. They replace it with PHP's own policy for the remainder of each translation unit.
The affected sites are:
Zend/zend_execute.c, around theexecute_datadeclaration;Zend/zend_execute.c, around theoplinedeclaration;ext/opcache/jit/zend_jit_vm_helpers.c, around its global-register declaration block.
Each site currently uses this shape:
#pragma GCC diagnostic ignored "-Wvolatile-register-var"
/* required global register declaration */
#pragma GCC diagnostic warning "-Wvolatile-register-var"
The final warning is not the inverse of ignored. GCC documents diagnostic pragmas as overriding command-line options; specifically, warning makes the diagnostic a warning even when -Werror is in effect. Only push / pop saves and restores the previous state.
This creates a policy-ownership conflict. PHP legitimately needs a narrow exception for these declarations, while the build system or downstream packager owns the diagnostic policy for the translation unit. The current code lets the narrow exception overwrite that caller policy after the exception has ended:
| Caller-selected policy | State after the current PHP block | Consequence |
|---|---|---|
-Wno-volatile-register-var |
forced to warning |
a warning the caller explicitly disabled is re-enabled |
-Werror=volatile-register-var |
forced to warning |
an error the caller explicitly requested is downgraded, so compilation can succeed |
The affected blocks occur near the start of files containing 5,733 and 1,327 lines respectively, so the unintended state covers most of both translation units. The problem is not that PHP suppresses its own deliberate declarations; the problem is that the suppression is not scoped to those declarations.
Steps to reproduce
This is a compiler-state issue rather than PHP runtime behavior, so it cannot be demonstrated with a PHP snippet or 3v4l.
On x86-64 Linux with GCC, the essential behavior can be seen with:
#pragma GCC diagnostic ignored "-Wvolatile-register-var"
register void *volatile php_required_register __asm__("%r14");
#pragma GCC diagnostic warning "-Wvolatile-register-var"
register void *volatile post_php_oracle __asm__("%r13");
Compile it once with -Wno-volatile-register-var and once with -Werror=volatile-register-var.
I also tested the actual PHP sources rather than relying only on this reduced example:
- Configure
PHP-8.4with--disable-all --enable-opcache --enable-opcache-jit; configure detectsHAVE_GCC_GLOBAL_REGS=1. - Compile the real
Zend/zend_execute.loandext/opcache/jit/zend_jit_vm_helpers.loobjects. - Compile wrappers containing each complete source file followed by the valid
%r13global-register oracle shown above, using the owning object's generated include paths and defines. - Run both wrappers with
-Wno-volatile-register-varand-Werror=volatile-register-var.
Actual behavior
With the current source:
| Caller policy | Result after the complete PHP source |
|---|---|
-Wno-volatile-register-var |
exit 0, but the post-source oracle warns |
-Werror=volatile-register-var |
exit 0; the post-source oracle is only a warning |
Thus the first policy is unexpectedly re-enabled and the second is silently downgraded.
Expected behavior
PHP's suppression should apply only to its required global-register declarations. The exact caller state—disabled, warning, or error—should resume immediately afterward.
Using #pragma GCC diagnostic push before ignored and #pragma GCC diagnostic pop after the declarations produces the expected result in both complete translation units:
| Caller policy | Result with scoped suppression |
|---|---|
-Wno-volatile-register-var |
exit 0, no diagnostic |
-Werror=volatile-register-var |
exit 1; the post-source oracle is an error |
This change does not alter the treatment of PHP's own global-register declarations.
Impact and scope
This is a bounded compiler-policy bug. I found no declaration later in the current owning files that presently triggers -Wvolatile-register-var, so the unmodified configured objects build successfully. I am not reporting a current default-build failure, runtime miscompile, or security impact.
The demonstrated defect is loss of caller policy. A later PHP change, a platform/configuration-specific branch, instrumentation, or a downstream patch can consequently emit a warning that the build disabled or, more importantly, be silently downgraded from an explicitly requested error.
The same source pattern is present in the inspected PHP-8.4, PHP-8.5, and master (8.6.0-dev) branch tips.
LLM disclosure: The wording of this report was prepared with LLM assistance. The source relations, supported branches, compiler behavior, full-translation-unit results, and proposed patch were independently checked against the repository and disposable GCC builds.
PHP Version
`PHP-8.4` development branch at commit `2bca7364790124b75fbfc9e10b08277e3744cafd`. The same pattern was also confirmed in the inspected `PHP-8.5` and master branch tips.
Operating System
Ubuntu 22.04 (x86-64), GCC 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04.3).
- Linguagem predominante
- C
- Estrelas
- 40.4k
- Forks
- 8.2k
- Merge médio
- 2d 17h
- PRs com merge (30d)
- 115
Guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de php/php-src
-
Bug Status: Needs Triage
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
-
Bug Status: Needs Triage
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 90/100
-
Bug Status: Needs Triage
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
-
Flaky hrtime.phpt test AbertaBug Category: Tests Status: Verified
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
-
Bug SAPI: fpm Status: Needs Triage
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 65/100
Todas as issues de php/php-src
Issues semelhantes
-
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 88/100
zephyrproject-rtos/zephyr#120318 · 1 comentário ·
-
issue: bug report
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 90/100
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 88/100
darktable-org/darktable#22386 ·
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 70/100
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100