[clang] [Clang] Make the result type of sizeof/pointer subtraction/size_t lit… (PR #136542)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 22 04:59:39 PDT 2025
https://github.com/YexuanXiao updated https://github.com/llvm/llvm-project/pull/136542
>From b9cc91971469dcf19bb926f6f53ae5a57d1109c3 Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Mon, 21 Apr 2025 14:28:33 +0800
Subject: [PATCH 01/11] [Clang] Make the result type of sizeof/pointer
subtraction/size_t literals be typedefs instead of built-in types Includeing
the results of `sizeof`, `sizeof...`, `__datasizeof`, `__alignof`,
`_Alignof`, `alignof`, `_Countof`, `size_t` literals, and signed `size_t`
literals, as well as the results of pointer-pointer subtraction. It does not
affect any program output except for debugging information. The goal is to
enable clang and downstream tools such as clangd and clang-tidy to provide
more portable hints and diagnostics.
---
clang/include/clang/AST/ASTContext.h | 4 +++
clang/lib/AST/ASTContext.cpp | 29 ++++++++++++++++++++++
clang/lib/AST/ComparisonCategories.cpp | 30 ++++-------------------
clang/lib/AST/ExprCXX.cpp | 6 +++--
clang/lib/Sema/SemaExpr.cpp | 34 ++++++++++++++++++++------
5 files changed, 68 insertions(+), 35 deletions(-)
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 3c78833a3f069..0c133d45d3f5e 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -2442,6 +2442,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error,
unsigned *IntegerConstantArgs = nullptr) const;
+ QualType getCGlobalCXXStdNSTypedef(const NamespaceDecl *StdNS,
+ StringRef DefName,
+ QualType FallBack = {}) const;
+
/// Types and expressions required to build C++2a three-way comparisons
/// using operator<=>, including the values return by builtin <=> operators.
ComparisonCategories CompCategories;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 2836d68b05ff6..aa8ce0078d4d3 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -12556,6 +12556,35 @@ QualType ASTContext::GetBuiltinType(unsigned Id,
return getFunctionType(ResType, ArgTypes, EPI);
}
+QualType ASTContext::getCGlobalCXXStdNSTypedef(const NamespaceDecl *StdNS,
+ StringRef DefName,
+ QualType FallBack) const {
+ DeclContextLookupResult Lookup;
+ if (getLangOpts().C99) {
+ Lookup = getTranslationUnitDecl()->lookup(&Idents.get(DefName));
+ } else if (getLangOpts().CPlusPlus) {
+ if (StdNS == nullptr) {
+ auto LookupStdNS = getTranslationUnitDecl()->lookup(&Idents.get("std"));
+ if (!LookupStdNS.empty()) {
+ StdNS = dyn_cast<NamespaceDecl>(LookupStdNS.front());
+ }
+ }
+ if (StdNS) {
+ Lookup = StdNS->lookup(&Idents.get(DefName));
+ } else {
+ Lookup = getTranslationUnitDecl()->lookup(&Idents.get(DefName));
+ }
+ }
+ if (!Lookup.empty()) {
+ if (auto *TD = dyn_cast<TypedefNameDecl>(Lookup.front())) {
+ if (auto Result = getTypeDeclType(TD); !Result.isNull()) {
+ return Result;
+ }
+ }
+ }
+ return FallBack;
+}
+
static GVALinkage basicGVALinkageForFunction(const ASTContext &Context,
const FunctionDecl *FD) {
if (!FD->isExternallyVisible())
diff --git a/clang/lib/AST/ComparisonCategories.cpp b/clang/lib/AST/ComparisonCategories.cpp
index 28244104d6636..46dcd6ac4261d 100644
--- a/clang/lib/AST/ComparisonCategories.cpp
+++ b/clang/lib/AST/ComparisonCategories.cpp
@@ -87,37 +87,17 @@ ComparisonCategoryInfo::ValueInfo *ComparisonCategoryInfo::lookupValueInfo(
return &Objects.back();
}
-static const NamespaceDecl *lookupStdNamespace(const ASTContext &Ctx,
- NamespaceDecl *&StdNS) {
- if (!StdNS) {
- DeclContextLookupResult Lookup =
- Ctx.getTranslationUnitDecl()->lookup(&Ctx.Idents.get("std"));
- if (!Lookup.empty())
- StdNS = dyn_cast<NamespaceDecl>(Lookup.front());
- }
- return StdNS;
-}
-
-static const CXXRecordDecl *lookupCXXRecordDecl(const ASTContext &Ctx,
- const NamespaceDecl *StdNS,
- ComparisonCategoryType Kind) {
- StringRef Name = ComparisonCategories::getCategoryString(Kind);
- DeclContextLookupResult Lookup = StdNS->lookup(&Ctx.Idents.get(Name));
- if (!Lookup.empty())
- if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Lookup.front()))
- return RD;
- return nullptr;
-}
-
const ComparisonCategoryInfo *
ComparisonCategories::lookupInfo(ComparisonCategoryType Kind) const {
auto It = Data.find(static_cast<char>(Kind));
if (It != Data.end())
return &It->second;
-
- if (const NamespaceDecl *NS = lookupStdNamespace(Ctx, StdNS))
- if (const CXXRecordDecl *RD = lookupCXXRecordDecl(Ctx, NS, Kind))
+ if (auto QT = Ctx.getCGlobalCXXStdNSTypedef(
+ nullptr, ComparisonCategories::getCategoryString(Kind));
+ !QT.isNull()) {
+ if (const auto *RD = QT->getAsCXXRecordDecl())
return &Data.try_emplace((char)Kind, Ctx, RD, Kind).first->second;
+ }
return nullptr;
}
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 169f11b611066..306ddcb9f491a 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1700,8 +1700,10 @@ SizeOfPackExpr *SizeOfPackExpr::Create(ASTContext &Context,
ArrayRef<TemplateArgument> PartialArgs) {
void *Storage =
Context.Allocate(totalSizeToAlloc<TemplateArgument>(PartialArgs.size()));
- return new (Storage) SizeOfPackExpr(Context.getSizeType(), OperatorLoc, Pack,
- PackLoc, RParenLoc, Length, PartialArgs);
+ return new (Storage) SizeOfPackExpr(
+ Context.getCGlobalCXXStdNSTypedef(nullptr, "size_t",
+ Context.getSizeType()),
+ OperatorLoc, Pack, PackLoc, RParenLoc, Length, PartialArgs);
}
SizeOfPackExpr *SizeOfPackExpr::CreateDeserialized(ASTContext &Context,
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 01a021443c94f..d07be9f117957 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4026,10 +4026,20 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
// Does it fit in size_t?
if (ResultVal.isIntN(SizeTSize)) {
// Does it fit in ssize_t?
- if (!Literal.isUnsigned && ResultVal[SizeTSize - 1] == 0)
- Ty = Context.getSignedSizeType();
- else if (AllowUnsigned)
- Ty = Context.getSizeType();
+ if (!Literal.isUnsigned && ResultVal[SizeTSize - 1] == 0) {
+ auto SignedSize = Context.getSignedSizeType();
+ if (auto PtrDiff = Context.getCGlobalCXXStdNSTypedef(
+ getStdNamespace(), "ptrdiff_t");
+ Context.hasSameType(PtrDiff, SignedSize))
+ Ty = PtrDiff;
+ else if (auto SSize = Context.getCGlobalCXXStdNSTypedef(
+ getStdNamespace(), "ssize_t");
+ Context.hasSameType(SSize, SignedSize))
+ Ty = SSize;
+ } else if (AllowUnsigned) {
+ Ty = Context.getCGlobalCXXStdNSTypedef(getStdNamespace(), "size_t",
+ Context.getSizeType());
+ }
Width = SizeTSize;
}
}
@@ -4702,7 +4712,10 @@ ExprResult Sema::CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
// C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
return new (Context) UnaryExprOrTypeTraitExpr(
- ExprKind, TInfo, Context.getSizeType(), OpLoc, R.getEnd());
+ ExprKind, TInfo,
+ Context.getCGlobalCXXStdNSTypedef(getStdNamespace(), "size_t",
+ Context.getSizeType()),
+ OpLoc, R.getEnd());
}
ExprResult
@@ -4745,7 +4758,10 @@ Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc,
// C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
return new (Context) UnaryExprOrTypeTraitExpr(
- ExprKind, E, Context.getSizeType(), OpLoc, E->getSourceRange().getEnd());
+ ExprKind, E,
+ Context.getCGlobalCXXStdNSTypedef(getStdNamespace(), "size_t",
+ Context.getSizeType()),
+ OpLoc, E->getSourceRange().getEnd());
}
ExprResult
@@ -11353,8 +11369,10 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
}
}
- if (CompLHSTy) *CompLHSTy = LHS.get()->getType();
- return Context.getPointerDiffType();
+ if (CompLHSTy)
+ *CompLHSTy = LHS.get()->getType();
+ return Context.getCGlobalCXXStdNSTypedef(getStdNamespace(), "ptrdiff_t",
+ Context.getPointerDiffType());
}
}
>From af5749ad5b94d30ee5252959a61ebf8602179826 Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Mon, 21 Apr 2025 15:25:58 +0800
Subject: [PATCH 02/11] Revert ComparisonCategories.cpp because RecordDecl is
not TypedefNameDecl
---
clang/lib/AST/ComparisonCategories.cpp | 30 +++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/clang/lib/AST/ComparisonCategories.cpp b/clang/lib/AST/ComparisonCategories.cpp
index 46dcd6ac4261d..28244104d6636 100644
--- a/clang/lib/AST/ComparisonCategories.cpp
+++ b/clang/lib/AST/ComparisonCategories.cpp
@@ -87,17 +87,37 @@ ComparisonCategoryInfo::ValueInfo *ComparisonCategoryInfo::lookupValueInfo(
return &Objects.back();
}
+static const NamespaceDecl *lookupStdNamespace(const ASTContext &Ctx,
+ NamespaceDecl *&StdNS) {
+ if (!StdNS) {
+ DeclContextLookupResult Lookup =
+ Ctx.getTranslationUnitDecl()->lookup(&Ctx.Idents.get("std"));
+ if (!Lookup.empty())
+ StdNS = dyn_cast<NamespaceDecl>(Lookup.front());
+ }
+ return StdNS;
+}
+
+static const CXXRecordDecl *lookupCXXRecordDecl(const ASTContext &Ctx,
+ const NamespaceDecl *StdNS,
+ ComparisonCategoryType Kind) {
+ StringRef Name = ComparisonCategories::getCategoryString(Kind);
+ DeclContextLookupResult Lookup = StdNS->lookup(&Ctx.Idents.get(Name));
+ if (!Lookup.empty())
+ if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Lookup.front()))
+ return RD;
+ return nullptr;
+}
+
const ComparisonCategoryInfo *
ComparisonCategories::lookupInfo(ComparisonCategoryType Kind) const {
auto It = Data.find(static_cast<char>(Kind));
if (It != Data.end())
return &It->second;
- if (auto QT = Ctx.getCGlobalCXXStdNSTypedef(
- nullptr, ComparisonCategories::getCategoryString(Kind));
- !QT.isNull()) {
- if (const auto *RD = QT->getAsCXXRecordDecl())
+
+ if (const NamespaceDecl *NS = lookupStdNamespace(Ctx, StdNS))
+ if (const CXXRecordDecl *RD = lookupCXXRecordDecl(Ctx, NS, Kind))
return &Data.try_emplace((char)Kind, Ctx, RD, Kind).first->second;
- }
return nullptr;
}
>From 25418415bf97e292e3089a4232e01882a5ef5225 Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Mon, 21 Apr 2025 16:01:01 +0800
Subject: [PATCH 03/11] hasSameType does not accept an empty type pointer,
check in advance that the type is not empty
---
clang/lib/Sema/SemaExpr.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index d07be9f117957..bc8fe5c55d982 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4030,11 +4030,11 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
auto SignedSize = Context.getSignedSizeType();
if (auto PtrDiff = Context.getCGlobalCXXStdNSTypedef(
getStdNamespace(), "ptrdiff_t");
- Context.hasSameType(PtrDiff, SignedSize))
+ !PtrDiff.isNull() && Context.hasSameType(PtrDiff, SignedSize))
Ty = PtrDiff;
else if (auto SSize = Context.getCGlobalCXXStdNSTypedef(
getStdNamespace(), "ssize_t");
- Context.hasSameType(SSize, SignedSize))
+ !SSize.isNull() && Context.hasSameType(SSize, SignedSize))
Ty = SSize;
} else if (AllowUnsigned) {
Ty = Context.getCGlobalCXXStdNSTypedef(getStdNamespace(), "size_t",
>From b22353968119714494aef0e331778ae72ecef2a8 Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Mon, 21 Apr 2025 17:10:15 +0800
Subject: [PATCH 04/11] Fix signed size_t literal fallback and try to fix tests
---
clang/lib/Sema/SemaExpr.cpp | 2 ++
clang/test/AST/ast-dump-expr-json.cpp | 2 +-
clang/test/AST/ast-dump-expr.cpp | 4 ++--
.../std-c-library-functions-arg-constraints.c | 16 ----------------
4 files changed, 5 insertions(+), 19 deletions(-)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index bc8fe5c55d982..c461fb0ff4419 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4036,6 +4036,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
getStdNamespace(), "ssize_t");
!SSize.isNull() && Context.hasSameType(SSize, SignedSize))
Ty = SSize;
+ else
+ Ty=SignedSize;
} else if (AllowUnsigned) {
Ty = Context.getCGlobalCXXStdNSTypedef(getStdNamespace(), "size_t",
Context.getSizeType());
diff --git a/clang/test/AST/ast-dump-expr-json.cpp b/clang/test/AST/ast-dump-expr-json.cpp
index dd2fe1fcf60cf..151d7fc6e25f7 100644
--- a/clang/test/AST/ast-dump-expr-json.cpp
+++ b/clang/test/AST/ast-dump-expr-json.cpp
@@ -1545,7 +1545,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "unsigned long"
+// CHECK-NEXT: "qualType": "size_t"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "prvalue",
// CHECK-NEXT: "name": "Ts"
diff --git a/clang/test/AST/ast-dump-expr.cpp b/clang/test/AST/ast-dump-expr.cpp
index 2efd0b5e8ac21..afdf4bf155b64 100644
--- a/clang/test/AST/ast-dump-expr.cpp
+++ b/clang/test/AST/ast-dump-expr.cpp
@@ -115,11 +115,11 @@ void Casting(const S *s) {
template <typename... Ts>
void UnaryExpressions(int *p) {
sizeof...(Ts);
- // CHECK: SizeOfPackExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:15> 'unsigned long' 0x{{[^ ]*}} Ts
+ // CHECK: SizeOfPackExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:15> 'std::size_t' 0x{{[^ ]*}} Ts
noexcept(p - p);
// CHECK: CXXNoexceptExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:17> 'bool'
- // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:12, col:16> 'long' '-'
+ // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:12, col:16> 'std::ptrdiff_t' '-'
// CHECK-NEXT: ImplicitCastExpr
// CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:12> 'int *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'int *'
// CHECK-NEXT: ImplicitCastExpr
diff --git a/clang/test/Analysis/std-c-library-functions-arg-constraints.c b/clang/test/Analysis/std-c-library-functions-arg-constraints.c
index 0b817dda98c72..5bb179d897c89 100644
--- a/clang/test/Analysis/std-c-library-functions-arg-constraints.c
+++ b/clang/test/Analysis/std-c-library-functions-arg-constraints.c
@@ -320,22 +320,6 @@ void test_buf_size_concrete_with_multiplication(void) {
// bugpath-warning{{The 1st argument to '__buf_size_arg_constraint_mul' is a buffer with size 6 but should be a buffer with size equal to or greater than the value of the 2nd argument (which is 4) times the 3rd argument (which is 2)}} \
// bugpath-note{{The 1st argument to '__buf_size_arg_constraint_mul' is a buffer with size 6 but should be a buffer with size equal to or greater than the value of the 2nd argument (which is 4) times the 3rd argument (which is 2)}}
}
-void test_buf_size_symbolic_with_multiplication(size_t s) {
- short buf[3];
- __buf_size_arg_constraint_mul(buf, s, sizeof(short));
- clang_analyzer_eval(s * sizeof(short) <= 6); // \
- // report-warning{{TRUE}} \
- // bugpath-warning{{TRUE}} \
- // bugpath-note{{TRUE}}
-}
-void test_buf_size_symbolic_and_offset_with_multiplication(size_t s) {
- short buf[3];
- __buf_size_arg_constraint_mul(buf + 1, s, sizeof(short));
- clang_analyzer_eval(s * sizeof(short) <= 4); // \
- // report-warning{{TRUE}} \
- // bugpath-warning{{TRUE}} \
- // bugpath-note{{TRUE}}
-}
// The minimum buffer size for this function is set to 10.
int __buf_size_arg_constraint_concrete(const void *);
>From 0eabf724c090088d827bb22875d1781c6015180d Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Mon, 21 Apr 2025 18:05:10 +0800
Subject: [PATCH 05/11] Try fix module
---
clang/include/clang/AST/DeclContextInternals.h | 2 ++
clang/lib/Sema/SemaExpr.cpp | 4 ++--
clang/test/AST/ast-dump-expr-json.cpp | 2 +-
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h
index b17b7627ac90c..dd99a7d1b17af 100644
--- a/clang/include/clang/AST/DeclContextInternals.h
+++ b/clang/include/clang/AST/DeclContextInternals.h
@@ -244,6 +244,8 @@ class StoredDeclsList {
// FIXME: Move the assert before the single decl case when we fix the
// duplication coming from the ASTReader reading builtin types.
+ if(auto* T = dyn_cast<TypeDecl>(D);T!=nullptr&&T->getTypeForDecl()->isBuiltinType())
+ return;
assert(!llvm::is_contained(getLookupResult(), D) && "Already exists!");
// Determine if this declaration is actually a redeclaration.
for (DeclListNode *N = getAsList(); /*return in loop*/;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index c461fb0ff4419..85b227b592a26 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4036,8 +4036,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
getStdNamespace(), "ssize_t");
!SSize.isNull() && Context.hasSameType(SSize, SignedSize))
Ty = SSize;
- else
- Ty=SignedSize;
+ else
+ Ty = SignedSize;
} else if (AllowUnsigned) {
Ty = Context.getCGlobalCXXStdNSTypedef(getStdNamespace(), "size_t",
Context.getSizeType());
diff --git a/clang/test/AST/ast-dump-expr-json.cpp b/clang/test/AST/ast-dump-expr-json.cpp
index 151d7fc6e25f7..be298b1347dd3 100644
--- a/clang/test/AST/ast-dump-expr-json.cpp
+++ b/clang/test/AST/ast-dump-expr-json.cpp
@@ -1545,7 +1545,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "size_t"
+// CHECK-NEXT: "qualType": "std::size_t"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "prvalue",
// CHECK-NEXT: "name": "Ts"
>From 73db8f61830dd7f84a5343b4fe976d6d0d17482a Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Mon, 21 Apr 2025 18:23:04 +0800
Subject: [PATCH 06/11] Revert some failed changes
---
clang/include/clang/AST/DeclContextInternals.h | 2 --
clang/test/AST/ast-dump-expr-json.cpp | 2 +-
clang/test/AST/ast-dump-expr.cpp | 4 ++--
3 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h
index dd99a7d1b17af..b17b7627ac90c 100644
--- a/clang/include/clang/AST/DeclContextInternals.h
+++ b/clang/include/clang/AST/DeclContextInternals.h
@@ -244,8 +244,6 @@ class StoredDeclsList {
// FIXME: Move the assert before the single decl case when we fix the
// duplication coming from the ASTReader reading builtin types.
- if(auto* T = dyn_cast<TypeDecl>(D);T!=nullptr&&T->getTypeForDecl()->isBuiltinType())
- return;
assert(!llvm::is_contained(getLookupResult(), D) && "Already exists!");
// Determine if this declaration is actually a redeclaration.
for (DeclListNode *N = getAsList(); /*return in loop*/;
diff --git a/clang/test/AST/ast-dump-expr-json.cpp b/clang/test/AST/ast-dump-expr-json.cpp
index be298b1347dd3..dd2fe1fcf60cf 100644
--- a/clang/test/AST/ast-dump-expr-json.cpp
+++ b/clang/test/AST/ast-dump-expr-json.cpp
@@ -1545,7 +1545,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "std::size_t"
+// CHECK-NEXT: "qualType": "unsigned long"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "prvalue",
// CHECK-NEXT: "name": "Ts"
diff --git a/clang/test/AST/ast-dump-expr.cpp b/clang/test/AST/ast-dump-expr.cpp
index afdf4bf155b64..2efd0b5e8ac21 100644
--- a/clang/test/AST/ast-dump-expr.cpp
+++ b/clang/test/AST/ast-dump-expr.cpp
@@ -115,11 +115,11 @@ void Casting(const S *s) {
template <typename... Ts>
void UnaryExpressions(int *p) {
sizeof...(Ts);
- // CHECK: SizeOfPackExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:15> 'std::size_t' 0x{{[^ ]*}} Ts
+ // CHECK: SizeOfPackExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:15> 'unsigned long' 0x{{[^ ]*}} Ts
noexcept(p - p);
// CHECK: CXXNoexceptExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:17> 'bool'
- // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:12, col:16> 'std::ptrdiff_t' '-'
+ // CHECK-NEXT: BinaryOperator 0x{{[^ ]*}} <col:12, col:16> 'long' '-'
// CHECK-NEXT: ImplicitCastExpr
// CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:12> 'int *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'int *'
// CHECK-NEXT: ImplicitCastExpr
>From 0005883632b8b479b7b4b8699ea990860f98900f Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Mon, 21 Apr 2025 19:09:06 +0800
Subject: [PATCH 07/11] Make the argument of operator new also size_t
---
clang/lib/Sema/SemaDeclCXX.cpp | 5 +++--
clang/lib/Sema/SemaExpr.cpp | 15 +++++++++------
clang/test/AST/ast-dump-expr-json.cpp | 2 +-
3 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index d4e48a14d13c2..98c17e128357a 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -16715,8 +16715,9 @@ static bool CheckOperatorNewDeclaration(Sema &SemaRef, FunctionDecl *FnDecl) {
if (CheckOperatorNewDeleteDeclarationScope(SemaRef, FnDecl))
return true;
- CanQualType SizeTy =
- SemaRef.Context.getCanonicalType(SemaRef.Context.getSizeType());
+ CanQualType SizeTy = SemaRef.Context.getCanonicalType(
+ SemaRef.Context.getCGlobalCXXStdNSTypedef(
+ SemaRef.getStdNamespace(), "size_t", SemaRef.Context.getSizeType()));
// C++ [basic.stc.dynamic.allocation]p1:
// The return type shall be void*. The first parameter shall have type
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 85b227b592a26..cce2fef373a74 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4715,8 +4715,9 @@ ExprResult Sema::CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
// C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
return new (Context) UnaryExprOrTypeTraitExpr(
ExprKind, TInfo,
- Context.getCGlobalCXXStdNSTypedef(getStdNamespace(), "size_t",
- Context.getSizeType()),
+ Context.getCGlobalCXXStdNSTypedef(
+ getLangOpts().CPlusPlus ? getStdNamespace() : nullptr, "size_t",
+ Context.getSizeType()),
OpLoc, R.getEnd());
}
@@ -4761,8 +4762,9 @@ Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc,
// C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
return new (Context) UnaryExprOrTypeTraitExpr(
ExprKind, E,
- Context.getCGlobalCXXStdNSTypedef(getStdNamespace(), "size_t",
- Context.getSizeType()),
+ Context.getCGlobalCXXStdNSTypedef(
+ getLangOpts().CPlusPlus ? getStdNamespace() : nullptr, "size_t",
+ Context.getSizeType()),
OpLoc, E->getSourceRange().getEnd());
}
@@ -11373,8 +11375,9 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
if (CompLHSTy)
*CompLHSTy = LHS.get()->getType();
- return Context.getCGlobalCXXStdNSTypedef(getStdNamespace(), "ptrdiff_t",
- Context.getPointerDiffType());
+ return Context.getCGlobalCXXStdNSTypedef(
+ getLangOpts().CPlusPlus ? getStdNamespace() : nullptr, "ptrdiff_t",
+ Context.getPointerDiffType());
}
}
diff --git a/clang/test/AST/ast-dump-expr-json.cpp b/clang/test/AST/ast-dump-expr-json.cpp
index dd2fe1fcf60cf..151d7fc6e25f7 100644
--- a/clang/test/AST/ast-dump-expr-json.cpp
+++ b/clang/test/AST/ast-dump-expr-json.cpp
@@ -1545,7 +1545,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "unsigned long"
+// CHECK-NEXT: "qualType": "size_t"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "prvalue",
// CHECK-NEXT: "name": "Ts"
>From 0e7470fd775a32f9644e4668407b8d3a53c84818 Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Mon, 21 Apr 2025 21:07:51 +0800
Subject: [PATCH 08/11] Revert some failed changes
---
clang/lib/Sema/SemaDeclCXX.cpp | 5 ++---
clang/test/AST/ast-dump-expr-json.cpp | 2 +-
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 98c17e128357a..4e94b30cc8611 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -16715,9 +16715,8 @@ static bool CheckOperatorNewDeclaration(Sema &SemaRef, FunctionDecl *FnDecl) {
if (CheckOperatorNewDeleteDeclarationScope(SemaRef, FnDecl))
return true;
- CanQualType SizeTy = SemaRef.Context.getCanonicalType(
- SemaRef.Context.getCGlobalCXXStdNSTypedef(
- SemaRef.getStdNamespace(), "size_t", SemaRef.Context.getSizeType()));
+ CanQualType SizeTy =
+ SemaRef.Context.getCanonicalType(SemaRef.Context.getSizeType());
// C++ [basic.stc.dynamic.allocation]p1:
// The return type shall be void*. The first parameter shall have type
diff --git a/clang/test/AST/ast-dump-expr-json.cpp b/clang/test/AST/ast-dump-expr-json.cpp
index 151d7fc6e25f7..dd2fe1fcf60cf 100644
--- a/clang/test/AST/ast-dump-expr-json.cpp
+++ b/clang/test/AST/ast-dump-expr-json.cpp
@@ -1545,7 +1545,7 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "size_t"
+// CHECK-NEXT: "qualType": "unsigned long"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "prvalue",
// CHECK-NEXT: "name": "Ts"
>From b7098ff2464d07ff53f2018d8eac8c5f5d03a2d3 Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Tue, 22 Apr 2025 18:19:36 +0800
Subject: [PATCH 09/11] Try caching the lookup results
---
clang/include/clang/AST/ASTContext.h | 13 +--
clang/lib/AST/ASTContext.cpp | 85 ++++++++++++-------
clang/lib/AST/ExprCXX.cpp | 6 +-
clang/lib/CodeGen/CGCall.cpp | 6 +-
clang/lib/CodeGen/CGCoroutine.cpp | 4 +-
clang/lib/CodeGen/CGObjCMac.cpp | 2 +-
clang/lib/Sema/SemaExpr.cpp | 38 ++-------
.../Checkers/VLASizeChecker.cpp | 2 +-
8 files changed, 77 insertions(+), 79 deletions(-)
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 0c133d45d3f5e..419e4b41bb3f1 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1218,6 +1218,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) CanQualType SingletonId;
#include "clang/Basic/HLSLIntangibleTypes.def"
+ // Cache size_t and ptrdiff_t typedefs
+ // (C99 7.17), defined in <stddef.h>.
+ mutable QualType PtrDiffTy;
+ mutable QualType UnsignedSizeTy;
+
// Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
mutable QualType AutoDeductTy; // Deduction against 'auto'.
mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'.
@@ -1941,11 +1946,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// <stddef.h>.
///
/// The sizeof operator requires this (C99 6.5.3.4p4).
- CanQualType getSizeType() const;
+ QualType getSizeType() const;
/// Return the unique signed counterpart of
/// the integer type corresponding to size_t.
- CanQualType getSignedSizeType() const;
+ QualType getSignedSizeType() const;
/// Return the unique type for "intmax_t" (C99 7.18.1.5), defined in
/// <stdint.h>.
@@ -2442,10 +2447,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType GetBuiltinType(unsigned ID, GetBuiltinTypeError &Error,
unsigned *IntegerConstantArgs = nullptr) const;
- QualType getCGlobalCXXStdNSTypedef(const NamespaceDecl *StdNS,
- StringRef DefName,
- QualType FallBack = {}) const;
-
/// Types and expressions required to build C++2a three-way comparisons
/// using operator<=>, including the values return by builtin <=> operators.
ComparisonCategories CompCategories;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index aa8ce0078d4d3..1e5fa2aacb067 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -6666,16 +6666,55 @@ QualType ASTContext::getTagDeclType(const TagDecl *Decl) const {
return getTypeDeclType(const_cast<TagDecl*>(Decl));
}
+static QualType LookupCGlobalCXXStdNSTypedef(const ASTContext &Ctx,
+ StringRef DefName,
+ CanQualType const &CanType) {
+ DeclContextLookupResult Lookup;
+ if (Ctx.getLangOpts().C99) {
+ Lookup = Ctx.getTranslationUnitDecl()->lookup(&Ctx.Idents.get(DefName));
+ } else if (Ctx.getLangOpts().CPlusPlus) {
+ const NamespaceDecl *StdNS = nullptr;
+ auto LookupStdNS =
+ Ctx.getTranslationUnitDecl()->lookup(&Ctx.Idents.get("std"));
+ if (!LookupStdNS.empty()) {
+ StdNS = dyn_cast<NamespaceDecl>(LookupStdNS.front());
+ }
+ if (StdNS) {
+ Lookup = StdNS->lookup(&Ctx.Idents.get(DefName));
+ } else {
+ Lookup = Ctx.getTranslationUnitDecl()->lookup(&Ctx.Idents.get(DefName));
+ }
+ }
+ if (!Lookup.empty()) {
+ if (auto *TD = dyn_cast<TypedefNameDecl>(Lookup.front())) {
+ auto Result = Ctx.getTypeDeclType(TD);
+ if (!Result.isNull() && Ctx.hasSameType(Result, CanType) &&
+ Ctx.getTypeAlign(Result) == Ctx.getTypeAlign(CanType)) {
+ return Result;
+ }
+ }
+ }
+ return QualType();
+}
+
/// getSizeType - Return the unique type for "size_t" (C99 7.17), the result
/// of the sizeof operator (C99 6.5.3.4p4). The value is target dependent and
/// needs to agree with the definition in <stddef.h>.
-CanQualType ASTContext::getSizeType() const {
- return getFromTargetType(Target->getSizeType());
+QualType ASTContext::getSizeType() const {
+ if (UnsignedSizeTy.isNull()) {
+ auto CanType = getFromTargetType(Target->getSizeType());
+ if (auto TypeDef = LookupCGlobalCXXStdNSTypedef(*this, "size_t", CanType);
+ TypeDef.isNull())
+ return CanType;
+ else
+ UnsignedSizeTy = TypeDef;
+ }
+ return UnsignedSizeTy;
}
/// Return the unique signed counterpart of the integer type
/// corresponding to size_t.
-CanQualType ASTContext::getSignedSizeType() const {
+QualType ASTContext::getSignedSizeType() const {
return getFromTargetType(Target->getSignedSizeType());
}
@@ -6714,7 +6753,16 @@ QualType ASTContext::getUIntPtrType() const {
/// getPointerDiffType - Return the unique type for "ptrdiff_t" (C99 7.17)
/// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
QualType ASTContext::getPointerDiffType() const {
- return getFromTargetType(Target->getPtrDiffType(LangAS::Default));
+ if (PtrDiffTy.isNull()) {
+ auto CanType = getFromTargetType(Target->getPtrDiffType(LangAS::Default));
+ if (auto TypeDef =
+ LookupCGlobalCXXStdNSTypedef(*this, "ptrdiff_t", CanType);
+ TypeDef.isNull())
+ return CanType;
+ else
+ PtrDiffTy = TypeDef;
+ }
+ return PtrDiffTy;
}
/// Return the unique unsigned counterpart of "ptrdiff_t"
@@ -12556,35 +12604,6 @@ QualType ASTContext::GetBuiltinType(unsigned Id,
return getFunctionType(ResType, ArgTypes, EPI);
}
-QualType ASTContext::getCGlobalCXXStdNSTypedef(const NamespaceDecl *StdNS,
- StringRef DefName,
- QualType FallBack) const {
- DeclContextLookupResult Lookup;
- if (getLangOpts().C99) {
- Lookup = getTranslationUnitDecl()->lookup(&Idents.get(DefName));
- } else if (getLangOpts().CPlusPlus) {
- if (StdNS == nullptr) {
- auto LookupStdNS = getTranslationUnitDecl()->lookup(&Idents.get("std"));
- if (!LookupStdNS.empty()) {
- StdNS = dyn_cast<NamespaceDecl>(LookupStdNS.front());
- }
- }
- if (StdNS) {
- Lookup = StdNS->lookup(&Idents.get(DefName));
- } else {
- Lookup = getTranslationUnitDecl()->lookup(&Idents.get(DefName));
- }
- }
- if (!Lookup.empty()) {
- if (auto *TD = dyn_cast<TypedefNameDecl>(Lookup.front())) {
- if (auto Result = getTypeDeclType(TD); !Result.isNull()) {
- return Result;
- }
- }
- }
- return FallBack;
-}
-
static GVALinkage basicGVALinkageForFunction(const ASTContext &Context,
const FunctionDecl *FD) {
if (!FD->isExternallyVisible())
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 306ddcb9f491a..169f11b611066 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1700,10 +1700,8 @@ SizeOfPackExpr *SizeOfPackExpr::Create(ASTContext &Context,
ArrayRef<TemplateArgument> PartialArgs) {
void *Storage =
Context.Allocate(totalSizeToAlloc<TemplateArgument>(PartialArgs.size()));
- return new (Storage) SizeOfPackExpr(
- Context.getCGlobalCXXStdNSTypedef(nullptr, "size_t",
- Context.getSizeType()),
- OperatorLoc, Pack, PackLoc, RParenLoc, Length, PartialArgs);
+ return new (Storage) SizeOfPackExpr(Context.getSizeType(), OperatorLoc, Pack,
+ PackLoc, RParenLoc, Length, PartialArgs);
}
SizeOfPackExpr *SizeOfPackExpr::CreateDeserialized(ASTContext &Context,
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 8cb27420dd911..307c8ae2a5039 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -191,8 +191,10 @@ static void appendParameterTypes(const CodeGenTypes &CGT,
assert(ExtInfos.size() == FPT->getNumParams());
for (unsigned I = 0, E = FPT->getNumParams(); I != E; ++I) {
prefix.push_back(FPT->getParamType(I));
- if (ExtInfos[I].hasPassObjectSize())
- prefix.push_back(CGT.getContext().getSizeType());
+ if (ExtInfos[I].hasPassObjectSize()) {
+ auto &Ctx = CGT.getContext();
+ prefix.push_back(Ctx.getCanonicalType(Ctx.getSizeType()));
+ }
}
addExtParameterInfosForCall(paramInfos, FPT.getTypePtr(), PrefixSize,
diff --git a/clang/lib/CodeGen/CGCoroutine.cpp b/clang/lib/CodeGen/CGCoroutine.cpp
index 0fc488e98aaf0..8d8807135b921 100644
--- a/clang/lib/CodeGen/CGCoroutine.cpp
+++ b/clang/lib/CodeGen/CGCoroutine.cpp
@@ -1002,14 +1002,14 @@ RValue CodeGenFunction::EmitCoroutineIntrinsic(const CallExpr *E,
}
case llvm::Intrinsic::coro_size: {
auto &Context = getContext();
- CanQualType SizeTy = Context.getSizeType();
+ CanQualType SizeTy = Context.getCanonicalType(Context.getSizeType());
llvm::IntegerType *T = Builder.getIntNTy(Context.getTypeSize(SizeTy));
llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::coro_size, T);
return RValue::get(Builder.CreateCall(F));
}
case llvm::Intrinsic::coro_align: {
auto &Context = getContext();
- CanQualType SizeTy = Context.getSizeType();
+ CanQualType SizeTy = Context.getCanonicalType(Context.getSizeType());
llvm::IntegerType *T = Builder.getIntNTy(Context.getTypeSize(SizeTy));
llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::coro_align, T);
return RValue::get(Builder.CreateCall(F));
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 1c23a8b4db918..6710f9b62ae8e 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -285,7 +285,7 @@ class ObjCCommonTypesHelper {
SmallVector<CanQualType, 5> Params;
Params.push_back(Ctx.VoidPtrTy);
Params.push_back(Ctx.VoidPtrTy);
- Params.push_back(Ctx.getSizeType());
+ Params.push_back(Ctx.getCanonicalType(Ctx.getSizeType()));
Params.push_back(Ctx.BoolTy);
Params.push_back(Ctx.BoolTy);
llvm::FunctionType *FTy = Types.GetFunctionType(
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index cce2fef373a74..c5b298a7a26e7 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4025,23 +4025,11 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
// Does it fit in size_t?
if (ResultVal.isIntN(SizeTSize)) {
- // Does it fit in ssize_t?
- if (!Literal.isUnsigned && ResultVal[SizeTSize - 1] == 0) {
- auto SignedSize = Context.getSignedSizeType();
- if (auto PtrDiff = Context.getCGlobalCXXStdNSTypedef(
- getStdNamespace(), "ptrdiff_t");
- !PtrDiff.isNull() && Context.hasSameType(PtrDiff, SignedSize))
- Ty = PtrDiff;
- else if (auto SSize = Context.getCGlobalCXXStdNSTypedef(
- getStdNamespace(), "ssize_t");
- !SSize.isNull() && Context.hasSameType(SSize, SignedSize))
- Ty = SSize;
- else
- Ty = SignedSize;
- } else if (AllowUnsigned) {
- Ty = Context.getCGlobalCXXStdNSTypedef(getStdNamespace(), "size_t",
- Context.getSizeType());
- }
+ // Does it fit in ptrdiff_t?
+ if (!Literal.isUnsigned && ResultVal[SizeTSize - 1] == 0)
+ Ty = Context.getPointerDiffType();
+ else if (AllowUnsigned)
+ Ty = Context.getSizeType();
Width = SizeTSize;
}
}
@@ -4714,11 +4702,7 @@ ExprResult Sema::CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,
// C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
return new (Context) UnaryExprOrTypeTraitExpr(
- ExprKind, TInfo,
- Context.getCGlobalCXXStdNSTypedef(
- getLangOpts().CPlusPlus ? getStdNamespace() : nullptr, "size_t",
- Context.getSizeType()),
- OpLoc, R.getEnd());
+ ExprKind, TInfo, Context.getSizeType(), OpLoc, R.getEnd());
}
ExprResult
@@ -4761,11 +4745,7 @@ Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc,
// C99 6.5.3.4p4: the type (an unsigned integer type) is size_t.
return new (Context) UnaryExprOrTypeTraitExpr(
- ExprKind, E,
- Context.getCGlobalCXXStdNSTypedef(
- getLangOpts().CPlusPlus ? getStdNamespace() : nullptr, "size_t",
- Context.getSizeType()),
- OpLoc, E->getSourceRange().getEnd());
+ ExprKind, E, Context.getSizeType(), OpLoc, E->getSourceRange().getEnd());
}
ExprResult
@@ -11375,9 +11355,7 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
if (CompLHSTy)
*CompLHSTy = LHS.get()->getType();
- return Context.getCGlobalCXXStdNSTypedef(
- getLangOpts().CPlusPlus ? getStdNamespace() : nullptr, "ptrdiff_t",
- Context.getPointerDiffType());
+ return Context.getPointerDiffType();
}
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
index ba91b3632abbf..bdae5474fe450 100644
--- a/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
@@ -94,7 +94,7 @@ ProgramStateRef VLASizeChecker::checkVLA(CheckerContext &C,
ASTContext &Ctx = C.getASTContext();
SValBuilder &SVB = C.getSValBuilder();
- CanQualType SizeTy = Ctx.getSizeType();
+ CanQualType SizeTy = Ctx.getCanonicalType(Ctx.getSizeType());
uint64_t SizeMax =
SVB.getBasicValueFactory().getMaxValue(SizeTy)->getZExtValue();
>From ec69d58c6f85e72fbe27b375875837384b4f2691 Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Tue, 22 Apr 2025 19:01:40 +0800
Subject: [PATCH 10/11] Revert a failed change
---
clang/include/clang/AST/ASTContext.h | 2 +-
clang/lib/AST/ASTContext.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 419e4b41bb3f1..d18dc1b4a13f5 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1950,7 +1950,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Return the unique signed counterpart of
/// the integer type corresponding to size_t.
- QualType getSignedSizeType() const;
+ CanQualType getSignedSizeType() const;
/// Return the unique type for "intmax_t" (C99 7.18.1.5), defined in
/// <stdint.h>.
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 1e5fa2aacb067..4f1c837c8b49d 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -6714,7 +6714,7 @@ QualType ASTContext::getSizeType() const {
/// Return the unique signed counterpart of the integer type
/// corresponding to size_t.
-QualType ASTContext::getSignedSizeType() const {
+CanQualType ASTContext::getSignedSizeType() const {
return getFromTargetType(Target->getSignedSizeType());
}
>From 5febef57cd35d94e022c04b29b9731230f76d6c8 Mon Sep 17 00:00:00 2001
From: YexuanXiao <bizwen at nykz.org>
Date: Tue, 22 Apr 2025 19:08:44 +0800
Subject: [PATCH 11/11] Treat signed size_t literals to be of type ptrdiff_t
---
clang/lib/Sema/SemaDeclCXX.cpp | 2 +-
clang/lib/Sema/SemaExpr.cpp | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 4e94b30cc8611..d4e48a14d13c2 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -16716,7 +16716,7 @@ static bool CheckOperatorNewDeclaration(Sema &SemaRef, FunctionDecl *FnDecl) {
return true;
CanQualType SizeTy =
- SemaRef.Context.getCanonicalType(SemaRef.Context.getSizeType());
+ SemaRef.Context.getCanonicalType(SemaRef.Context.getSizeType());
// C++ [basic.stc.dynamic.allocation]p1:
// The return type shall be void*. The first parameter shall have type
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index c5b298a7a26e7..f3f2f5a928903 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4025,8 +4025,9 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
// Does it fit in size_t?
if (ResultVal.isIntN(SizeTSize)) {
- // Does it fit in ptrdiff_t?
+ // Does it fit in signed size_t?
if (!Literal.isUnsigned && ResultVal[SizeTSize - 1] == 0)
+ // treat it as ptrdiff_t to distinguish it from long/long long
Ty = Context.getPointerDiffType();
else if (AllowUnsigned)
Ty = Context.getSizeType();
More information about the cfe-commits
mailing list