[libc-commits] [libc] [libc] Add explicit format attributes for modular printf (PR #201212)

Daniel Thornburgh via libc-commits libc-commits at lists.llvm.org
Tue Jun 2 14:51:46 PDT 2026


https://github.com/mysterymath created https://github.com/llvm/llvm-project/pull/201212

We had been relying on compiler-generated format attributes when using the modular_format attribute for printf-family functions, but this is not applied in -ffreestanding mode. When modular format is enabled, libc is explicitly asserting the semantics of these functions, so it should be explicit about the format attributes as well to keep them from breaking in -ffreestanding.

>From 6686bfddc6fa0d0b4c1e5d6d6aa8f6b59d0fefab Mon Sep 17 00:00:00 2001
From: Daniel Thornburgh <dthorn at google.com>
Date: Tue, 2 Jun 2026 14:35:13 -0700
Subject: [PATCH] [libc] Add explicit format attributes for modular printf

We had been relying on compiler-generated format attributes when using
the modular_format attribute for printf-family functions, but this is
not applied in -ffreestanding mode. When modular format is enabled, libc
is explicitly asserting the semantics of these functions, so it should
be explicit about the format attributes as well to keep them from
breaking in -ffreestanding.
---
 .../_LIBC_MODULAR_FORMAT_PRINTF-disable.h        |  2 +-
 .../_LIBC_MODULAR_FORMAT_PRINTF.h                |  6 ++++--
 libc/include/stdio.yaml                          | 16 ++++++++--------
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/libc/include/llvm-libc-macros/_LIBC_MODULAR_FORMAT_PRINTF-disable.h b/libc/include/llvm-libc-macros/_LIBC_MODULAR_FORMAT_PRINTF-disable.h
index e3238161b3808..57aacadc704b5 100644
--- a/libc/include/llvm-libc-macros/_LIBC_MODULAR_FORMAT_PRINTF-disable.h
+++ b/libc/include/llvm-libc-macros/_LIBC_MODULAR_FORMAT_PRINTF-disable.h
@@ -9,6 +9,6 @@
 #ifndef LLVM_LIBC_MACROS_LIBC_MODULAR_FORMAT_PRINTF_H
 #define LLVM_LIBC_MACROS_LIBC_MODULAR_FORMAT_PRINTF_H
 
-#define _LIBC_MODULAR_FORMAT_PRINTF(MODULAR_IMPL_FN)
+#define _LIBC_MODULAR_FORMAT_PRINTF(MODULAR_IMPL_FN, FORMAT_IDX, FIRST_TO_CHECK)
 
 #endif // LLVM_LIBC_MACROS_LIBC_MODULAR_FORMAT_PRINTF_H
diff --git a/libc/include/llvm-libc-macros/_LIBC_MODULAR_FORMAT_PRINTF.h b/libc/include/llvm-libc-macros/_LIBC_MODULAR_FORMAT_PRINTF.h
index 918241ab8f2ec..8e6efe8868625 100644
--- a/libc/include/llvm-libc-macros/_LIBC_MODULAR_FORMAT_PRINTF.h
+++ b/libc/include/llvm-libc-macros/_LIBC_MODULAR_FORMAT_PRINTF.h
@@ -9,7 +9,9 @@
 #ifndef LLVM_LIBC_MACROS_LIBC_MODULAR_FORMAT_PRINTF_H
 #define LLVM_LIBC_MACROS_LIBC_MODULAR_FORMAT_PRINTF_H
 
-#define _LIBC_MODULAR_FORMAT_PRINTF(MODULAR_IMPL_FN)                           \
-  __attribute__((modular_format(MODULAR_IMPL_FN, "__printf", "float")))
+#define _LIBC_MODULAR_FORMAT_PRINTF(MODULAR_IMPL_FN, FORMAT_IDX,               \
+                                    FIRST_TO_CHECK)                            \
+  __attribute__((format(printf, FORMAT_IDX, FIRST_TO_CHECK),                   \
+                 modular_format(MODULAR_IMPL_FN, "__printf", "float")))
 
 #endif // LLVM_LIBC_MACROS_LIBC_MODULAR_FORMAT_PRINTF_H
diff --git a/libc/include/stdio.yaml b/libc/include/stdio.yaml
index 78d07052198ee..4b12698e2484d 100644
--- a/libc/include/stdio.yaml
+++ b/libc/include/stdio.yaml
@@ -51,7 +51,7 @@ functions:
       - type: const char *__restrict
       - type: '...'
     attributes:
-      - _LIBC_MODULAR_FORMAT_PRINTF(__asprintf_modular)
+      - _LIBC_MODULAR_FORMAT_PRINTF(__asprintf_modular, 2, 3)
   - name: clearerr
     standards:
       - stdc
@@ -304,7 +304,7 @@ functions:
       - type: const char *__restrict
       - type: '...'
     attributes:
-      - _LIBC_MODULAR_FORMAT_PRINTF(__printf_modular)
+      - _LIBC_MODULAR_FORMAT_PRINTF(__printf_modular, 1, 2)
   - name: putc
     standards:
       - stdc
@@ -377,7 +377,7 @@ functions:
       - type: const char *__restrict
       - type: '...'
     attributes:
-      - _LIBC_MODULAR_FORMAT_PRINTF(__snprintf_modular)
+      - _LIBC_MODULAR_FORMAT_PRINTF(__snprintf_modular, 3, 4)
   - name: sprintf
     standards:
       - stdc
@@ -387,7 +387,7 @@ functions:
       - type: const char *__restrict
       - type: '...'
     attributes:
-      - _LIBC_MODULAR_FORMAT_PRINTF(__sprintf_modular)
+      - _LIBC_MODULAR_FORMAT_PRINTF(__sprintf_modular, 2, 3)
   - name: sscanf
     standards:
       - stdc
@@ -412,7 +412,7 @@ functions:
       - type: const char *__restrict
       - type: va_list
     attributes:
-      - _LIBC_MODULAR_FORMAT_PRINTF(__vasprintf_modular)
+      - _LIBC_MODULAR_FORMAT_PRINTF(__vasprintf_modular, 2, 0)
   - name: vfprintf
     standards:
       - stdc
@@ -429,7 +429,7 @@ functions:
       - type: const char *__restrict
       - type: va_list
     attributes:
-      - _LIBC_MODULAR_FORMAT_PRINTF(__vprintf_modular)
+      - _LIBC_MODULAR_FORMAT_PRINTF(__vprintf_modular, 1, 0)
   - name: vsnprintf
     standards:
       - stdc
@@ -440,7 +440,7 @@ functions:
       - type: const char *__restrict
       - type: va_list
     attributes:
-      - _LIBC_MODULAR_FORMAT_PRINTF(__vsnprintf_modular)
+      - _LIBC_MODULAR_FORMAT_PRINTF(__vsnprintf_modular, 3, 0)
   - name: vsprintf
     standards:
       - stdc
@@ -450,7 +450,7 @@ functions:
       - type: const char *__restrict
       - type: va_list
     attributes:
-      - _LIBC_MODULAR_FORMAT_PRINTF(__vsprintf_modular)
+      - _LIBC_MODULAR_FORMAT_PRINTF(__vsprintf_modular, 2, 0)
   - name: vsscanf
     standards:
       - stdc



More information about the libc-commits mailing list