Timm =?utf-8?q?Bäder?= <tbae...@redhat.com> Message-ID: In-Reply-To: <llvm.org/llvm/llvm-project/pull/117...@github.com>
https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/117763 >From 07b326b59bf9a8e385840a590c5162b9d1914650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Tue, 26 Nov 2024 19:26:32 +0100 Subject: [PATCH 1/2] [clang] Format bitfield width diagnostics with thousands-separators --- .../clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/lib/Sema/SemaDecl.cpp | 27 ++++++++++++++----- clang/test/SemaCXX/bitfield-layout.cpp | 4 +-- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6ff24c2bc8faad..5ab0885c8414fd 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6400,7 +6400,7 @@ def err_incorrect_number_of_vector_initializers : Error< // Used by C++ which allows bit-fields that are wider than the type. def warn_bitfield_width_exceeds_type_width: Warning< "width of bit-field %0 (%1 bits) exceeds the width of its type; value will " - "be truncated to %2 bit%s2">, InGroup<BitFieldWidth>; + "be truncated to %2 bits">, InGroup<BitFieldWidth>; def err_bitfield_too_wide : Error< "%select{bit-field %1|anonymous bit-field}0 is too wide (%2 bits)">; def warn_bitfield_too_small_for_enum : Warning< diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 74b0e5ad23bd48..7378edc1c5cecb 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18307,16 +18307,22 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, if (Value.isSigned() && Value.isNegative()) { if (FieldName) return Diag(FieldLoc, diag::err_bitfield_has_negative_width) - << FieldName << toString(Value, 10); + << FieldName + << toString(Value, 10, Value.isSigned(), + /*formatAsCLiteral=*/false, /*UpperCase=*/true, + /*InsertSeparators=*/true); return Diag(FieldLoc, diag::err_anon_bitfield_has_negative_width) - << toString(Value, 10); + << toString(Value, 10, Value.isSigned(), /*formatAsCLiteral=*/false, + /*UpperCase=*/true, /*InsertSeparators=*/true); } // The size of the bit-field must not exceed our maximum permitted object // size. if (Value.getActiveBits() > ConstantArrayType::getMaxSizeBits(Context)) { return Diag(FieldLoc, diag::err_bitfield_too_wide) - << !FieldName << FieldName << toString(Value, 10); + << !FieldName << FieldName + << toString(Value, 10, Value.isSigned(), /*formatAsCLiteral=*/false, + /*UpperCase=*/true, /*InsertSeparators=*/true); } if (!FieldTy->isDependentType()) { @@ -18335,7 +18341,10 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, unsigned DiagWidth = CStdConstraintViolation ? TypeWidth : TypeStorageSize; return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_width) - << (bool)FieldName << FieldName << toString(Value, 10) + << (bool)FieldName << FieldName + << toString(Value, 10, Value.isSigned(), + /*formatAsCLiteral=*/false, /*UpperCase=*/true, + /*InsertSeparators=*/true) << !CStdConstraintViolation << DiagWidth; } @@ -18343,9 +18352,15 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, // specified bits as value bits: that's all integral types other than // 'bool'. if (BitfieldIsOverwide && !FieldTy->isBooleanType() && FieldName) { + llvm::APInt TypeWidthAP(sizeof(TypeWidth) * 8, TypeWidth, + /*IsSigned=*/false); Diag(FieldLoc, diag::warn_bitfield_width_exceeds_type_width) - << FieldName << toString(Value, 10) - << (unsigned)TypeWidth; + << FieldName + << toString(Value, 10, Value.isSigned(), /*formatAsCLiteral=*/false, + /*UpperCase=*/true, /*InsertSeparators=*/true) + << toString(TypeWidthAP, 10, /*Signed=*/false, + /*formatAsCLiteral=*/false, /*UpperCase=*/true, + /*InsertSeparators=*/true); } } diff --git a/clang/test/SemaCXX/bitfield-layout.cpp b/clang/test/SemaCXX/bitfield-layout.cpp index 7efd1d38c682f5..951a4f72de1566 100644 --- a/clang/test/SemaCXX/bitfield-layout.cpp +++ b/clang/test/SemaCXX/bitfield-layout.cpp @@ -35,14 +35,14 @@ CHECK_SIZE(Test4, 8); CHECK_ALIGN(Test4, 8); struct Test5 { - char c : 0x100000001; // expected-warning {{width of bit-field 'c' (4294967297 bits) exceeds the width of its type; value will be truncated to 8 bits}} + char c : 0x100000001; // expected-warning {{width of bit-field 'c' (4'294'967'297 bits) exceeds the width of its type; value will be truncated to 8 bits}} }; // Size and align don't really matter here, just make sure we don't crash. CHECK_SIZE(Test5, 1); CHECK_ALIGN(Test5, 1); struct Test6 { - char c : (unsigned __int128)0xffffffffffffffff + 2; // expected-error {{bit-field 'c' is too wide (18446744073709551617 bits)}} + char c : (unsigned __int128)0xffffffffffffffff + 2; // expected-error {{bit-field 'c' is too wide (18'446'744'073'709'551'617 bits)}} }; // Size and align don't really matter here, just make sure we don't crash. CHECK_SIZE(Test6, 1); >From 95af9476cf74cb79f149450aca29c87badc02f1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Thu, 28 Nov 2024 11:00:29 +0100 Subject: [PATCH 2/2] Add %separated specifier --- clang/include/clang/Basic/Diagnostic.h | 19 +++++++++++- .../clang/Basic/DiagnosticSemaKinds.td | 8 ++--- clang/lib/Basic/Diagnostic.cpp | 29 +++++++++++++++++++ clang/lib/Sema/SemaDecl.cpp | 25 ++++------------ .../TableGen/ClangDiagnosticsEmitter.cpp | 7 ++++- 5 files changed, 62 insertions(+), 26 deletions(-) diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index d271accca3d3b7..d59974227b3686 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -18,6 +18,7 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" +#include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FunctionExtras.h" @@ -284,7 +285,10 @@ class DiagnosticsEngine : public RefCountedBase<DiagnosticsEngine> { ak_qualtype_pair, /// Attr * - ak_attr + ak_attr, + + /// APSInt * + ak_apsint, }; /// Represents on argument value, which is a union discriminated @@ -1366,6 +1370,12 @@ inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, return DB; } +inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, + const llvm::APSInt *I) { + DB.AddTaggedVal(reinterpret_cast<intptr_t>(I), DiagnosticsEngine::ak_apsint); + return DB; +} + // We use enable_if here to prevent that this overload is selected for // pointers or other arguments that are implicitly convertible to bool. template <typename T> @@ -1582,6 +1592,13 @@ class Diagnostic { DiagStorage.DiagArgumentsVal[Idx]); } + const llvm::APSInt *getArgAPSInt(unsigned Idx) const { + assert(getArgKind(Idx) == DiagnosticsEngine::ak_apsint && + "invalid argument accessor!"); + return reinterpret_cast<const llvm::APSInt *>( + DiagStorage.DiagArgumentsVal[Idx]); + } + /// Return the specified non-string argument in an opaque form. /// \pre getArgKind(Idx) != DiagnosticsEngine::ak_std_string uint64_t getRawArg(unsigned Idx) const { diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5ab0885c8414fd..f9db05140877d4 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6387,7 +6387,7 @@ def err_init_objc_class : Error< def err_implicit_empty_initializer : Error< "initializer for aggregate with no elements requires explicit braces">; def err_bitfield_has_negative_width : Error< - "bit-field %0 has negative width (%1)">; + "bit-field %0 has negative width (%separated1)">; def err_anon_bitfield_has_negative_width : Error< "anonymous bit-field has negative width (%0)">; def err_bitfield_has_zero_width : Error<"named bit-field %0 has zero width">; @@ -6399,10 +6399,10 @@ def err_incorrect_number_of_vector_initializers : Error< // Used by C++ which allows bit-fields that are wider than the type. def warn_bitfield_width_exceeds_type_width: Warning< - "width of bit-field %0 (%1 bits) exceeds the width of its type; value will " - "be truncated to %2 bits">, InGroup<BitFieldWidth>; + "width of bit-field %0 (%separated1 bits) exceeds the width of its type; value will " + "be truncated to %separated2 bit%s2">, InGroup<BitFieldWidth>; def err_bitfield_too_wide : Error< - "%select{bit-field %1|anonymous bit-field}0 is too wide (%2 bits)">; + "%select{bit-field %1|anonymous bit-field}0 is too wide (%separated2 bits)">; def warn_bitfield_too_small_for_enum : Warning< "bit-field %0 is not wide enough to store all enumerators of %1">, InGroup<BitFieldEnumConversion>, DefaultIgnore; diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index 2d0e358116362c..1e8eb976ffc482 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -769,6 +769,15 @@ static void HandleSelectModifier(const Diagnostic &DInfo, unsigned ValNo, DInfo.FormatDiagnostic(Argument, EndPtr, OutStr); } +static void HandleSeparatedModifier(const Diagnostic &DInfo, + const llvm::APSInt &Val, + const char *Argument, unsigned ArgumentLen, + SmallVectorImpl<char> &OutStr) { + llvm::raw_svector_ostream Out(OutStr); + Out << toString(Val, 10, Val.isSigned(), /*formatAsCLiteral=*/false, + /*UpperCase=*/false, /*InsertSeparators=*/true); +} + /// HandleIntegerSModifier - Handle the integer 's' modifier. This adds the /// letter 's' to the string if the value is not 1. This is used in cases like /// this: "you idiot, you have %4 parameter%s4!". @@ -1160,6 +1169,10 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, HandleOrdinalModifier((unsigned)Val, OutStr); } else if (ModifierIs(Modifier, ModifierLen, "human")) { HandleIntegerHumanModifier(Val, OutStr); + } else if (ModifierIs(Modifier, ModifierLen, "separated")) { + llvm::APSInt ValAP = llvm::APSInt( + llvm::APInt(64, Val, /*IsSigned=*/true), /*IsUnsigned=*/false); + HandleSeparatedModifier(*this, ValAP, Argument, ArgumentLen, OutStr); } else { assert(ModifierLen == 0 && "Unknown integer modifier"); llvm::raw_svector_ostream(OutStr) << Val; @@ -1180,12 +1193,28 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, HandleOrdinalModifier(Val, OutStr); } else if (ModifierIs(Modifier, ModifierLen, "human")) { HandleIntegerHumanModifier(Val, OutStr); + } else if (ModifierIs(Modifier, ModifierLen, "separated")) { + llvm::APSInt ValAP = llvm::APSInt( + llvm::APInt(64, Val, /*IsSigned=*/false), /*IsUnsigned=*/true); + HandleSeparatedModifier(*this, ValAP, Argument, ArgumentLen, OutStr); } else { assert(ModifierLen == 0 && "Unknown integer modifier"); llvm::raw_svector_ostream(OutStr) << Val; } break; } + + case DiagnosticsEngine::ak_apsint: { + const llvm::APSInt *Val = getArgAPSInt(ArgNo); + if (ModifierIs(Modifier, ModifierLen, "separated")) { + HandleSeparatedModifier(*this, *Val, Argument, ArgumentLen, OutStr); + } else { + assert(ModifierLen == 0 && "Unknown integer modifier"); + llvm::raw_svector_ostream(OutStr) << *Val; + } + // FIXME: Support the other modifiers for APSInt as well. + break; + } // ---- TOKEN SPELLINGS ---- case DiagnosticsEngine::ak_tokenkind: { tok::TokenKind Kind = static_cast<tok::TokenKind>(getRawArg(ArgNo)); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 7378edc1c5cecb..36f3af7a169633 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18307,22 +18307,15 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, if (Value.isSigned() && Value.isNegative()) { if (FieldName) return Diag(FieldLoc, diag::err_bitfield_has_negative_width) - << FieldName - << toString(Value, 10, Value.isSigned(), - /*formatAsCLiteral=*/false, /*UpperCase=*/true, - /*InsertSeparators=*/true); - return Diag(FieldLoc, diag::err_anon_bitfield_has_negative_width) - << toString(Value, 10, Value.isSigned(), /*formatAsCLiteral=*/false, - /*UpperCase=*/true, /*InsertSeparators=*/true); + << FieldName << &Value; + return Diag(FieldLoc, diag::err_anon_bitfield_has_negative_width) << &Value; } // The size of the bit-field must not exceed our maximum permitted object // size. if (Value.getActiveBits() > ConstantArrayType::getMaxSizeBits(Context)) { return Diag(FieldLoc, diag::err_bitfield_too_wide) - << !FieldName << FieldName - << toString(Value, 10, Value.isSigned(), /*formatAsCLiteral=*/false, - /*UpperCase=*/true, /*InsertSeparators=*/true); + << !FieldName << FieldName << &Value; } if (!FieldTy->isDependentType()) { @@ -18341,10 +18334,7 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, unsigned DiagWidth = CStdConstraintViolation ? TypeWidth : TypeStorageSize; return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_width) - << (bool)FieldName << FieldName - << toString(Value, 10, Value.isSigned(), - /*formatAsCLiteral=*/false, /*UpperCase=*/true, - /*InsertSeparators=*/true) + << (bool)FieldName << FieldName << &Value << !CStdConstraintViolation << DiagWidth; } @@ -18355,12 +18345,7 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, llvm::APInt TypeWidthAP(sizeof(TypeWidth) * 8, TypeWidth, /*IsSigned=*/false); Diag(FieldLoc, diag::warn_bitfield_width_exceeds_type_width) - << FieldName - << toString(Value, 10, Value.isSigned(), /*formatAsCLiteral=*/false, - /*UpperCase=*/true, /*InsertSeparators=*/true) - << toString(TypeWidthAP, 10, /*Signed=*/false, - /*formatAsCLiteral=*/false, /*UpperCase=*/true, - /*InsertSeparators=*/true); + << FieldName << &Value << (unsigned)TypeWidth; } } diff --git a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp index 6a4a64a0813063..48a3dd2fa0b7e3 100644 --- a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -413,6 +413,7 @@ enum ModifierType { MT_Diff, MT_Ordinal, MT_Human, + MT_Separated, MT_S, MT_Q, MT_ObjCClass, @@ -433,6 +434,8 @@ static StringRef getModifierName(ModifierType MT) { return "ordinal"; case MT_Human: return "human"; + case MT_Separated: + return "separated"; case MT_S: return "s"; case MT_Q: @@ -1030,6 +1033,7 @@ Piece *DiagnosticTextBuilder::DiagText::parseDiagText(StringRef &Text, .Case("s", MT_S) .Case("ordinal", MT_Ordinal) .Case("human", MT_Human) + .Case("separated", MT_Separated) .Case("q", MT_Q) .Case("objcclass", MT_ObjCClass) .Case("objcinstance", MT_ObjCInstance) @@ -1132,7 +1136,8 @@ Piece *DiagnosticTextBuilder::DiagText::parseDiagText(StringRef &Text, case MT_ObjCClass: case MT_ObjCInstance: case MT_Ordinal: - case MT_Human: { + case MT_Human: + case MT_Separated: { Parsed.push_back(New<PlaceholderPiece>(ModType, parseModifier(Text))); continue; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits