aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorYexuanXiao <bizwen@nykz.org>2025-07-18 09:45:57 +0800
committerGitHub <noreply@github.com>2025-07-17 22:45:57 -0300
commitc27e283cfbca2bd22f34592430e98ee76ed60ad8 (patch)
tree5f8e23eeadff53a72e3871720737c84771dcbc2c /clang/lib/Sema
parentbaa291bfb58e73a253669b86ac604cf8e6792b6c (diff)
downloadllvm-c27e283cfbca2bd22f34592430e98ee76ed60ad8.zip
llvm-c27e283cfbca2bd22f34592430e98ee76ed60ad8.tar.gz
llvm-c27e283cfbca2bd22f34592430e98ee76ed60ad8.tar.bz2
[Clang] Make the SizeType, SignedSizeType and PtrdiffType be named sugar 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.
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp4
-rw-r--r--clang/lib/Sema/SemaExpr.cpp3
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp10
-rw-r--r--clang/lib/Sema/TreeTransform.h6
4 files changed, 17 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index dd5b710..5e523fe 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -5239,7 +5239,9 @@ bool Sema::BuiltinVAStartARMMicrosoft(CallExpr *Call) {
<< 2 << Arg1->getType() << ConstCharPtrTy;
const QualType SizeTy = Context.getSizeType();
- if (Arg2Ty->getCanonicalTypeInternal().withoutLocalFastQualifiers() != SizeTy)
+ if (!Context.hasSameType(
+ Arg2Ty->getCanonicalTypeInternal().withoutLocalFastQualifiers(),
+ SizeTy))
Diag(Arg2->getBeginLoc(), diag::err_typecheck_convert_incompatible)
<< Arg2->getType() << SizeTy << 1 /* different class */
<< 0 /* qualifier difference */
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 728ada3..45c7178 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4564,6 +4564,9 @@ static void captureVariablyModifiedType(ASTContext &Context, QualType T,
case Type::Atomic:
T = cast<AtomicType>(Ty)->getValueType();
break;
+ case Type::PredefinedSugar:
+ T = cast<PredefinedSugarType>(Ty)->desugar();
+ break;
}
} while (!T.isNull() && T->isVariablyModifiedType());
}
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index fd95f4e..0edfd60 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -3461,11 +3461,11 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
// non-templated allocation function we are trying to declare here.
if (FunctionDecl *Func = dyn_cast<FunctionDecl>(*Alloc)) {
if (Func->getNumParams() == Params.size()) {
- llvm::SmallVector<QualType, 3> FuncParams;
- for (auto *P : Func->parameters())
- FuncParams.push_back(
- Context.getCanonicalType(P->getType().getUnqualifiedType()));
- if (llvm::ArrayRef(FuncParams) == Params) {
+ if (std::equal(Func->param_begin(), Func->param_end(), Params.begin(),
+ Params.end(), [&](ParmVarDecl *D, QualType RT) {
+ return Context.hasSameUnqualifiedType(D->getType(),
+ RT);
+ })) {
// Make the function visible to name lookup, even if we found it in
// an unimported module. It either is an implicitly-declared global
// allocation function, or is suppressing that function.
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 286c2b4..c7428d1 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -7245,6 +7245,12 @@ QualType TreeTransform<Derived>::TransformDependentBitIntType(
return Result;
}
+template <typename Derived>
+QualType TreeTransform<Derived>::TransformPredefinedSugarType(
+ TypeLocBuilder &TLB, PredefinedSugarTypeLoc TL) {
+ llvm_unreachable("This type does not need to be transformed.");
+}
+
/// Simple iterator that traverses the template arguments in a
/// container that provides a \c getArgLoc() member function.
///