[Clang] support C23 printf width length modifiers#199991
Merged
Merged
Conversation
|
@llvm/pr-subscribers-clang Author: Oleksandr Tarasiuk (a-tarasyuk) ChangesThis patch adds Patch is 21.01 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/199991.diff 10 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cef93e25f1e7d..1acfb155b974c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -227,6 +227,7 @@ C2y Feature Support
C23 Feature Support
^^^^^^^^^^^^^^^^^^^
- Clang now allows C23 ``constexpr`` struct member access through the dot operator in constant expressions. (#GH178349)
+- Clang now supports the C23 ``wN`` and ``wfN`` length modifiers. (#GH116962)
Objective-C Language Changes
-----------------------------
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 9ef27cc1eb58e..fa7f531248526 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -949,6 +949,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getIntTypeForBitwidth(unsigned DestWidth,
unsigned Signed) const;
+ QualType getLeastIntTypeForBitwidth(unsigned DestWidth,
+ unsigned Signed) const;
+
/// getRealTypeForBitwidth -
/// sets floating point QualTy according to specified bitwidth.
/// Returns empty type if there is no appropriate target types.
diff --git a/clang/include/clang/AST/FormatString.h b/clang/include/clang/AST/FormatString.h
index a3382e1a1d007..239d88ea33c7c 100644
--- a/clang/include/clang/AST/FormatString.h
+++ b/clang/include/clang/AST/FormatString.h
@@ -19,6 +19,7 @@
#define LLVM_CLANG_AST_FORMATSTRING_H
#include "clang/AST/CanonicalType.h"
+#include "llvm/ADT/StringRef.h"
#include <optional>
namespace clang {
@@ -80,6 +81,8 @@ class LengthModifier {
AsInt3264, // 'I' (MSVCRT, like __int3264 from MIDL)
AsInt64, // 'I64' (MSVCRT, like __int64)
AsLongDouble, // 'L'
+ AsIntN, // 'wN'
+ AsFastIntN, // 'wfN'
AsAllocate, // for '%as', GNU extension to C90 scanf
AsMAllocate, // for '%ms', GNU extension to scanf
AsWide, // 'w' (MSVCRT, like l but only for c, C, s, S, or Z
@@ -88,6 +91,8 @@ class LengthModifier {
LengthModifier() : Position(nullptr), kind(None) {}
LengthModifier(const char *pos, Kind k) : Position(pos), kind(k) {}
+ LengthModifier(const char *pos, Kind k, unsigned bitWidth, unsigned length)
+ : Position(pos), kind(k), BitWidth(bitWidth), ModifierLength(length) {}
const char *getStart() const { return Position; }
@@ -98,6 +103,9 @@ class LengthModifier {
case AsLongLong:
case AsChar:
return 2;
+ case AsIntN:
+ case AsFastIntN:
+ return ModifierLength;
case AsInt32:
case AsInt64:
return 3;
@@ -109,11 +117,15 @@ class LengthModifier {
Kind getKind() const { return kind; }
void setKind(Kind k) { kind = k; }
- const char *toString() const;
+ unsigned getBitWidth() const { return BitWidth; }
+
+ StringRef toString() const;
private:
const char *Position;
Kind kind;
+ unsigned BitWidth = 0;
+ unsigned ModifierLength = 0;
};
class ConversionSpecifier {
@@ -301,10 +313,18 @@ class ArgType {
const char *Name = nullptr;
bool Ptr = false;
- /// The TypeKind identifies certain well-known types like size_t and
- /// ptrdiff_t.
- enum class TypeKind { DontCare, SizeT, PtrdiffT };
+ /// The TypeKind identifies certain well-known types.
+ enum class TypeKind {
+ DontCare,
+ SizeT,
+ PtrdiffT,
+ IntN,
+ UIntN,
+ FastIntN,
+ FastUIntN,
+ };
TypeKind TK = TypeKind::DontCare;
+ unsigned BitWidth = 0;
public:
ArgType(Kind K = UnknownTy, const char *N = nullptr) : K(K), Name(N) {}
@@ -341,6 +361,9 @@ class ArgType {
return Res;
}
+ static ArgType makeIntNT(ASTContext &Ctx, const LengthModifier &LengthMod,
+ bool Signed);
+
MatchKind matchesType(ASTContext &C, QualType argTy) const;
MatchKind matchesArgType(ASTContext &C, const ArgType &other) const;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index a401a7471e6fc..ec483df8aa61b 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -13541,6 +13541,12 @@ QualType ASTContext::getIntTypeForBitwidth(unsigned DestWidth,
return QualTy;
}
+QualType ASTContext::getLeastIntTypeForBitwidth(unsigned DestWidth,
+ unsigned Signed) const {
+ return getFromTargetType(
+ getTargetInfo().getLeastIntTypeByWidth(DestWidth, Signed));
+}
+
/// getRealTypeForBitwidth -
/// sets floating point QualTy according to specified bitwidth.
/// Returns empty type if there is no appropriate target types.
diff --git a/clang/lib/AST/FormatString.cpp b/clang/lib/AST/FormatString.cpp
index 7e1ac0de6dcaf..81a77a89268aa 100644
--- a/clang/lib/AST/FormatString.cpp
+++ b/clang/lib/AST/FormatString.cpp
@@ -14,7 +14,9 @@
#include "FormatStringParsing.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetInfo.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ConvertUTF.h"
+#include <limits>
#include <optional>
using clang::analyze_format_string::ArgType;
@@ -59,6 +61,21 @@ OptionalAmount clang::analyze_format_string::ParseAmount(const char *&Beg,
return OptionalAmount();
}
+static bool ParseWidthModifier(const char *&I, const char *E,
+ unsigned &BitWidth, unsigned &ModifierLength) {
+ StringRef W = StringRef(I, E - I).take_while(llvm::isDigit);
+ if (W.empty() || W.front() == '0')
+ return false;
+
+ if (W.getAsInteger(10, BitWidth))
+ BitWidth = std::numeric_limits<unsigned>::max();
+
+ for (const char *End = W.end(); I != End; ++I)
+ ++ModifierLength;
+
+ return true;
+}
+
OptionalAmount clang::analyze_format_string::ParseNonPositionAmount(
const char *&Beg, const char *E, unsigned &argIndex) {
if (*Beg == '*') {
@@ -287,6 +304,25 @@ bool clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
lmKind = LengthModifier::AsInt3264;
break;
case 'w':
+ if (LO.C23) {
+ const char *WidthModifier = I + 1;
+ unsigned BitWidth = 0;
+ unsigned ModifierLength = 1;
+
+ LengthModifier::Kind WidthKind = LengthModifier::AsIntN;
+ if (WidthModifier != E && *WidthModifier == 'f') {
+ WidthModifier = I + 2;
+ ModifierLength = 2;
+ WidthKind = LengthModifier::AsFastIntN;
+ }
+
+ if (ParseWidthModifier(WidthModifier, E, BitWidth, ModifierLength)) {
+ I = WidthModifier;
+ FS.setLengthModifier(
+ LengthModifier(lmPosition, WidthKind, BitWidth, ModifierLength));
+ return true;
+ }
+ }
lmKind = LengthModifier::AsWide;
++I;
break;
@@ -774,6 +810,22 @@ ArgType ArgType::makeVectorType(ASTContext &C, unsigned NumElts) const {
return ArgType(Vec, Name);
}
+ArgType ArgType::makeIntNT(ASTContext &Ctx, const LengthModifier &LengthMod,
+ bool Signed) {
+ bool IsFast = LengthMod.getKind() == LengthModifier::AsFastIntN;
+ QualType Ty =
+ IsFast ? Ctx.getLeastIntTypeForBitwidth(LengthMod.getBitWidth(), Signed)
+ : Ctx.getIntTypeForBitwidth(LengthMod.getBitWidth(), Signed);
+ if (Ty.isNull())
+ return ArgType::Invalid();
+
+ ArgType Res(Ty);
+ Res.TK = IsFast ? (Signed ? TypeKind::FastIntN : TypeKind::FastUIntN)
+ : (Signed ? TypeKind::IntN : TypeKind::UIntN);
+ Res.BitWidth = LengthMod.getBitWidth();
+ return Res;
+}
+
QualType ArgType::getRepresentativeType(ASTContext &C) const {
QualType Res;
switch (K) {
@@ -820,6 +872,33 @@ std::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
if (Name) {
// Use a specific name for this type, e.g. "size_t".
Alias = Name;
+ } else {
+ const char *Prefix = nullptr;
+ switch (TK) {
+ case TypeKind::IntN:
+ Prefix = "int";
+ break;
+ case TypeKind::UIntN:
+ Prefix = "uint";
+ break;
+ case TypeKind::FastIntN:
+ Prefix = "int_fast";
+ break;
+ case TypeKind::FastUIntN:
+ Prefix = "uint_fast";
+ break;
+ case TypeKind::DontCare:
+ case TypeKind::SizeT:
+ case TypeKind::PtrdiffT:
+ break;
+ }
+ if (Prefix) {
+ Alias = Prefix;
+ Alias += std::to_string(BitWidth);
+ Alias += "_t";
+ }
+ }
+ if (!Alias.empty()) {
if (Ptr) {
// If ArgType is actually a pointer to T, append an asterisk.
Alias += (Alias[Alias.size() - 1] == '*') ? "*" : " *";
@@ -847,7 +926,7 @@ analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const {
// Methods on LengthModifier.
//===----------------------------------------------------------------------===//
-const char *analyze_format_string::LengthModifier::toString() const {
+StringRef analyze_format_string::LengthModifier::toString() const {
switch (kind) {
case AsChar:
return "hh";
@@ -875,6 +954,9 @@ const char *analyze_format_string::LengthModifier::toString() const {
return "I64";
case AsLongDouble:
return "L";
+ case AsIntN:
+ case AsFastIntN:
+ return StringRef(Position, getLength());
case AsAllocate:
return "a";
case AsMAllocate:
@@ -884,7 +966,7 @@ const char *analyze_format_string::LengthModifier::toString() const {
case None:
return "";
}
- return nullptr;
+ llvm_unreachable("Invalid LengthModifier Kind!");
}
//===----------------------------------------------------------------------===//
@@ -1156,6 +1238,35 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target,
return false;
}
+ case LengthModifier::AsIntN:
+ case LengthModifier::AsFastIntN: {
+ if (!LO.C23)
+ return false;
+
+ TargetInfo::IntType TargetType =
+ LM.getKind() == LengthModifier::AsIntN
+ ? Target.getIntTypeByWidth(LM.getBitWidth(), /*IsSigned=*/true)
+ : Target.getLeastIntTypeByWidth(LM.getBitWidth(),
+ /*IsSigned=*/true);
+ if (TargetType == TargetInfo::NoInt)
+ return false;
+
+ switch (CS.getKind()) {
+ case ConversionSpecifier::bArg:
+ case ConversionSpecifier::BArg:
+ case ConversionSpecifier::dArg:
+ case ConversionSpecifier::iArg:
+ case ConversionSpecifier::oArg:
+ case ConversionSpecifier::uArg:
+ case ConversionSpecifier::xArg:
+ case ConversionSpecifier::XArg:
+ case ConversionSpecifier::nArg:
+ return true;
+ default:
+ return false;
+ }
+ }
+
case LengthModifier::AsAllocate:
switch (CS.getKind()) {
case ConversionSpecifier::sArg:
@@ -1217,6 +1328,8 @@ bool FormatSpecifier::hasStandardLengthModifier() const {
case LengthModifier::AsSizeT:
case LengthModifier::AsPtrDiff:
case LengthModifier::AsLongDouble:
+ case LengthModifier::AsIntN:
+ case LengthModifier::AsFastIntN:
return true;
case LengthModifier::AsAllocate:
case LengthModifier::AsMAllocate:
diff --git a/clang/lib/AST/PrintfFormatString.cpp b/clang/lib/AST/PrintfFormatString.cpp
index 6610a2de9e083..64310193e1057 100644
--- a/clang/lib/AST/PrintfFormatString.cpp
+++ b/clang/lib/AST/PrintfFormatString.cpp
@@ -601,6 +601,11 @@ ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx,
case LengthModifier::AsPtrDiff:
return ArgType::makePtrdiffT(
ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
+ case LengthModifier::AsIntN:
+ case LengthModifier::AsFastIntN:
+ return ArgType::makeIntNT(Ctx, LM,
+ CS.getKind() != ConversionSpecifier::bArg &&
+ CS.getKind() != ConversionSpecifier::BArg);
case LengthModifier::AsAllocate:
case LengthModifier::AsMAllocate:
case LengthModifier::AsWide:
@@ -639,6 +644,9 @@ ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx,
case LengthModifier::AsPtrDiff:
return ArgType::makePtrdiffT(
ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t"));
+ case LengthModifier::AsIntN:
+ case LengthModifier::AsFastIntN:
+ return ArgType::makeIntNT(Ctx, LM, /*Signed=*/false);
case LengthModifier::AsAllocate:
case LengthModifier::AsMAllocate:
case LengthModifier::AsWide:
@@ -684,6 +692,9 @@ ArgType PrintfSpecifier::getScalarArgType(ASTContext &Ctx,
case LengthModifier::AsPtrDiff:
return ArgType::PtrTo(ArgType::makePtrdiffT(
ArgType(Ctx.getPointerDiffType(), "ptrdiff_t")));
+ case LengthModifier::AsIntN:
+ case LengthModifier::AsFastIntN:
+ return ArgType::PtrTo(ArgType::makeIntNT(Ctx, LM, /*Signed=*/true));
case LengthModifier::AsLongDouble:
return ArgType(); // FIXME: Is this a known extension?
case LengthModifier::AsAllocate:
diff --git a/clang/lib/AST/ScanfFormatString.cpp b/clang/lib/AST/ScanfFormatString.cpp
index 90cbbd60bbcf5..9b832376983d2 100644
--- a/clang/lib/AST/ScanfFormatString.cpp
+++ b/clang/lib/AST/ScanfFormatString.cpp
@@ -300,6 +300,9 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const {
case LengthModifier::AsPtrDiff:
return ArgType::PtrTo(ArgType::makePtrdiffT(
ArgType(Ctx.getPointerDiffType(), "ptrdiff_t")));
+ case LengthModifier::AsIntN:
+ case LengthModifier::AsFastIntN:
+ return ArgType::PtrTo(ArgType::makeIntNT(Ctx, LM, /*Signed=*/true));
case LengthModifier::AsLongDouble:
// GNU extension.
return ArgType::PtrTo(Ctx.LongLongTy);
@@ -344,6 +347,9 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const {
case LengthModifier::AsPtrDiff:
return ArgType::PtrTo(ArgType::makePtrdiffT(
ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t")));
+ case LengthModifier::AsIntN:
+ case LengthModifier::AsFastIntN:
+ return ArgType::PtrTo(ArgType::makeIntNT(Ctx, LM, /*Signed=*/false));
case LengthModifier::AsLongDouble:
// GNU extension.
return ArgType::PtrTo(Ctx.UnsignedLongLongTy);
@@ -443,6 +449,9 @@ ArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const {
case LengthModifier::AsPtrDiff:
return ArgType::PtrTo(ArgType::makePtrdiffT(
ArgType(Ctx.getPointerDiffType(), "ptrdiff_t")));
+ case LengthModifier::AsIntN:
+ case LengthModifier::AsFastIntN:
+ return ArgType::PtrTo(ArgType::makeIntNT(Ctx, LM, /*Signed=*/true));
case LengthModifier::AsLongDouble:
return ArgType(); // FIXME: Is this a known extension?
case LengthModifier::AsAllocate:
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2309196ee1696..671ac62bfcce0 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -8322,7 +8322,7 @@ class EquatableFormatArgument {
private:
analyze_format_string::ArgType ArgType;
- analyze_format_string::LengthModifier::Kind LengthMod;
+ analyze_format_string::LengthModifier LengthMod;
StringRef SpecifierLetter;
CharSourceRange Range;
SourceLocation ElementLoc;
@@ -8336,7 +8336,7 @@ class EquatableFormatArgument {
public:
EquatableFormatArgument(CharSourceRange Range, SourceLocation ElementLoc,
- analyze_format_string::LengthModifier::Kind LengthMod,
+ analyze_format_string::LengthModifier LengthMod,
StringRef SpecifierLetter,
analyze_format_string::ArgType ArgType,
FormatArgumentRole Role,
@@ -8351,7 +8351,7 @@ class EquatableFormatArgument {
SourceLocation getSourceLocation() const { return ElementLoc; }
CharSourceRange getSourceRange() const { return Range; }
analyze_format_string::LengthModifier getLengthModifier() const {
- return analyze_format_string::LengthModifier(nullptr, LengthMod);
+ return LengthMod;
}
void setModifierFor(unsigned V) { ModifierFor = V; }
@@ -8699,7 +8699,7 @@ bool DecomposePrintfHandler::HandlePrintfSpecifier(
Specs.emplace_back(
getSpecifierRange(startSpecifier, specifierLen),
getLocationOfByte(FieldWidth.getStart()),
- analyze_format_string::LengthModifier::None, FieldWidth.getCharacters(),
+ analyze_format_string::LengthModifier(), FieldWidth.getCharacters(),
FieldWidth.getArgType(S.Context),
EquatableFormatArgument::FAR_FieldWidth,
EquatableFormatArgument::SS_None,
@@ -8714,7 +8714,7 @@ bool DecomposePrintfHandler::HandlePrintfSpecifier(
Specs.emplace_back(
getSpecifierRange(startSpecifier, specifierLen),
getLocationOfByte(Precision.getStart()),
- analyze_format_string::LengthModifier::None, Precision.getCharacters(),
+ analyze_format_string::LengthModifier(), Precision.getCharacters(),
Precision.getArgType(S.Context), EquatableFormatArgument::FAR_Precision,
EquatableFormatArgument::SS_None,
Precision.usesPositionalArg() ? Precision.getPositionalArgIndex() - 1
@@ -8742,7 +8742,7 @@ bool DecomposePrintfHandler::HandlePrintfSpecifier(
Specs.emplace_back(
getSpecifierRange(startSpecifier, specifierLen),
- getLocationOfByte(CS.getStart()), FS.getLengthModifier().getKind(),
+ getLocationOfByte(CS.getStart()), FS.getLengthModifier(),
CS.getCharacters(), FS.getArgType(S.Context, isObjCContext()),
EquatableFormatArgument::FAR_Data, Sensitivity, SpecIndex, 0);
@@ -8751,7 +8751,7 @@ bool DecomposePrintfHandler::HandlePrintfSpecifier(
CS.getKind() == analyze_format_string::ConversionSpecifier::FreeBSDDArg) {
Specs.emplace_back(getSpecifierRange(startSpecifier, specifierLen),
getLocationOfByte(CS.getStart()),
- analyze_format_string::LengthModifier::None,
+ analyze_format_string::LengthModifier(),
CS.getCharacters(),
analyze_format_string::ArgType::CStrTy,
EquatableFormatArgument::FAR_Auxiliary, Sensitivity,
diff --git a/clang/test/Sema/format-strings-c23.c b/clang/test/Sema/format-strings-c23.c
new file mode 100644
index 0000000000000..7156dc21981de
--- /dev/null
+++ b/clang/test/Sema/format-strings-c23.c
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -std=c23 -fsyntax-only -verify %s
+
+typedef __INT32_TYPE__ int32_t;
+typedef __UINT32_TYPE__ uint32_t;
+typedef __INT_FAST32_TYPE__ int_fast32_t;
+typedef __UINT_FAST32_TYPE__ uint_fast32_t;
+
+int printf(const char *restrict, ...);
+int scanf(const char *restrict, ...);
+
+void t1(int32_t i32, uint32_t u32, int_fast32_t if32, uint_fast32_t uf32, int32_t *i_ptr, int_fast32_t *if_ptr, double *d_ptr) {
+ printf("%w32d", i32);
+ printf("%w32i", i32);
+ printf("%w32u", u32);
+ printf("%w32x", u32);
+ printf("%w32b", u32);
+ printf("%wf32d", if32);
+ printf("%wf32u", uf32);
+ printf("%wf32B", uf32);
+
+ printf("%w32d", 1.0); // expected-warning{{format specifies type 'int32_t' (aka 'int') but the argument has type 'double'}}
+ printf("%w32u", 1.0); // expected-warning{{format specifies type 'uint32_t' (aka 'unsigned int') but the argument has type 'double'}}
+ printf("%wf32d", 1.0); // expected-warning{{format specifies type 'int_fast32_t' (aka 'int') but the argument has type 'double'}}
+ printf("%wf32u", 1.0); // expected-warning{{format specifies type 'uint_fast32_t' (aka 'unsigned int') but the argument has type 'double'}}
+
+ printf("%w32n", i_ptr);
+ printf("%wf32n", if_ptr);
+ printf("%w32n", d_ptr); // expected-warning{{format specifies type 'int32_t *' (aka 'int *') but the argument has type 'double *'}}
+}
+
+void t2(int32_t *i_ptr, uint32_t *u_ptr, int_fast32_t *if_ptr, uint_fast32_t *uf_ptr, double *d_ptr) {
+ scanf("%w32d", i_ptr);
+ scanf("%w32i", i_ptr);
+ scanf("%w32u", u_ptr);
+ scanf("%w32x", u_ptr);
+ scanf("%w32b", u_ptr);
+ scanf("%wf32d", if_ptr);
+ scanf("%wf32u", uf_ptr);
+
+ scanf("%w32d", d_ptr); // expected-warning{{format specifies type 'int32_t *' (aka 'int *') but the argument has type 'double *'}}
+ scanf("%w32u", d_ptr); // expected-warning{{format specifies type 'uint32_t *' (aka 'unsigned int *') but the argument has type 'double *'}}
+ scanf("%wf32d", d_ptr); // expected-warning{{format specifies type 'int_fast32_t *' (aka 'int *') but the argument has type 'double *'}}
+ scanf("%wf32u", d_ptr); // expected-warning{{format specifies type 'uint_fast32_t *' (aka 'unsigned int *') but the argument has type 'double *'}}
+}
+
+void t3(con...
[truncated]
|
AaronBallman
reviewed
Jun 4, 2026
AaronBallman
reviewed
Jun 5, 2026
AaronBallman
approved these changes
Jun 5, 2026
AaronBallman
left a comment
Contributor
There was a problem hiding this comment.
LGTM presuming precommit CI comes back green. Thank you!
carlobertolli
pushed a commit
to carlobertolli/llvm-project
that referenced
this pull request
Jun 11, 2026
This patch adds `-Wformat` support for the C23 `wN` and `wfN` length modifiers in `printf`/`scanf` format strings. llvm#116962
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This patch adds
-Wformatsupport for the C23wNandwfNlength modifiers inprintf/scanfformat strings. #116962