From b6d5e15aae202f157c6cd63da8fa4b089e7b31e9 Mon Sep 17 00:00:00 2001
From: rdivacky <rdivacky@FreeBSD.org>
Date: Wed, 4 Nov 2009 15:04:32 +0000
Subject: Update clang to r86025.

---
 lib/Analysis/DivZeroChecker.cpp | 70 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 lib/Analysis/DivZeroChecker.cpp

(limited to 'lib/Analysis/DivZeroChecker.cpp')

diff --git a/lib/Analysis/DivZeroChecker.cpp b/lib/Analysis/DivZeroChecker.cpp
new file mode 100644
index 0000000..9c2359f
--- /dev/null
+++ b/lib/Analysis/DivZeroChecker.cpp
@@ -0,0 +1,70 @@
+//== DivZeroChecker.cpp - Division by zero checker --------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines DivZeroChecker, a builtin check in GRExprEngine that performs
+// checks for division by zeros.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Analysis/PathSensitive/Checkers/DivZeroChecker.h"
+
+using namespace clang;
+
+void *DivZeroChecker::getTag() {
+  static int x;
+  return &x;
+}
+
+void DivZeroChecker::PreVisitBinaryOperator(CheckerContext &C,
+                                            const BinaryOperator *B) {
+  BinaryOperator::Opcode Op = B->getOpcode();
+  if (Op != BinaryOperator::Div &&
+      Op != BinaryOperator::Rem &&
+      Op != BinaryOperator::DivAssign &&
+      Op != BinaryOperator::RemAssign)
+    return;
+
+  if (!B->getRHS()->getType()->isIntegerType() ||
+      !B->getRHS()->getType()->isScalarType())
+    return;
+
+  SVal Denom = C.getState()->getSVal(B->getRHS());
+  const DefinedSVal *DV = dyn_cast<DefinedSVal>(&Denom);
+
+  // Divide-by-undefined handled in the generic checking for uses of
+  // undefined values.
+  if (!DV)
+    return;
+
+  // Check for divide by zero.
+  ConstraintManager &CM = C.getConstraintManager();
+  const GRState *stateNotZero, *stateZero;
+  llvm::tie(stateNotZero, stateZero) = CM.AssumeDual(C.getState(), *DV);
+
+  if (stateZero && !stateNotZero) {
+    if (ExplodedNode *N = C.GenerateNode(B, stateZero, true)) {
+      if (!BT)
+        BT = new BuiltinBug(0, "Division by zero");
+
+      EnhancedBugReport *R = 
+        new EnhancedBugReport(*BT, BT->getDescription().c_str(), N);
+
+      R->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
+                           bugreporter::GetDenomExpr(N));
+
+      C.EmitReport(R);
+    }
+    return;
+  }
+
+  // If we get here, then the denom should not be zero. We abandon the implicit
+  // zero denom case for now.
+  if (stateNotZero != C.getState())
+    C.addTransition(C.GenerateNode(B, stateNotZero));
+}
-- 
cgit v1.1