Skip to content

Commit

Permalink
RecursiveASTVisitor: Traverse the child of a BoundsValueExpr (#978)
Browse files Browse the repository at this point in the history
* Traverse BoundsValueExpr temp bindings in RecursiveASTVisitor

* Don't traverse the children of a BoundsValueExpr in NonModifyingExprSema

* Add test cases involving _Assume_bounds_cast to free-variables.c

* Don't traverse temp bindings of a BoundsValueExpr in VariableCountHelper or ReplaceVariableHelper

* Remove unnecessary TraverseBoundsValueExpr override from ReplaceVariableHelper
  • Loading branch information
kkjeer committed Feb 20, 2021
1 parent 6aae701 commit ad482c0
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
6 changes: 5 additions & 1 deletion clang/include/clang/AST/RecursiveASTVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2617,7 +2617,6 @@ DEF_TRAVERSE_STMT(NullaryBoundsExpr, {})
DEF_TRAVERSE_STMT(RangeBoundsExpr, {})
DEF_TRAVERSE_STMT(InteropTypeExpr, {})
DEF_TRAVERSE_STMT(PositionalParameterExpr, {})
DEF_TRAVERSE_STMT(BoundsValueExpr, {})
DEF_TRAVERSE_STMT(CHKCBindTemporaryExpr, {})
DEF_TRAVERSE_STMT(PackExpr, {})

Expand Down Expand Up @@ -2675,6 +2674,11 @@ DEF_TRAVERSE_STMT(BoundsCastExpr, {
TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
})

// CheckedC Bounds Value Expressions
DEF_TRAVERSE_STMT(BoundsValueExpr, {
TRY_TO(TraverseStmt(S->getTemporaryBinding()));
})


// OpenMP directives.
template <typename Derived>
Expand Down
17 changes: 17 additions & 0 deletions clang/lib/Sema/SemaBounds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,15 @@ namespace {
++Count;
return true;
}

// Do not traverse the child of a BoundsValueExpr.
// If a BoundsValueExpr uses the variable V, this should not count
// toward the total occurrence count of V in the expression.
// For example, for the expression BoundsValue(TempBinding(v)) + v, the
// total occurrence count of the variable v should be 1, not 2.
bool TraverseBoundsValueExpr(BoundsValueExpr *E) {
return true;
}
};

// VariableOccurrenceCount returns the number of occurrences of V in E.
Expand Down Expand Up @@ -6573,6 +6582,14 @@ namespace {
return true;
}

// Do not traverse the children of a BoundsValueExpr. Any expressions
// that are wrapped in a BoundsValueExpr should not be considered
// modifying expressions. For example, BoundsValue(TempBinding(f()))
// should not be considered modifying.
bool TraverseBoundsValueExpr(BoundsValueExpr *E) {
return true;
}


private:
Sema &S;
Expand Down
14 changes: 14 additions & 0 deletions clang/test/CheckedC/static-checking/free-variables.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,3 +172,17 @@ void g(void) {
// expected-note {{inferred bounds are}}
}

void f_itype(int *p : itype(ptr<int>));
void f_arrayptr(array_ptr<int> p : count(2));

void h(void) {
int *p = 0;
f_itype(_Assume_bounds_cast<ptr<int>>(p)); // expected-warning {{cannot prove argument meets declared bounds for 1st parameter}} \
// expected-note {{(expanded) expected argument bounds are 'bounds((_Array_ptr<int>)_Assume_bounds_cast<_Ptr<int>>p(count(1)), (_Array_ptr<int>)_Assume_bounds_cast<_Ptr<int>>p(count(1)) + 1)'}} \
// expected-note {{(expanded) inferred bounds are 'bounds((_Array_ptr<int>)value of p, (_Array_ptr<int>)value of p + 1)'}}

array_ptr<int> a : count(2) = 0;
f_arrayptr(_Assume_bounds_cast<array_ptr<int>>(a, count(2))); // expected-warning {{cannot prove argument meets declared bounds for 1st parameter}} \
// expected-note {{(expanded) expected argument bounds are 'bounds(_Assume_bounds_cast<_Array_ptr<int>>a(count(2)), _Assume_bounds_cast<_Array_ptr<int>>a(count(2)) + 2)'}} \
// expected-note {{(expanded) inferred bounds are 'bounds((_Array_ptr<int>)value of a, (_Array_ptr<int>)value of a + 2)'}}
}

0 comments on commit ad482c0

Please sign in to comment.