[clang] [Wunsafe-buffer-usage] False positives for & expression indexing constant size array (arr[anything & 0]) (PR #112284)
Ziqing Luo via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 29 14:09:40 PDT 2024
================
@@ -420,6 +420,118 @@ AST_MATCHER(CXXConstructExpr, isSafeSpanTwoParamConstruct) {
return false;
}
+class MaxValueEval : public RecursiveASTVisitor<MaxValueEval> {
+
+ std::vector<llvm::APInt> val;
+ ASTContext &Context;
+ llvm::APInt Max;
+ unsigned bit_width;
+
+public:
+ typedef RecursiveASTVisitor<MaxValueEval> VisitorBase;
+
+ explicit MaxValueEval(ASTContext &Ctx, const Expr *exp) : Context(Ctx) {
+ bit_width = Ctx.getIntWidth(exp->getType());
+ Max = llvm::APInt::getSignedMaxValue(bit_width);
+ val.clear();
+ }
+
+ bool findMatch(Expr *exp) {
+ TraverseStmt(exp);
+ return true;
+ }
+
+ bool VisitDeclRefExpr(DeclRefExpr *dre) {
+ val.push_back(Max);
+ return false;
+ }
+
+ bool VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
+ val.push_back(Max);
+ return false;
+ }
+
+ bool EvaluateExpression(Expr *exp) {
+ Expr::EvalResult EVResult;
+ if (exp->EvaluateAsInt(EVResult, Context)) {
+ llvm::APSInt Result = EVResult.Val.getInt();
+ val.push_back(Result);
+ return true;
+ }
+ return false;
+ }
+
+ bool VisitBinaryOperator(BinaryOperator *E) {
----------------
ziqingluo-90 wrote:
According to the document of `RecursiveASTVisitor`:
>/// These three method groups are tiered (Traverse* > WalkUpFrom* >
>/// Visit*). A method (e.g. Traverse*) may call methods from the same
>/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
>/// It may not call methods from a higher tier.
we should override `TraverseBinaryOperator` here, because this function depends on the results of its' two children (i.e., `TraverseStmt(E->getLHS())` below).
Looks like `Visit*` is for cases where visiting a node is independent of its' children.
https://github.com/llvm/llvm-project/pull/112284
More information about the cfe-commits
mailing list