Analyzability (since C11)
Esta extensión opcional del lenguaje C limita los resultados potenciales de ejecutar algunas formas de comportamiento indefinido, lo que mejora la efectividad del análisis estático de dichos programas. La capacidad de análisis solo se garantiza habilitada si la macro constante predefinida __STDC_ANALYZABLE__ está definida por el compilador.
Si el compilador admite analizabilidad, cualquier construcción de lenguaje o biblioteca cuyo comportamiento sea indefinido se clasifica adicionalmente entre comportamiento indefinido crítico y comportamiento indefinido acotado , y el comportamiento de todos los casos de UB acotado se limita como se especifica a continuación.
Contenidos |
Comportamiento indefinido crítico
UB crítico es undefined behavior que podría realizar una escritura de memoria o una lectura de memoria volátil fuera de los límites de cualquier objeto. Un programa que tiene undefined behavior crítico puede ser susceptible a exploits de seguridad.
Solo los siguientes comportamientos indefinidos son críticos:
- acceso a un objeto fuera de su lifetime (ej. a través de un puntero colgante)
- escritura a un objeto cuyas declaraciones no son compatible
- llamada a función a través de un puntero a función cuyo tipo no es compatible con el tipo de la función a la que apunta
- lvalue expression es evaluada, pero no designa un objeto
- intento de modificación de un string literal
- dereferencing un puntero inválido (null, indeterminado, etc.) o past-the-end
- modificación de un const object a través de un puntero no constante
- llamada a una función o macro de la biblioteca estándar con un argumento inválido
- llamada a una función variádica de la biblioteca estándar con tipo de argumento inesperado (ej. llamada a printf con un argumento de tipo que no coincide con su especificador de conversión)
- longjmp donde no hay setjmp en el ámbito de llamada, a través de hilos, o desde dentro del ámbito de un tipo VM.
- cualquier uso del puntero que fue desasignado por free o realloc
- cualquier función de biblioteca de string o wide string accede a un array fuera de límites
Comportamiento indefinido acotado
UB acotado es comportamiento indefinido que no puede realizar una escritura de memoria ilegal, aunque puede generar una trampa y puede producir o almacenar valores indeterminados.
- Todo comportamiento indefinido no listado como crítico está acotado, incluyendo
-
- carreras de datos en multihilo
- uso de valores indeterminados con duración de almacenamiento automático
- violaciones de strict aliasing
- acceso a objetos desalineados
- desbordamiento de enteros con signo
- efectos secundarios no secuenciados que modifican el mismo escalar o modifican y leen el mismo escalar
- desbordamiento en conversión de conversión de flotante a entero o de puntero a entero
- desplazamiento bit a bit por un conteo de bits negativo o demasiado grande
- división entera por cero
- uso de una expresión void
- asignación directa o memcpy de objetos con superposición inexacta
- violaciones de restrict
- etc... TODO comportamiento indefinido que no esté en la lista crítica.
Notas
El comportamiento indefinido acotado deshabilita ciertas optimizaciones: la compilación con analizabilidad habilitada preserva la causalidad del código fuente, que podría verse violada por comportamiento indefinido de otro modo.
La extensión de analizabilidad permite, como una forma de comportamiento definido por la implementación, que el runtime constraint handler sea invocado cuando ocurre un trap.
Referencias
- Estándar C23 (ISO/IEC 9899:2024):
-
- 6.10.10.4/1 Macros de características condicionales (p: 188-189)
-
- Anexo L Analizabilidad (p: 672-673)
- Estándar C17 (ISO/IEC 9899:2018):
-
- 6.10.8.3/1 Macros de características condicionales (p: 128-129)
-
- Anexo L Analizabilidad (p: 473-474)
- Estándar C11 (ISO/IEC 9899:2011):
-
- 6.10.8.3/1 Macros de características condicionales (p: 177)
-
- Anexo L Analizabilidad (p: 652-653)