From 9cedb8bb69b89b0f0c529937247a6a80cabdbaec Mon Sep 17 00:00:00 2001
From: dim <dim@FreeBSD.org>
Date: Fri, 21 Mar 2014 17:53:59 +0000
Subject: MFC 261991:

Upgrade our copy of llvm/clang to 3.4 release.  This version supports
all of the features in the current working draft of the upcoming C++
standard, provisionally named C++1y.

The code generator's performance is greatly increased, and the loop
auto-vectorizer is now enabled at -Os and -O2 in addition to -O3.  The
PowerPC backend has made several major improvements to code generation
quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ
backends have all seen major feature work.

Release notes for llvm and clang can be found here:
<http://llvm.org/releases/3.4/docs/ReleaseNotes.html>
<http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html>

MFC 262121 (by emaste):

Update lldb for clang/llvm 3.4 import

This commit largely restores the lldb source to the upstream r196259
snapshot with the addition of threaded inferior support and a few bug
fixes.

Specific upstream lldb revisions restored include:
   SVN      git
  181387  779e6ac
  181703  7bef4e2
  182099  b31044e
  182650  f2dcf35
  182683  0d91b80
  183862  15c1774
  183929  99447a6
  184177  0b2934b
  184948  4dc3761
  184954  007e7bc
  186990  eebd175

Sponsored by:	DARPA, AFRL

MFC 262186 (by emaste):

Fix mismerge in r262121

A break statement was lost in the merge.  The error had no functional
impact, but restore it to reduce the diff against upstream.

MFC 262303:

Pull in r197521 from upstream clang trunk (by rdivacky):

  Use the integrated assembler by default on FreeBSD/ppc and ppc64.

Requested by:	jhibbits

MFC 262611:

Pull in r196874 from upstream llvm trunk:

  Fix a crash that occurs when PWD is invalid.

  MCJIT needs to be able to run in hostile environments, even when PWD
  is invalid. There's no need to crash MCJIT in this case.

  The obvious fix is to simply leave MCContext's CompilationDir empty
  when PWD can't be determined. This way, MCJIT clients,
  and other clients that link with LLVM don't need a valid working directory.

  If we do want to guarantee valid CompilationDir, that should be done
  only for clients of getCompilationDir(). This is as simple as checking
  for an empty string.

  The only current use of getCompilationDir is EmitGenDwarfInfo, which
  won't conceivably run with an invalid working dir. However, in the
  purely hypothetically and untestable case that this happens, the
  AT_comp_dir will be omitted from the compilation_unit DIE.

This should help fix assertions occurring with ports-mgmt/tinderbox,
when it is using jails, and sometimes invalidates clang's current
working directory.

Reported by:	decke

MFC 262809:

Pull in r203007 from upstream clang trunk:

  Don't produce an alias between destructors with different calling conventions.

  Fixes pr19007.

(Please note that is an LLVM PR identifier, not a FreeBSD one.)

This should fix Firefox and/or libxul crashes (due to problems with
regparm/stdcall calling conventions) on i386.

Reported by:	multiple users on freebsd-current
PR:		bin/187103

MFC 263048:

Repair recognition of "CC" as an alias for the C++ compiler, since it
was silently broken by upstream for a Windows-specific use-case.

Apparently some versions of CMake still rely on this archaic feature...

Reported by:	rakuco

MFC 263049:

Garbage collect the old way of adding the libstdc++ include directories
in clang's InitHeaderSearch.cpp.  This has been superseded by David
Chisnall's commit in r255321.

Moreover, if libc++ is used, the libstdc++ include directories should
not be in the search path at all.  These directories are now only used
if you pass -stdlib=libstdc++.
---
 .../Checkers/IdenticalExprChecker.cpp              | 226 +++++++++++++++++++++
 1 file changed, 226 insertions(+)
 create mode 100644 contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp

(limited to 'contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp')

diff --git a/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
new file mode 100644
index 0000000..e696e38
--- /dev/null
+++ b/contrib/llvm/tools/clang/lib/StaticAnalyzer/Checkers/IdenticalExprChecker.cpp
@@ -0,0 +1,226 @@
+//== IdenticalExprChecker.cpp - Identical expression checker----------------==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This defines IdenticalExprChecker, a check that warns about
+/// unintended use of identical expressions.
+///
+/// It checks for use of identical expressions with comparison operators.
+///
+//===----------------------------------------------------------------------===//
+
+#include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+
+using namespace clang;
+using namespace ento;
+
+static bool isIdenticalExpr(const ASTContext &Ctx, const Expr *Expr1,
+                            const Expr *Expr2);
+//===----------------------------------------------------------------------===//
+// FindIdenticalExprVisitor - Identify nodes using identical expressions.
+//===----------------------------------------------------------------------===//
+
+namespace {
+class FindIdenticalExprVisitor
+    : public RecursiveASTVisitor<FindIdenticalExprVisitor> {
+public:
+  explicit FindIdenticalExprVisitor(BugReporter &B, AnalysisDeclContext *A)
+      : BR(B), AC(A) {}
+  // FindIdenticalExprVisitor only visits nodes
+  // that are binary operators.
+  bool VisitBinaryOperator(const BinaryOperator *B);
+
+private:
+  BugReporter &BR;
+  AnalysisDeclContext *AC;
+};
+} // end anonymous namespace
+
+bool FindIdenticalExprVisitor::VisitBinaryOperator(const BinaryOperator *B) {
+  BinaryOperator::Opcode Op = B->getOpcode();
+  if (!BinaryOperator::isComparisonOp(Op))
+    return true;
+  //
+  // Special case for floating-point representation.
+  //
+  // If expressions on both sides of comparison operator are of type float,
+  // then for some comparison operators no warning shall be
+  // reported even if the expressions are identical from a symbolic point of
+  // view. Comparison between expressions, declared variables and literals
+  // are treated differently.
+  //
+  // != and == between float literals that have the same value should NOT warn.
+  // < > between float literals that have the same value SHOULD warn.
+  //
+  // != and == between the same float declaration should NOT warn.
+  // < > between the same float declaration SHOULD warn.
+  //
+  // != and == between eq. expressions that evaluates into float
+  //           should NOT warn.
+  // < >       between eq. expressions that evaluates into float
+  //           should NOT warn.
+  //
+  const Expr *LHS = B->getLHS()->IgnoreParenImpCasts();
+  const Expr *RHS = B->getRHS()->IgnoreParenImpCasts();
+
+  const DeclRefExpr *DeclRef1 = dyn_cast<DeclRefExpr>(LHS);
+  const DeclRefExpr *DeclRef2 = dyn_cast<DeclRefExpr>(RHS);
+  const FloatingLiteral *FloatLit1 = dyn_cast<FloatingLiteral>(LHS);
+  const FloatingLiteral *FloatLit2 = dyn_cast<FloatingLiteral>(RHS);
+  if ((DeclRef1) && (DeclRef2)) {
+    if ((DeclRef1->getType()->hasFloatingRepresentation()) &&
+        (DeclRef2->getType()->hasFloatingRepresentation())) {
+      if (DeclRef1->getDecl() == DeclRef2->getDecl()) {
+        if ((Op == BO_EQ) || (Op == BO_NE)) {
+          return true;
+        }
+      }
+    }
+  } else if ((FloatLit1) && (FloatLit2)) {
+    if (FloatLit1->getValue().bitwiseIsEqual(FloatLit2->getValue())) {
+      if ((Op == BO_EQ) || (Op == BO_NE)) {
+        return true;
+      }
+    }
+  } else if (LHS->getType()->hasFloatingRepresentation()) {
+    // If any side of comparison operator still has floating-point
+    // representation, then it's an expression. Don't warn.
+    // Here only LHS is checked since RHS will be implicit casted to float.
+    return true;
+  } else {
+    // No special case with floating-point representation, report as usual.
+  }
+
+  if (isIdenticalExpr(AC->getASTContext(), B->getLHS(), B->getRHS())) {
+    PathDiagnosticLocation ELoc =
+        PathDiagnosticLocation::createOperatorLoc(B, BR.getSourceManager());
+    StringRef Message;
+    if (((Op == BO_EQ) || (Op == BO_LE) || (Op == BO_GE)))
+      Message = "comparison of identical expressions always evaluates to true";
+    else
+      Message = "comparison of identical expressions always evaluates to false";
+    BR.EmitBasicReport(AC->getDecl(), "Compare of identical expressions",
+                       categories::LogicError, Message, ELoc);
+  }
+  // We want to visit ALL nodes (subexpressions of binary comparison
+  // expressions too) that contains comparison operators.
+  // True is always returned to traverse ALL nodes.
+  return true;
+}
+/// \brief Determines whether two expression trees are identical regarding
+/// operators and symbols.
+///
+/// Exceptions: expressions containing macros or functions with possible side
+/// effects are never considered identical.
+/// Limitations: (t + u) and (u + t) are not considered identical.
+/// t*(u + t) and t*u + t*t are not considered identical.
+///
+static bool isIdenticalExpr(const ASTContext &Ctx, const Expr *Expr1,
+                            const Expr *Expr2) {
+  // If Expr1 & Expr2 are of different class then they are not
+  // identical expression.
+  if (Expr1->getStmtClass() != Expr2->getStmtClass())
+    return false;
+  // If Expr1 has side effects then don't warn even if expressions
+  // are identical.
+  if (Expr1->HasSideEffects(Ctx))
+    return false;
+  // Is expression is based on macro then don't warn even if
+  // the expressions are identical.
+  if ((Expr1->getExprLoc().isMacroID()) || (Expr2->getExprLoc().isMacroID()))
+    return false;
+  // If all children of two expressions are identical, return true.
+  Expr::const_child_iterator I1 = Expr1->child_begin();
+  Expr::const_child_iterator I2 = Expr2->child_begin();
+  while (I1 != Expr1->child_end() && I2 != Expr2->child_end()) {
+    const Expr *Child1 = dyn_cast<Expr>(*I1);
+    const Expr *Child2 = dyn_cast<Expr>(*I2);
+    if (!Child1 || !Child2 || !isIdenticalExpr(Ctx, Child1, Child2))
+      return false;
+    ++I1;
+    ++I2;
+  }
+  // If there are different number of children in the expressions, return false.
+  // (TODO: check if this is a redundant condition.)
+  if (I1 != Expr1->child_end())
+    return false;
+  if (I2 != Expr2->child_end())
+    return false;
+
+  switch (Expr1->getStmtClass()) {
+  default:
+    return false;
+  case Stmt::ArraySubscriptExprClass:
+  case Stmt::CStyleCastExprClass:
+  case Stmt::ImplicitCastExprClass:
+  case Stmt::ParenExprClass:
+    return true;
+  case Stmt::BinaryOperatorClass: {
+    const BinaryOperator *BinOp1 = dyn_cast<BinaryOperator>(Expr1);
+    const BinaryOperator *BinOp2 = dyn_cast<BinaryOperator>(Expr2);
+    return BinOp1->getOpcode() == BinOp2->getOpcode();
+  }
+  case Stmt::CharacterLiteralClass: {
+    const CharacterLiteral *CharLit1 = dyn_cast<CharacterLiteral>(Expr1);
+    const CharacterLiteral *CharLit2 = dyn_cast<CharacterLiteral>(Expr2);
+    return CharLit1->getValue() == CharLit2->getValue();
+  }
+  case Stmt::DeclRefExprClass: {
+    const DeclRefExpr *DeclRef1 = dyn_cast<DeclRefExpr>(Expr1);
+    const DeclRefExpr *DeclRef2 = dyn_cast<DeclRefExpr>(Expr2);
+    return DeclRef1->getDecl() == DeclRef2->getDecl();
+  }
+  case Stmt::IntegerLiteralClass: {
+    const IntegerLiteral *IntLit1 = dyn_cast<IntegerLiteral>(Expr1);
+    const IntegerLiteral *IntLit2 = dyn_cast<IntegerLiteral>(Expr2);
+    return IntLit1->getValue() == IntLit2->getValue();
+  }
+  case Stmt::FloatingLiteralClass: {
+    const FloatingLiteral *FloatLit1 = dyn_cast<FloatingLiteral>(Expr1);
+    const FloatingLiteral *FloatLit2 = dyn_cast<FloatingLiteral>(Expr2);
+    return FloatLit1->getValue().bitwiseIsEqual(FloatLit2->getValue());
+  }
+  case Stmt::MemberExprClass: {
+    const MemberExpr *MemberExpr1 = dyn_cast<MemberExpr>(Expr1);
+    const MemberExpr *MemberExpr2 = dyn_cast<MemberExpr>(Expr2);
+    return MemberExpr1->getMemberDecl() == MemberExpr2->getMemberDecl();
+  }
+  case Stmt::UnaryOperatorClass: {
+    const UnaryOperator *UnaryOp1 = dyn_cast<UnaryOperator>(Expr1);
+    const UnaryOperator *UnaryOp2 = dyn_cast<UnaryOperator>(Expr2);
+    if (UnaryOp1->getOpcode() != UnaryOp2->getOpcode())
+      return false;
+    return !UnaryOp1->isIncrementDecrementOp();
+  }
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// FindIdenticalExprChecker
+//===----------------------------------------------------------------------===//
+
+namespace {
+class FindIdenticalExprChecker : public Checker<check::ASTCodeBody> {
+public:
+  void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr,
+                        BugReporter &BR) const {
+    FindIdenticalExprVisitor Visitor(BR, Mgr.getAnalysisDeclContext(D));
+    Visitor.TraverseDecl(const_cast<Decl *>(D));
+  }
+};
+} // end anonymous namespace
+
+void ento::registerIdenticalExprChecker(CheckerManager &Mgr) {
+  Mgr.registerChecker<FindIdenticalExprChecker>();
+}
-- 
cgit v1.1