[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
Wed Feb 5 12:09:45 PST 2025


================
@@ -431,6 +431,122 @@ AST_MATCHER(CXXConstructExpr, isSafeSpanTwoParamConstruct) {
   return false;
 }
 
+class MaxValueEval : public ConstStmtVisitor<MaxValueEval, llvm::APInt> {
+
+  ASTContext &Context;
+  llvm::APInt Max;
+  unsigned bit_width;
+
+public:
+  typedef ConstStmtVisitor<MaxValueEval, llvm::APInt> VisitorBase;
+
+  explicit MaxValueEval(ASTContext &Ctx, const Expr *exp) : Context(Ctx) {
+    bit_width = Ctx.getIntWidth(exp->getType());
+    Max = llvm::APInt::getSignedMaxValue(bit_width);
+    // val.clear();
+  }
+
+  llvm::APInt findMatch(Expr *exp) { return TraverseStmt(exp); }
+
+  llvm::APInt TraverseStmt(Stmt *S) {
+    if (Expr *E = dyn_cast<Expr>(S)) {
+      Expr::EvalResult EVResult;
+      if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+        return TraverseImplicitCastExpr(ICE);
+      } else if (dyn_cast<DeclRefExpr>(E)) {
+        return Max;
+      } else if (dyn_cast<ArraySubscriptExpr>(E)) {
+        return Max;
+      } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
+        return TraverseBinaryOperator(BO);
+      } else if (IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E)) {
+        return IL->getValue();
+      }
+    }
+    return Max;
+  }
+
+  llvm::APInt TraverseImplicitCastExpr(ImplicitCastExpr *E) {
+    Expr::EvalResult EVResult;
+    if (EvaluateExpression(E, EVResult)) {
+      return EVResult.Val.getInt();
+    } else {
+      Expr *eExpr = E->getSubExpr();
+      llvm::APInt subEValue = TraverseStmt(eExpr);
+      switch (E->getCastKind()) {
+      case CK_LValueToRValue:
+        return subEValue;
+      case CK_IntegralCast: {
+        Expr *eExpr = E->getSubExpr();
+        clang::IntegerLiteral *intLiteral = clang::IntegerLiteral::Create(
+            Context, subEValue, eExpr->getType(), {});
+        E->setSubExpr(intLiteral);
----------------
ziqingluo-90 wrote:

Calling `setSubExpr ` changes the AST.  I think we should not do this?

https://github.com/llvm/llvm-project/pull/112284


More information about the cfe-commits mailing list