Skip to content
Closed
7 changes: 6 additions & 1 deletion clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&'.
Expand Down Expand Up @@ -1941,7 +1946,7 @@ 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.
Expand Down
54 changes: 51 additions & 3 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6666,11 +6666,50 @@ 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
Expand Down Expand Up @@ -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"
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CGCoroutine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGObjCMac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
8 changes: 5 additions & 3 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4025,9 +4025,10 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {

// Does it fit in size_t?
if (ResultVal.isIntN(SizeTSize)) {
// Does it fit in ssize_t?
// Does it fit in signed size_t?
if (!Literal.isUnsigned && ResultVal[SizeTSize - 1] == 0)
Ty = Context.getSignedSizeType();
// treat it as ptrdiff_t to distinguish it from long/long long
Ty = Context.getPointerDiffType();
else if (AllowUnsigned)
Ty = Context.getSizeType();
Width = SizeTSize;
Expand Down Expand Up @@ -11353,7 +11354,8 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
}
}

if (CompLHSTy) *CompLHSTy = LHS.get()->getType();
if (CompLHSTy)
*CompLHSTy = LHS.get()->getType();
return Context.getPointerDiffType();
}
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Checkers/VLASizeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
16 changes: 0 additions & 16 deletions clang/test/Analysis/std-c-library-functions-arg-constraints.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down