[clang] [libc] [libc] Fix modular printf attributes (PR #194003)

2026-05-07 Thread Daniel Thornburgh via cfe-commits

mysterymath wrote:

> Hi, digging into this a bit more, it looks like handling of builtins is 
> different in C and C++ mode: in C mode attributes are initialized earlier and 
> are available for the validation, while in C++ this is skipped, so that the 
> format attribute is only added after the validation.
> 
> I removed the hardcoded attributes from this patch and added my local fix as 
> a demonstration - it extends the validation logic to expect that builtins and 
> the special asprintf-like functions will get the attribute eventually.
> 
> Other ways to fix would be to move validation or addition of implicit 
> attributes around, which is a bigger structural change.
> 
> Please let me know what you think, thanks!

Ah, thanks for looking into this; sorry that I've been a bit busy. I do think 
this patch will broadly work now, but I want to compare against one of the more 
intrinsic ways of solving it; duplicating the printf-like detection logic is 
not the greatest. But, we can fall back to this if need be and clean it up 
later I think.

https://github.com/llvm/llvm-project/pull/194003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libc] [libc] Fix modular printf attributes (PR #194003)

2026-05-07 Thread Volodymyr Turanskyy via cfe-commits

voltur01 wrote:

Hi, digging into this a bit more, it looks like handling of builtins is 
different in C and C++ mode: in C mode attributes are initialized earlier and 
are available for the validation, while in C++ this is skipped, so that the 
format attribute is only added after the validation.

I removed the hardcoded attributes from this patch and added my local fix as a 
demonstration - it extends the validation logic to expect that builtins and the 
special asprintf-like functions will get the attribute eventually.

Other ways to fix would be to move validation or addition of implicit 
attributes around, which is a bigger structural change.

Please let me know what you think, thanks!

https://github.com/llvm/llvm-project/pull/194003
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libc] [libc] Fix modular printf attributes (PR #194003)

2026-05-07 Thread Volodymyr Turanskyy via cfe-commits

https://github.com/voltur01 updated 
https://github.com/llvm/llvm-project/pull/194003

>From e36c9d6b9c1f0df50a577442a1c7460327efd1e3 Mon Sep 17 00:00:00 2001
From: Volodymyr Turanskyy 
Date: Fri, 24 Apr 2026 17:04:26 +0100
Subject: [PATCH 1/3] Fix modular printf attributes

This fixes declarations of modular printf attributes by adding the format
attribute required by clang and documented here
https://github.com/llvm/llvm-project/blob/deb84db5b4056eed1457a6b03148a486bbadd8ea/libc/docs/dev/modular_format.rst?plain=1#L26
---
 libc/include/llvm-libc-macros/CMakeLists.txt |  2 +-
 .../_LIBC_MODULAR_FORMAT_PRINTF-disable.h|  3 ++-
 .../_LIBC_MODULAR_FORMAT_PRINTF.h|  4 +++-
 libc/include/stdio.yaml  | 16 
 4 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt 
b/libc/include/llvm-libc-macros/CMakeLists.txt
index 1f34257c57e01..a923b979e71c9 100644
--- a/libc/include/llvm-libc-macros/CMakeLists.txt
+++ b/libc/include/llvm-libc-macros/CMakeLists.txt
@@ -400,7 +400,7 @@ add_macro_header(
 sysexits-macros.h
 )
 
-if (LIBC_CONF_MODULAR_FORMAT)
+if (LIBC_CONF_PRINTF_MODULAR)
   add_macro_header(
 _LIBC_MODULAR_FORMAT_PRINTF
 HDR
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..ecec03c2142ce 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,7 @@
 #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_INDEX, 
\
+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..e7349afe94371 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)   
\
+#define _LIBC_MODULAR_FORMAT_PRINTF(MODULAR_IMPL_FN, FORMAT_INDEX, 
\
+FIRST_TO_CHECK)
\
+  __attribute__((format(printf, FORMAT_INDEX, FIRST_TO_CHECK)))
\
   __attribute__((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 24890b4b25670..ce7738e8e0648 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
@@ -4