diff options
author | YexuanXiao <bizwen@nykz.org> | 2025-07-18 09:45:57 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-07-17 22:45:57 -0300 |
commit | c27e283cfbca2bd22f34592430e98ee76ed60ad8 (patch) | |
tree | 5f8e23eeadff53a72e3871720737c84771dcbc2c /clang/lib/Sema | |
parent | baa291bfb58e73a253669b86ac604cf8e6792b6c (diff) | |
download | llvm-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.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 6 |
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. /// |