Skip to content

Commit fdd38f8

Browse files
[BoundsSafety] Add utilities for checking dependent count and pointer
Add functions for checking various properties of dependent count to ValueDecl: - Whether the count has dereference or not - Whether the count is used in an inout pointer Add a similar function to check if a count-attributed type is depending on an inout count.
1 parent cc5d6c3 commit fdd38f8

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed

clang/include/clang/AST/Decl.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,38 @@ class ValueDecl : public NamedDecl {
732732
bool isInitCapture() const;
733733

734734
/* TO_UPSTREAM(BoundsSafety) ON */
735+
/// Whether this decl is a dependent count. This returns true for dependent
736+
/// counts with and without dereference:
737+
/// void foo(int *__counted_by(m) p, int m,
738+
/// int *__counted_by(*n) *q, int *n);
739+
/// True for both `m` and `n`.
740+
bool isDependentCount() const;
741+
742+
/// Whether this decl is a dependent count without a dereference:
743+
/// void foo(int *__counted_by(m) p, int m,
744+
/// int *__counted_by(*n) *q, int *n);
745+
/// True for `m`, but false for `n`.
746+
bool isDependentCountWithoutDeref() const;
747+
748+
/// Whether this decl is a dependent count with a dereference:
749+
/// void foo(int *__counted_by(m) p, int m,
750+
/// int *__counted_by(*n) *q, int *n);
751+
/// False for `m`, but true for `n`.
752+
bool isDependentCountWithDeref() const;
753+
754+
/// Whether this decl is a dependent count that is used at least once in a
755+
/// count expression of an inout count-attributed pointer.
756+
/// void foo(int *__counted_by(a) p, int a,
757+
/// int *__counted_by(*b) q, int *b,
758+
/// int *__counted_by(c) *r, int c,
759+
/// int *__counted_by(*d) *s, int *d);
760+
/// True for `c` and `d`, but false for `a` and `b`.
761+
/// void bar(int *__counted_by(count) in_p,
762+
/// int *__counted_by(count) *out_p,
763+
/// int count);
764+
/// True for `count` (because of `out_p`).
765+
bool isDependentCountThatIsUsedInInoutPointer() const;
766+
735767
/// Whether this decl is a dependent parameter referred to by the return type
736768
/// that is a bounds-attributed type.
737769
bool isDependentParamOfReturnType(

clang/include/clang/AST/TypeBase.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2651,6 +2651,10 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
26512651
bool isAnyVaListType(ASTContext &) const;
26522652
bool isDynamicRangePointerType() const;
26532653
bool isBoundsAttributedType() const;
2654+
/// Whether this type is a count-attributed type that is depending on an
2655+
/// inout count. True for `__counted_by(*count)`, but false for
2656+
/// `__counted_by(len)`.
2657+
bool isCountAttributedTypeDependingOnInoutCount() const;
26542658
bool isValueTerminatedType() const;
26552659
bool isImplicitlyNullTerminatedType(const ASTContext &) const;
26562660
/* TO_UPSTREAM(BoundsSafety) OFF */

clang/lib/AST/Decl.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5502,6 +5502,27 @@ bool ValueDecl::isParameterPack() const {
55025502
}
55035503

55045504
/* TO_UPSTREAM(BoundsSafety) ON */
5505+
bool ValueDecl::isDependentCount() const {
5506+
return hasAttr<DependerDeclsAttr>();
5507+
}
5508+
5509+
bool ValueDecl::isDependentCountWithoutDeref() const {
5510+
const auto *Att = getAttr<DependerDeclsAttr>();
5511+
return Att && !Att->getIsDeref();
5512+
}
5513+
5514+
bool ValueDecl::isDependentCountWithDeref() const {
5515+
const auto *Att = getAttr<DependerDeclsAttr>();
5516+
return Att && Att->getIsDeref();
5517+
}
5518+
5519+
bool ValueDecl::isDependentCountThatIsUsedInInoutPointer() const {
5520+
const auto *Att = getAttr<DependerDeclsAttr>();
5521+
return Att &&
5522+
std::any_of(Att->dependerLevels_begin(), Att->dependerLevels_end(),
5523+
[](unsigned Level) { return Level > 0; });
5524+
}
5525+
55055526
bool ValueDecl::isDependentParamOfReturnType(
55065527
const BoundsAttributedType **RetType,
55075528
const TypeCoupledDeclRefInfo **Info) const {

clang/lib/AST/Type.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,14 @@ bool Type::isBoundsAttributedType() const {
829829
return getAs<BoundsAttributedType>();
830830
}
831831

832+
bool Type::isCountAttributedTypeDependingOnInoutCount() const {
833+
const auto *CAT = getAs<CountAttributedType>();
834+
return CAT &&
835+
std::any_of(
836+
CAT->dependent_decl_begin(), CAT->dependent_decl_end(),
837+
[](const TypeCoupledDeclRefInfo &Info) { return Info.isDeref(); });
838+
}
839+
832840
bool Type::isValueTerminatedType() const {
833841
return getAs<ValueTerminatedType>();
834842
}

0 commit comments

Comments
 (0)