Skip to content

Commit f4a3a88

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. (cherry picked from commit fdd38f8) Conflicts: clang/include/clang/AST/TypeBase.h
1 parent 907e00a commit f4a3a88

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
@@ -712,6 +712,38 @@ class ValueDecl : public NamedDecl {
712712
bool isInitCapture() const;
713713

714714
/* TO_UPSTREAM(BoundsSafety) ON */
715+
/// Whether this decl is a dependent count. This returns true for dependent
716+
/// counts with and without dereference:
717+
/// void foo(int *__counted_by(m) p, int m,
718+
/// int *__counted_by(*n) *q, int *n);
719+
/// True for both `m` and `n`.
720+
bool isDependentCount() const;
721+
722+
/// Whether this decl is a dependent count without a dereference:
723+
/// void foo(int *__counted_by(m) p, int m,
724+
/// int *__counted_by(*n) *q, int *n);
725+
/// True for `m`, but false for `n`.
726+
bool isDependentCountWithoutDeref() const;
727+
728+
/// Whether this decl is a dependent count with a dereference:
729+
/// void foo(int *__counted_by(m) p, int m,
730+
/// int *__counted_by(*n) *q, int *n);
731+
/// False for `m`, but true for `n`.
732+
bool isDependentCountWithDeref() const;
733+
734+
/// Whether this decl is a dependent count that is used at least once in a
735+
/// count expression of an inout count-attributed pointer.
736+
/// void foo(int *__counted_by(a) p, int a,
737+
/// int *__counted_by(*b) q, int *b,
738+
/// int *__counted_by(c) *r, int c,
739+
/// int *__counted_by(*d) *s, int *d);
740+
/// True for `c` and `d`, but false for `a` and `b`.
741+
/// void bar(int *__counted_by(count) in_p,
742+
/// int *__counted_by(count) *out_p,
743+
/// int count);
744+
/// True for `count` (because of `out_p`).
745+
bool isDependentCountThatIsUsedInInoutPointer() const;
746+
715747
/// Whether this decl is a dependent parameter referred to by the return type
716748
/// that is a bounds-attributed type.
717749
bool isDependentParamOfReturnType(

clang/include/clang/AST/Type.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2615,6 +2615,10 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
26152615
bool isAnyVaListType(ASTContext &) const;
26162616
bool isDynamicRangePointerType() const;
26172617
bool isBoundsAttributedType() const;
2618+
/// Whether this type is a count-attributed type that is depending on an
2619+
/// inout count. True for `__counted_by(*count)`, but false for
2620+
/// `__counted_by(len)`.
2621+
bool isCountAttributedTypeDependingOnInoutCount() const;
26182622
bool isValueTerminatedType() const;
26192623
bool isImplicitlyNullTerminatedType(const ASTContext &) const;
26202624
/* TO_UPSTREAM(BoundsSafety) OFF */

clang/lib/AST/Decl.cpp

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

55155515
/* TO_UPSTREAM(BoundsSafety) ON */
5516+
bool ValueDecl::isDependentCount() const {
5517+
return hasAttr<DependerDeclsAttr>();
5518+
}
5519+
5520+
bool ValueDecl::isDependentCountWithoutDeref() const {
5521+
const auto *Att = getAttr<DependerDeclsAttr>();
5522+
return Att && !Att->getIsDeref();
5523+
}
5524+
5525+
bool ValueDecl::isDependentCountWithDeref() const {
5526+
const auto *Att = getAttr<DependerDeclsAttr>();
5527+
return Att && Att->getIsDeref();
5528+
}
5529+
5530+
bool ValueDecl::isDependentCountThatIsUsedInInoutPointer() const {
5531+
const auto *Att = getAttr<DependerDeclsAttr>();
5532+
return Att &&
5533+
std::any_of(Att->dependerLevels_begin(), Att->dependerLevels_end(),
5534+
[](unsigned Level) { return Level > 0; });
5535+
}
5536+
55165537
bool ValueDecl::isDependentParamOfReturnType(
55175538
const BoundsAttributedType **RetType,
55185539
const TypeCoupledDeclRefInfo **Info) const {

clang/lib/AST/Type.cpp

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

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

0 commit comments

Comments
 (0)