Skip to content

Commit 7c402b8

Browse files
authored
Reland [Clang] Make the SizeType, SignedSizeType and PtrdiffType be named 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 4c85bf2. In the latest commit 27c5862, 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
1 parent 9bf7d04 commit 7c402b8

File tree

83 files changed

+1036
-732
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+1036
-732
lines changed

clang-tools-extra/clangd/unittests/FindTargetTests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,7 @@ TEST_F(TargetDeclTest, OverloadExpr) {
838838
)cpp";
839839
// Sized deallocation is enabled by default in C++14 onwards.
840840
EXPECT_DECLS("CXXDeleteExpr",
841-
"void operator delete(void *, unsigned long) noexcept");
841+
"void operator delete(void *, __size_t) noexcept");
842842
}
843843

844844
TEST_F(TargetDeclTest, DependentExprs) {

clang-tools-extra/clangd/unittests/HoverTests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2794,7 +2794,7 @@ TEST(Hover, All) {
27942794
})cpp",
27952795
[](HoverInfo &HI) {
27962796
HI.Name = "expression";
2797-
HI.Type = "unsigned long";
2797+
HI.Type = {"__size_t", "unsigned long"};
27982798
HI.Value = "1";
27992799
}},
28002800
{
@@ -2804,7 +2804,7 @@ TEST(Hover, All) {
28042804
})cpp",
28052805
[](HoverInfo &HI) {
28062806
HI.Name = "expression";
2807-
HI.Type = "unsigned long";
2807+
HI.Type = {"__size_t", "unsigned long"};
28082808
HI.Value = "1";
28092809
}},
28102810
{

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Potentially Breaking Changes
4646
``endbr64`` instruction at the labels named as possible branch
4747
destinations, so it is not safe to use a register-controlled branch
4848
instruction to branch to one. (In line with gcc.)
49+
- Added a sugar type `PredefinedSugarType` to improve diagnostic messages. (#GH143653)
4950

5051
C/C++ Language Potentially Breaking Changes
5152
-------------------------------------------

clang/include/clang/AST/ASTContext.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
277277
mutable llvm::ContextualFoldingSet<ArrayParameterType, ASTContext &>
278278
ArrayParameterTypes;
279279

280+
/// Store the unique Type corresponding to each Kind.
281+
mutable std::array<Type *,
282+
llvm::to_underlying(PredefinedSugarType::Kind::Last) + 1>
283+
PredefinedSugarTypes{};
284+
280285
/// The set of nested name specifiers.
281286
///
282287
/// This set is managed by the NestedNameSpecifier class.
@@ -1569,6 +1574,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
15691574
/// and bit count.
15701575
QualType getDependentBitIntType(bool Unsigned, Expr *BitsExpr) const;
15711576

1577+
QualType getPredefinedSugarType(PredefinedSugarType::Kind KD) const;
1578+
15721579
/// Gets the struct used to keep track of the extended descriptor for
15731580
/// pointer to blocks.
15741581
QualType getBlockDescriptorExtendedType() const;
@@ -2001,11 +2008,13 @@ class ASTContext : public RefCountedBase<ASTContext> {
20012008
/// <stddef.h>.
20022009
///
20032010
/// The sizeof operator requires this (C99 6.5.3.4p4).
2004-
CanQualType getSizeType() const;
2011+
QualType getSizeType() const;
2012+
2013+
CanQualType getCanonicalSizeType() const;
20052014

20062015
/// Return the unique signed counterpart of
20072016
/// the integer type corresponding to size_t.
2008-
CanQualType getSignedSizeType() const;
2017+
QualType getSignedSizeType() const;
20092018

20102019
/// Return the unique type for "intmax_t" (C99 7.18.1.5), defined in
20112020
/// <stdint.h>.

clang/include/clang/AST/FormatString.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,8 @@ class FormatSpecifier {
489489

490490
/// For a TypedefType QT, if it is a named integer type such as size_t,
491491
/// assign the appropriate value to LM and return true.
492-
static bool namedTypeToLengthModifier(QualType QT, LengthModifier &LM);
492+
static bool namedTypeToLengthModifier(ASTContext &Ctx, QualType QT,
493+
LengthModifier &LM);
493494
};
494495

495496
} // end analyze_format_string namespace

clang/include/clang/AST/RecursiveASTVisitor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,8 @@ DEF_TRAVERSE_TYPE(BitIntType, {})
12081208
DEF_TRAVERSE_TYPE(DependentBitIntType,
12091209
{ TRY_TO(TraverseStmt(T->getNumBitsExpr())); })
12101210

1211+
DEF_TRAVERSE_TYPE(PredefinedSugarType, {})
1212+
12111213
#undef DEF_TRAVERSE_TYPE
12121214

12131215
// ----------------- TypeLoc traversal -----------------
@@ -1524,6 +1526,8 @@ DEF_TRAVERSE_TYPELOC(DependentBitIntType, {
15241526
TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr()));
15251527
})
15261528

1529+
DEF_TRAVERSE_TYPELOC(PredefinedSugarType, {})
1530+
15271531
#undef DEF_TRAVERSE_TYPELOC
15281532

15291533
// ----------------- Decl traversal -----------------

clang/include/clang/AST/Type.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2258,6 +2258,30 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
22582258
unsigned NumExpansions;
22592259
};
22602260

2261+
enum class PredefinedSugarKind {
2262+
/// The "size_t" type.
2263+
SizeT,
2264+
2265+
/// The signed integer type corresponding to "size_t".
2266+
SignedSizeT,
2267+
2268+
/// The "ptrdiff_t" type.
2269+
PtrdiffT,
2270+
2271+
// Indicates how many items the enum has.
2272+
Last = PtrdiffT
2273+
};
2274+
2275+
class PresefinedSugarTypeBitfields {
2276+
friend class PredefinedSugarType;
2277+
2278+
LLVM_PREFERRED_TYPE(TypeBitfields)
2279+
unsigned : NumTypeBits;
2280+
2281+
LLVM_PREFERRED_TYPE(PredefinedSugarKind)
2282+
unsigned Kind : 8;
2283+
};
2284+
22612285
class CountAttributedTypeBitfields {
22622286
friend class CountAttributedType;
22632287

@@ -2297,6 +2321,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
22972321
DependentTemplateSpecializationTypeBits;
22982322
PackExpansionTypeBitfields PackExpansionTypeBits;
22992323
CountAttributedTypeBitfields CountAttributedTypeBits;
2324+
PresefinedSugarTypeBitfields PredefinedSugarTypeBits;
23002325
};
23012326

23022327
private:
@@ -8038,6 +8063,37 @@ class DependentBitIntType final : public Type, public llvm::FoldingSetNode {
80388063
}
80398064
};
80408065

8066+
class PredefinedSugarType final : public Type {
8067+
public:
8068+
friend class ASTContext;
8069+
using Kind = PredefinedSugarKind;
8070+
8071+
private:
8072+
PredefinedSugarType(Kind KD, const IdentifierInfo *IdentName,
8073+
QualType CanonicalType)
8074+
: Type(PredefinedSugar, CanonicalType, TypeDependence::None),
8075+
Name(IdentName) {
8076+
PredefinedSugarTypeBits.Kind = llvm::to_underlying(KD);
8077+
}
8078+
8079+
static StringRef getName(Kind KD);
8080+
8081+
const IdentifierInfo *Name;
8082+
8083+
public:
8084+
bool isSugared() const { return true; }
8085+
8086+
QualType desugar() const { return getCanonicalTypeInternal(); }
8087+
8088+
Kind getKind() const { return Kind(PredefinedSugarTypeBits.Kind); }
8089+
8090+
const IdentifierInfo *getIdentifier() const { return Name; }
8091+
8092+
static bool classof(const Type *T) {
8093+
return T->getTypeClass() == PredefinedSugar;
8094+
}
8095+
};
8096+
80418097
/// A qualifier set is used to build a set of qualifiers.
80428098
class QualifierCollector : public Qualifiers {
80438099
public:

clang/include/clang/AST/TypeLoc.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2783,6 +2783,16 @@ class ObjCProtocolLoc {
27832783
}
27842784
};
27852785

2786+
struct PredefinedSugarTypeLocInfo {}; // Nothing.
2787+
2788+
class PredefinedSugarTypeLoc final
2789+
: public ConcreteTypeLoc<UnqualTypeLoc, PredefinedSugarTypeLoc,
2790+
PredefinedSugarType, PredefinedSugarTypeLocInfo> {
2791+
public:
2792+
void initializeLocal(ASTContext &Context, SourceLocation loc) {}
2793+
SourceRange getLocalSourceRange() const { return {}; }
2794+
};
2795+
27862796
} // namespace clang
27872797

27882798
#endif // LLVM_CLANG_AST_TYPELOC_H

clang/include/clang/AST/TypeProperties.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,3 +1028,12 @@ let Class = DependentBitIntType in {
10281028
return ctx.getDependentBitIntType(isUnsigned, numBitsExpr);
10291029
}]>;
10301030
}
1031+
1032+
let Class = PredefinedSugarType in {
1033+
def : Property<"kind", UInt32> {
1034+
let Read = [{ static_cast<uint32_t>(node->getKind()) }];
1035+
}
1036+
def : Creator<[{
1037+
return ctx.getPredefinedSugarType(static_cast<PredefinedSugarType::Kind>(kind));
1038+
}]>;
1039+
}

clang/include/clang/Basic/TypeNodes.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,4 @@ def PipeType : TypeNode<Type>;
117117
def AtomicType : TypeNode<Type>;
118118
def BitIntType : TypeNode<Type>;
119119
def DependentBitIntType : TypeNode<Type>, AlwaysDependent;
120+
def PredefinedSugarType : TypeNode<Type>, NeverCanonical;

0 commit comments

Comments
 (0)