Skip to content
Closed
4 changes: 4 additions & 0 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
29 changes: 29 additions & 0 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/AST/ExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
36 changes: 28 additions & 8 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4026,10 +4026,22 @@ 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");
!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",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a test file to verify that size_t is shown instead of unsigned long/unsigned long long?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm looking into it.

Context.getSizeType());
}
Width = SizeTSize;
}
}
Expand Down Expand Up @@ -4702,7 +4714,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
Expand Down Expand Up @@ -4745,7 +4760,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());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mentioning getStdNamespace for C is really not great. Couldn't we merge getCGlobalCXXStdNSTypedef into Context.getSizeType?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it appropriate to change it to getLangOpts().CPlusPlus ? getStdNamespace() : nullptr? I’m concerned that moving it into getSizeType might introduce unintended effects.

}

ExprResult
Expand Down Expand Up @@ -11353,8 +11371,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());
}
}

Expand Down
2 changes: 1 addition & 1 deletion clang/test/AST/ast-dump-expr-json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions clang/test/AST/ast-dump-expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
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