summaryrefslogtreecommitdiff
path: root/clang/lib/AST/FormatString.cpp
AgeCommit message (Collapse)Author
2025-08-26[clang] NFC: introduce Type::getAsEnumDecl, and cast variants for all ↵Matheus Izvekov
TagDecls (#155463) And make use of those. These changes are split from prior PR #155028, in order to decrease the size of that PR and facilitate review.
2025-08-25[clang] NFC: change more places to use Type::getAsTagDecl and friends (#155313)Matheus Izvekov
This changes a bunch of places which use getAs<TagType>, including derived types, just to obtain the tag definition. This is preparation for #155028, offloading all the changes that PR used to introduce which don't depend on any new helpers.
2025-08-09[clang] Improve nested name specifier AST representation (#147835)Matheus Izvekov
This is a major change on how we represent nested name qualifications in the AST. * The nested name specifier itself and how it's stored is changed. The prefixes for types are handled within the type hierarchy, which makes canonicalization for them super cheap, no memory allocation required. Also translating a type into nested name specifier form becomes a no-op. An identifier is stored as a DependentNameType. The nested name specifier gains a lightweight handle class, to be used instead of passing around pointers, which is similar to what is implemented for TemplateName. There is still one free bit available, and this handle can be used within a PointerUnion and PointerIntPair, which should keep bit-packing aficionados happy. * The ElaboratedType node is removed, all type nodes in which it could previously apply to can now store the elaborated keyword and name qualifier, tail allocating when present. * TagTypes can now point to the exact declaration found when producing these, as opposed to the previous situation of there only existing one TagType per entity. This increases the amount of type sugar retained, and can have several applications, for example in tracking module ownership, and other tools which care about source file origins, such as IWYU. These TagTypes are lazily allocated, in order to limit the increase in AST size. This patch offers a great performance benefit. It greatly improves compilation time for [stdexec](https://github.com/NVIDIA/stdexec). For one datapoint, for `test_on2.cpp` in that project, which is the slowest compiling test, this patch improves `-c` compilation time by about 7.2%, with the `-fsyntax-only` improvement being at ~12%. This has great results on compile-time-tracker as well: ![image](https://github.com/user-attachments/assets/700dce98-2cab-4aa8-97d1-b038c0bee831) This patch also further enables other optimziations in the future, and will reduce the performance impact of template specialization resugaring when that lands. It has some other miscelaneous drive-by fixes. About the review: Yes the patch is huge, sorry about that. Part of the reason is that I started by the nested name specifier part, before the ElaboratedType part, but that had a huge performance downside, as ElaboratedType is a big performance hog. I didn't have the steam to go back and change the patch after the fact. There is also a lot of internal API changes, and it made sense to remove ElaboratedType in one go, versus removing it from one type at a time, as that would present much more churn to the users. Also, the nested name specifier having a different API avoids missing changes related to how prefixes work now, which could make existing code compile but not work. How to review: The important changes are all in `clang/include/clang/AST` and `clang/lib/AST`, with also important changes in `clang/lib/Sema/TreeTransform.h`. The rest and bulk of the changes are mostly consequences of the changes in API. PS: TagType::getDecl is renamed to `getOriginalDecl` in this patch, just for easier to rebasing. I plan to rename it back after this lands. Fixes #136624 Fixes https://github.com/llvm/llvm-project/issues/43179 Fixes https://github.com/llvm/llvm-project/issues/68670 Fixes https://github.com/llvm/llvm-project/issues/92757
2025-07-19Reland [Clang] Make the SizeType, SignedSizeType and PtrdiffType be named ↵YexuanXiao
sugar types (#149613) The checks for the 'z' and 't' format specifiers added in the original PR #143653 had some issues and were overly strict, causing some build failures and were consequently reverted at https://github.com/llvm/llvm-project/commit/4c85bf2fe8042c855c9dd5be4b02191e9d071ffd. In the latest commit https://github.com/llvm/llvm-project/pull/149613/commits/27c58629ec76a703fde9c0b99b170573170b4a7a, I relaxed the checks for the 'z' and 't' format specifiers, so warnings are now only issued when they are used with mismatched types. The original intent of these checks was to diagnose code that assumes the underlying type of `size_t` is `unsigned` or `unsigned long`, for example: ```c printf("%zu", 1ul); // Not portable, but not an error when size_t is unsigned long ``` However, it produced a significant number of false positives. This was partly because Clang does not treat the `typedef` `size_t` and `__size_t` as having a common "sugar" type, and partly because a large amount of existing code either assumes `unsigned` (or `unsigned long`) is `size_t`, or they define the equivalent of size_t in their own way (such as sanitizer_internal_defs.h).https://github.com/llvm/llvm-project/blob/2e67dcfdcd023df2f06e0823eeea23990ce41534/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h#L203
2025-07-17Revert "[Clang] Make the SizeType, SignedSizeType and PtrdiffType be named ↵Kazu Hirata
sugar types instead of built-in types (#143653)" This reverts commit c27e283cfbca2bd22f34592430e98ee76ed60ad8. A builbot failure has been reported: https://lab.llvm.org/buildbot/#/builders/186/builds/10819/steps/10/logs/stdio I'm also getting a large number of warnings related to %zu and %zx.
2025-07-17[Clang] Make the SizeType, SignedSizeType and PtrdiffType be named sugar ↵YexuanXiao
types instead of built-in types (#143653) Including the results of `sizeof`, `sizeof...`, `__datasizeof`, `__alignof`, `_Alignof`, `alignof`, `_Countof`, `size_t` literals, and signed `size_t` literals, the results of pointer-pointer subtraction and checks for standard library functions (and their calls). The goal is to enable clang and downstream tools such as clangd and clang-tidy to provide more portable hints and diagnostics. The previous discussion can be found at #136542. This PR implements this feature by introducing a new subtype of `Type` called `PredefinedSugarType`, which was considered appropriate in discussions. I tried to keep `PredefinedSugarType` simple enough yet not limited to `size_t` and `ptrdiff_t` so that it can be used for other purposes. `PredefinedSugarType` wraps a canonical `Type` and provides a name, conceptually similar to a compiler internal `TypedefType` but without depending on a `TypedefDecl` or a source file. Additionally, checks for the `z` and `t` format specifiers in format strings for `scanf` and `printf` were added. It will precisely match expressions using `typedef`s or built-in expressions. The affected tests indicates that it works very well. Several code require that `SizeType` is canonical, so I kept `SizeType` to its canonical form. The failed tests in CI are allowed to fail. See the [comment](https://github.com/llvm/llvm-project/pull/135386#issuecomment-3049426611) in another PR #135386.
2025-02-24[clang] Implement __attribute__((format_matches)) (#116708)apple-fcloutier
This implements ``__attribute__((format_matches))``, as described in the RFC: https://discourse.llvm.org/t/rfc-format-attribute-attribute-format-like/83076 The ``format`` attribute only allows the compiler to check that a format string matches its arguments. If the format string is passed independently of its arguments, there is no way to have the compiler check it. ``format_matches(flavor, fmtidx, example)`` allows the compiler to check format strings against the ``example`` format string instead of against format arguments. See the changes to AttrDocs.td in this diff for more information. Implementation-wise, this change subclasses CheckPrintfHandler and CheckScanfHandler to allow them to collect specifiers into arrays, and implements comparing that two specifiers are equivalent. `checkFormatStringExpr` gets a new `ReferenceFormatString` argument that is piped down when calling a function with the `format_matches` attribute (and is `nullptr` otherwise); this is the string that the actual format string is compared against. Although this change does not enable -Wformat-nonliteral by default, IMO, all the pieces are now in place such that it could be.
2024-08-20[Clang] CWG722: nullptr to ellipses (#104704)Mital Ashok
https://cplusplus.github.io/CWG/issues/722.html nullptr passed to a variadic function now converted to void* in C++. This does not affect C23 nullptr. Also fixes -Wformat-pedantic so that it no longer warns for nullptr passed to %p (because it is converted to void* in C++ and it is allowed for va_arg(ap, void*) in C23)
2024-03-31[Sema] Implement support for -Wformat-signedness (#74440)Karl-Johan Karlsson
In gcc there exist a modifier option -Wformat-signedness that turns on additional signedness warnings in the already existing -Wformat warning. This patch implements that support in clang. This is done by adding a dummy warning diag::warn_format_conversion_argument_type_mismatch_signedness that is never emitted and only used as an option to toggle the signedness warning in -Wformat. This will ensure gcc compatibility.
2024-02-27[clang] Update -Wformat warnings for fixed-point format specifiers (#82855)PiJoules
ISO/IEC TR 18037 defines %r, %R, %k, and %K for fixed point format specifiers. -Wformat should not warn on these when they are provided.
2024-01-08[Sema] Warning for _Float16 passed to format specifier '%f' (#74439)Haocong Lu
According to https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2844.pdf, default argument promotions for _FloatN types has been removed. A warning is needed to notice user to promote _Float16 to double explicitly, and then pass it to format specifier '%f', which is consistent with GCC. Fixes: https://github.com/llvm/llvm-project/issues/68538
2023-09-01[clang] Emit `Wformat` for bool value and char specifier confusion in scanfPodchishchaeva, Mariya
Fixes https://github.com/llvm/llvm-project/issues/64987 Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D159279
2023-08-25[Sema] tolerate more promotion matches in format string checkingFélix Cloutier
It's been reported that when using __attribute__((format)) on non-variadic functions, certain values that normally get promoted when passed as variadic arguments now unconditionally emit a diagnostic: ```c void foo(const char *fmt, float f) __attribute__((format(printf, 1, 2))); void bar(void) { foo("%g", 123.f); // ^ format specifies type 'double' but the argument has type 'float' } ``` This is normally not an issue because float values get promoted to doubles when passed as variadic arguments, but needless to say, variadic argument promotion does not apply to non-variadic arguments. While this can be fixed by adjusting the prototype of `foo`, this is sometimes undesirable in C (for instance, if `foo` is ABI). In C++, using variadic templates, this might instead require call-site fixing, which is tedious and arguably needless work: ```c++ template<typename... Args> void foo(const char *fmt, Args &&...args) __attribute__((format(printf, 1, 2))); void bar(void) { foo("%g", 123.f); // ^ format specifies type 'double' but the argument has type 'float' } ``` To address this issue, we teach FormatString about a few promotions that have always been around but that have never been exercised in the direction that FormatString checks for: * `char`, `unsigned char` -> `int`, `unsigned` * `half`, `float16`, `float` -> `double` This addresses issue https://github.com/llvm/llvm-project/issues/59824.
2023-06-16Diagnose incorrect use of scoped enumerations in format stringsAaron Ballman
Scoped enumerations in C++ do not undergo conversion to their underlying type as part of default argument promotion, and so these uses are UB. GCC correctly diagnoses them, and now Clang matches. Fixes https://github.com/llvm/llvm-project/issues/38717
2023-04-20[Sema] -Wformat: recognize %lb for the printf/scanf family of functionsFangrui Song
Fix https://github.com/llvm/llvm-project/issues/62247 D131057 added `bArg` and `BArg` in the `AsLongLong` label in `FormatSpecifier::hasValidLengthModifier`, but missed the `AsLong` label, therefore `%llb` is allowed while `%lb` (e.g. `printf("%lb", (long)10)`) has a spurious warning. Add the missing case labels. Reviewed By: aaron.ballman, enh Differential Revision: https://reviews.llvm.org/D148779
2023-01-14[clang] Use std::optional instead of llvm::Optional (NFC)Kazu Hirata
This patch replaces (llvm::|)Optional< with std::optional<. I'll post a separate patch to remove #include "llvm/ADT/Optional.h". This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-14[clang] Add #include <optional> (NFC)Kazu Hirata
This patch adds #include <optional> to those files containing llvm::Optional<...> or Optional<...>. I'll post a separate patch to actually replace llvm::Optional with std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-03[AST] Use std::nullopt instead of None (NFC)Kazu Hirata
This patch mechanically replaces None with std::nullopt where the compiler would warn if None were deprecated. The intent is to reduce the amount of manual work required in migrating from Optional to std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-10-20[HLSL] Disable integer promotion to avoid int16_t being promoted to int for ↵Xiang Li
HLSL. short will be promoted to int in UsualUnaryConversions. Disable it for HLSL to keep int16_t as 16bit. Reviewed By: aaron.ballman, rjmccall Differential Revision: https://reviews.llvm.org/D133668
2022-09-01[clang][Sema] check default argument promotions for printfYingChi Long
The main focus of this patch is to make ArgType::matchesType check for possible default parameter promotions when the argType is not a pointer. If so, no warning will be given for `int`, `unsigned int` types as corresponding arguments to %hhd and %hd. However, the usage of %hhd corresponding to short is relatively rare, and it is more likely to be a misuse. This patch keeps the original behavior of clang like this as much as possible, while making it more convenient to consider the default arguments promotion. Fixes https://github.com/llvm/llvm-project/issues/57102 Reviewed By: aaron.ballman, nickdesaulniers, #clang-language-wg Differential Revision: https://reviews.llvm.org/D132568
2022-08-08[clang] LLVM_FALLTHROUGH => [[fallthrough]]. NFCFangrui Song
With C++17 there is no Clang pedantic warning or MSVC C5051. Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D131346
2022-08-04[Sema] -Wformat: support C23 format specifier %b %BFangrui Song
Close #56885: WG14 N2630 added %b to fprintf/fscanf and recommended %B for fprintf. This patch teaches -Wformat %b for the printf/scanf family of functions and %B for the printf family of functions. glibc 2.35 and latest Android bionic added %b/%B printf support. From https://www.openwall.com/lists/libc-coord/2022/07/ no scanf support is available yet. Like GCC, we don't test library support. GCC 12 -Wformat -pedantic emits a warning: > warning: ISO C17 does not support the ‘%b’ gnu_printf format [-Wformat=] The behavior is not ported. Note: `freebsd_kernel_printf` uses %b differently. Reviewed By: aaron.ballman, dim, enh Differential Revision: https://reviews.llvm.org/D131057
2022-07-27[clang] Implement ElaboratedType sugaring for types written bareMatheus Izvekov
Without this patch, clang will not wrap in an ElaboratedType node types written without a keyword and nested name qualifier, which goes against the intent that we should produce an AST which retains enough details to recover how things are written. The lack of this sugar is incompatible with the intent of the type printer default policy, which is to print types as written, but to fall back and print them fully qualified when they are desugared. An ElaboratedTypeLoc without keyword / NNS uses no storage by itself, but still requires pointer alignment due to pre-existing bug in the TypeLoc buffer handling. --- Troubleshooting list to deal with any breakage seen with this patch: 1) The most likely effect one would see by this patch is a change in how a type is printed. The type printer will, by design and default, print types as written. There are customization options there, but not that many, and they mainly apply to how to print a type that we somehow failed to track how it was written. This patch fixes a problem where we failed to distinguish between a type that was written without any elaborated-type qualifiers, such as a 'struct'/'class' tags and name spacifiers such as 'std::', and one that has been stripped of any 'metadata' that identifies such, the so called canonical types. Example: ``` namespace foo { struct A {}; A a; }; ``` If one were to print the type of `foo::a`, prior to this patch, this would result in `foo::A`. This is how the type printer would have, by default, printed the canonical type of A as well. As soon as you add any name qualifiers to A, the type printer would suddenly start accurately printing the type as written. This patch will make it print it accurately even when written without qualifiers, so we will just print `A` for the initial example, as the user did not really write that `foo::` namespace qualifier. 2) This patch could expose a bug in some AST matcher. Matching types is harder to get right when there is sugar involved. For example, if you want to match a type against being a pointer to some type A, then you have to account for getting a type that is sugar for a pointer to A, or being a pointer to sugar to A, or both! Usually you would get the second part wrong, and this would work for a very simple test where you don't use any name qualifiers, but you would discover is broken when you do. The usual fix is to either use the matcher which strips sugar, which is annoying to use as for example if you match an N level pointer, you have to put N+1 such matchers in there, beginning to end and between all those levels. But in a lot of cases, if the property you want to match is present in the canonical type, it's easier and faster to just match on that... This goes with what is said in 1), if you want to match against the name of a type, and you want the name string to be something stable, perhaps matching on the name of the canonical type is the better choice. 3) This patch could expose a bug in how you get the source range of some TypeLoc. For some reason, a lot of code is using getLocalSourceRange(), which only looks at the given TypeLoc node. This patch introduces a new, and more common TypeLoc node which contains no source locations on itself. This is not an inovation here, and some other, more rare TypeLoc nodes could also have this property, but if you use getLocalSourceRange on them, it's not going to return any valid locations, because it doesn't have any. The right fix here is to always use getSourceRange() or getBeginLoc/getEndLoc which will dive into the inner TypeLoc to get the source range if it doesn't find it on the top level one. You can use getLocalSourceRange if you are really into micro-optimizations and you have some outside knowledge that the TypeLocs you are dealing with will always include some source location. 4) Exposed a bug somewhere in the use of the normal clang type class API, where you have some type, you want to see if that type is some particular kind, you try a `dyn_cast` such as `dyn_cast<TypedefType>` and that fails because now you have an ElaboratedType which has a TypeDefType inside of it, which is what you wanted to match. Again, like 2), this would usually have been tested poorly with some simple tests with no qualifications, and would have been broken had there been any other kind of type sugar, be it an ElaboratedType or a TemplateSpecializationType or a SubstTemplateParmType. The usual fix here is to use `getAs` instead of `dyn_cast`, which will look deeper into the type. Or use `getAsAdjusted` when dealing with TypeLocs. For some reason the API is inconsistent there and on TypeLocs getAs behaves like a dyn_cast. 5) It could be a bug in this patch perhaps. Let me know if you need any help! Signed-off-by: Matheus Izvekov <mizvekov@gmail.com> Differential Revision: https://reviews.llvm.org/D112374
2022-07-14Revert "[clang] Implement ElaboratedType sugaring for types written bare"Jonas Devlieghere
This reverts commit 7c51f02effdbd0d5e12bfd26f9c3b2ab5687c93f because it stills breaks the LLDB tests. This was re-landed without addressing the issue or even agreement on how to address the issue. More details and discussion in https://reviews.llvm.org/D112374.
2022-07-15[clang] Implement ElaboratedType sugaring for types written bareMatheus Izvekov
Without this patch, clang will not wrap in an ElaboratedType node types written without a keyword and nested name qualifier, which goes against the intent that we should produce an AST which retains enough details to recover how things are written. The lack of this sugar is incompatible with the intent of the type printer default policy, which is to print types as written, but to fall back and print them fully qualified when they are desugared. An ElaboratedTypeLoc without keyword / NNS uses no storage by itself, but still requires pointer alignment due to pre-existing bug in the TypeLoc buffer handling. --- Troubleshooting list to deal with any breakage seen with this patch: 1) The most likely effect one would see by this patch is a change in how a type is printed. The type printer will, by design and default, print types as written. There are customization options there, but not that many, and they mainly apply to how to print a type that we somehow failed to track how it was written. This patch fixes a problem where we failed to distinguish between a type that was written without any elaborated-type qualifiers, such as a 'struct'/'class' tags and name spacifiers such as 'std::', and one that has been stripped of any 'metadata' that identifies such, the so called canonical types. Example: ``` namespace foo { struct A {}; A a; }; ``` If one were to print the type of `foo::a`, prior to this patch, this would result in `foo::A`. This is how the type printer would have, by default, printed the canonical type of A as well. As soon as you add any name qualifiers to A, the type printer would suddenly start accurately printing the type as written. This patch will make it print it accurately even when written without qualifiers, so we will just print `A` for the initial example, as the user did not really write that `foo::` namespace qualifier. 2) This patch could expose a bug in some AST matcher. Matching types is harder to get right when there is sugar involved. For example, if you want to match a type against being a pointer to some type A, then you have to account for getting a type that is sugar for a pointer to A, or being a pointer to sugar to A, or both! Usually you would get the second part wrong, and this would work for a very simple test where you don't use any name qualifiers, but you would discover is broken when you do. The usual fix is to either use the matcher which strips sugar, which is annoying to use as for example if you match an N level pointer, you have to put N+1 such matchers in there, beginning to end and between all those levels. But in a lot of cases, if the property you want to match is present in the canonical type, it's easier and faster to just match on that... This goes with what is said in 1), if you want to match against the name of a type, and you want the name string to be something stable, perhaps matching on the name of the canonical type is the better choice. 3) This patch could exposed a bug in how you get the source range of some TypeLoc. For some reason, a lot of code is using getLocalSourceRange(), which only looks at the given TypeLoc node. This patch introduces a new, and more common TypeLoc node which contains no source locations on itself. This is not an inovation here, and some other, more rare TypeLoc nodes could also have this property, but if you use getLocalSourceRange on them, it's not going to return any valid locations, because it doesn't have any. The right fix here is to always use getSourceRange() or getBeginLoc/getEndLoc which will dive into the inner TypeLoc to get the source range if it doesn't find it on the top level one. You can use getLocalSourceRange if you are really into micro-optimizations and you have some outside knowledge that the TypeLocs you are dealing with will always include some source location. 4) Exposed a bug somewhere in the use of the normal clang type class API, where you have some type, you want to see if that type is some particular kind, you try a `dyn_cast` such as `dyn_cast<TypedefType>` and that fails because now you have an ElaboratedType which has a TypeDefType inside of it, which is what you wanted to match. Again, like 2), this would usually have been tested poorly with some simple tests with no qualifications, and would have been broken had there been any other kind of type sugar, be it an ElaboratedType or a TemplateSpecializationType or a SubstTemplateParmType. The usual fix here is to use `getAs` instead of `dyn_cast`, which will look deeper into the type. Or use `getAsAdjusted` when dealing with TypeLocs. For some reason the API is inconsistent there and on TypeLocs getAs behaves like a dyn_cast. 5) It could be a bug in this patch perhaps. Let me know if you need any help! Signed-off-by: Matheus Izvekov <mizvekov@gmail.com> Differential Revision: https://reviews.llvm.org/D112374
2022-07-13Revert "[clang] Implement ElaboratedType sugaring for types written bare"Jonas Devlieghere
This reverts commit bdc6974f92304f4ed542241b9b89ba58ba6b20aa because it breaks all the LLDB tests that import the std module. import-std-module/array.TestArrayFromStdModule.py import-std-module/deque-basic.TestDequeFromStdModule.py import-std-module/deque-dbg-info-content.TestDbgInfoContentDequeFromStdModule.py import-std-module/forward_list.TestForwardListFromStdModule.py import-std-module/forward_list-dbg-info-content.TestDbgInfoContentForwardListFromStdModule.py import-std-module/list.TestListFromStdModule.py import-std-module/list-dbg-info-content.TestDbgInfoContentListFromStdModule.py import-std-module/queue.TestQueueFromStdModule.py import-std-module/stack.TestStackFromStdModule.py import-std-module/vector.TestVectorFromStdModule.py import-std-module/vector-bool.TestVectorBoolFromStdModule.py import-std-module/vector-dbg-info-content.TestDbgInfoContentVectorFromStdModule.py import-std-module/vector-of-vectors.TestVectorOfVectorsFromStdModule.py https://green.lab.llvm.org/green/view/LLDB/job/lldb-cmake/45301/
2022-07-13[clang] Implement ElaboratedType sugaring for types written bareMatheus Izvekov
Without this patch, clang will not wrap in an ElaboratedType node types written without a keyword and nested name qualifier, which goes against the intent that we should produce an AST which retains enough details to recover how things are written. The lack of this sugar is incompatible with the intent of the type printer default policy, which is to print types as written, but to fall back and print them fully qualified when they are desugared. An ElaboratedTypeLoc without keyword / NNS uses no storage by itself, but still requires pointer alignment due to pre-existing bug in the TypeLoc buffer handling. Signed-off-by: Matheus Izvekov <mizvekov@gmail.com> Differential Revision: https://reviews.llvm.org/D112374
2022-07-05Allow non-variadic functions to be attributed with `__attribute__((format))`Félix Cloutier
Clang only allows you to use __attribute__((format)) on variadic functions. There are legit use cases for __attribute__((format)) on non-variadic functions, such as: (1) variadic templates ```c++ template<typename… Args> void print(const char *fmt, Args… &&args) __attribute__((format(1, 2))); // error: format attribute requires variadic function ``` (2) functions which take fixed arguments and a custom format: ```c++ void print_number_string(const char *fmt, unsigned number, const char *string) __attribute__((format(1, 2))); // ^error: format attribute requires variadic function void foo(void) { print_number_string(“%08x %s\n”, 0xdeadbeef, “hello”); print_number_string(“%d %s”, 0xcafebabe, “bar”); } ``` This change allows Clang users to attach __attribute__((format)) to non-variadic functions, including functions with C++ variadic templates. It replaces the error with a GCC compatibility warning and improves the type checker to ensure that received arrays are treated like pointers (this is a possibility in C++ since references to template types can bind to arrays). Reviewed By: aaron.ballman Differential Revision: https://reviews.llvm.org/D112579 rdar://84629099
2022-06-02[PS5] Support r and y specifiers of freebsd_kernel_printf format stringsPaul Robinson
2021-12-29[clang] Remove unused "using" (NFC)Kazu Hirata
2020-07-10[Sema] Emit a -Wformat warning for printf("%s", (void*)p)Erik Pilkington
Its dangerous to assume that the opaque pointer points to a null-terminated string, and this has an easy fix (casting to char*). rdar://62432331
2020-04-28[AST] Use PrintingPolicy for format string diagnosisJessica Clarke
Summary: This is a small improvement for OpenCL diagnostics, but is also useful for our CHERI fork, as our __capability qualifier is suppressed from diagnostics when all pointers are capabilities, only being used when pointers need to be explicitly opted-in to being capabilities. Reviewers: rsmith, Anastasia, aaron.ballman Reviewed By: Anastasia, aaron.ballman Subscribers: aaron.ballman, arichardson, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D78777
2020-01-28Revert "[Clang] Warn about 'z' printf modifier in old MSVC."Nico Weber
This reverts commit fe0d1b6a8ac5048b8007e5e7cc2aeb4e3291bda0. Makes Analysis/taint-generic.c fail on some Windows systems.
2020-01-28[Clang] Warn about 'z' printf modifier in old MSVC.Simon Tatham
Summary: The 'z' length modifier, signalling that an integer format specifier takes a `size_t` sized integer, is only supported by the C library of MSVC 2015 and later. Earlier versions don't recognize the 'z' at all, and respond to `printf("%zu", x)` by just printing "zu". So, if the MS compatibility version is set to a value earlier than MSVC2015, it's useful to warn about 'z' modifiers in printf format strings we check. Reviewers: aaron.ballman, lebedev.ri, rnk, majnemer, zturner Reviewed By: aaron.ballman Subscribers: amccarth, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D73457
2019-10-04[Sema] Split out -Wformat-type-confusion from -Wformat-pedanticErik Pilkington
The warnings now in -Wformat-type-confusion don't align with how we interpret 'pedantic' in clang, and don't belong in -pedantic. Differential revision: https://reviews.llvm.org/D67775 llvm-svn: 373774
2019-09-18[Sema] Suppress -Wformat diagnostics for bool types when printed using %hhdErik Pilkington
Also, add a diagnostic under -Wformat for printing a boolean value as a character. rdar://54579473 Differential revision: https://reviews.llvm.org/D66856 llvm-svn: 372247
2019-08-23[Sema] Don't warn on printf('%hd', [char]) (PR41467)Nathan Huckleberry
Summary: Link: https://bugs.llvm.org/show_bug.cgi?id=41467 Reviewers: rsmith, nickdesaulniers, aaron.ballman, lebedev.ri Reviewed By: nickdesaulniers, aaron.ballman, lebedev.ri Subscribers: lebedev.ri, nickdesaulniers, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D66186 llvm-svn: 369791
2019-01-29OpenCL: Use length modifier for warning on vector printf argumentsMatt Arsenault
Re-enable format string warnings on printf. The warnings are still incomplete. Apparently it is undefined to use a vector specifier without a length modifier, which is not currently warned on. Additionally, type warnings appear to not be working with the hh modifier, and aren't warning on all of the special restrictions from c99 printf. llvm-svn: 352540
2019-01-19Update the file headers across all of the LLVM projects in the monorepoChandler Carruth
to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. llvm-svn: 351636
2018-12-01OpenCL: Improve vector printf warningsMatt Arsenault
The vector modifier is considered separate, so don't treat it as a conversion specifier. This is still not warning on some cases, like using a type that isn't a valid vector element. Fixes bug 39652 llvm-svn: 348084
2018-11-13OpenCL: Don't warn on v printf modifierMatt Arsenault
This avoids spurious warnings, but could use a lot of work. For example the number of vector elements is not verified, and the passed value type is not checked. Fixes bug 39486 llvm-svn: 346806
2018-11-02Reapply Logging: make os_log buffer size an integer constant expression.Tim Northover
The size of an os_log buffer is known at any stage of compilation, so making it a constant expression means that the common idiom of declaring a buffer for it won't result in a VLA. That allows the compiler to skip saving and restoring the stack pointer around such buffers. This also moves the OSLog and other FormatString helpers from libclangAnalysis to libclangAST to avoid a circular dependency. llvm-svn: 345971