r209131 - [analyzer] Alpha and implicit checker lists, expand/collapse feature.

Anton Yartsev anton.yartsev at gmail.com
Mon May 19 08:04:55 PDT 2014


Author: ayartsev
Date: Mon May 19 10:04:55 2014
New Revision: 209131

URL: http://llvm.org/viewvc/llvm-project?rev=209131&view=rev
Log:
[analyzer] Alpha and implicit checker lists, expand/collapse feature.

The list of alpha and the list of implicit checkers added. An ability to expand/collapse long texts added. Markup fixed.

http://reviews.llvm.org/D3457

Added:
    cfe/trunk/www/analyzer/alpha_checks.html
    cfe/trunk/www/analyzer/images/expandcollapse/
    cfe/trunk/www/analyzer/images/expandcollapse/arrows_dark.gif   (with props)
    cfe/trunk/www/analyzer/images/expandcollapse/arrows_light.gif   (with props)
    cfe/trunk/www/analyzer/images/expandcollapse/ellipses_dark.gif   (with props)
    cfe/trunk/www/analyzer/images/expandcollapse/ellipses_light.gif   (with props)
    cfe/trunk/www/analyzer/implicit_checks.html
    cfe/trunk/www/analyzer/scripts/expandcollapse.js
Modified:
    cfe/trunk/www/analyzer/available_checks.html
    cfe/trunk/www/analyzer/checker_dev_manual.html
    cfe/trunk/www/analyzer/content.css
    cfe/trunk/www/analyzer/potential_checkers.html

Added: cfe/trunk/www/analyzer/alpha_checks.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/alpha_checks.html?rev=209131&view=auto
==============================================================================
--- cfe/trunk/www/analyzer/alpha_checks.html (added)
+++ cfe/trunk/www/analyzer/alpha_checks.html Mon May 19 10:04:55 2014
@@ -0,0 +1,848 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <title>Alpha Checks</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+  <script type="text/javascript" src="scripts/menu.js"></script>
+  <script type="text/javascript" src="scripts/expandcollapse.js"></script>
+  <style type="text/css">
+  tr:first-child { width:20%; }
+  </style>
+</head>
+<body onload="initExpandCollapse()">
+
+<div id="page">
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+<h1>Alpha Checkers</h1>
+Experimental checkers in addition to the <a href = "available_checks.html">
+Default Checkers</a>. These are checkers with known issues or limitations that
+keep them from being on by default. They are likely to have false positives.
+Bug reports are welcome but will likely not be investigated for some time.
+Patches welcome!
+<ul>
+<li><a href="#core_alpha_checkers">Core Alpha Checkers</a></li>
+<li><a href="#cplusplus_alpha_checkers">C++ Alpha Checkers</a></li>
+<li><a href="#deadcode_alpha_checkers">Dead Code Alpha Checkers</a></li>
+<li><a href="#osx_alpha_checkers">OS X Alpha Checkers</a></li>
+<li><a href="#security_alpha_checkers">Security Alpha Checkers</a></li>
+<li><a href="#unix_alpha_checkers">Unix Alpha Checkers</a></li>
+</ul>
+
+<!------------------------------ core alpha ----------------------------------->
+<h3 id="core_alpha_checkers">Core Alpha Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.BoolAssignment</span><span class="lang">
+(ObjC)</span><div class="descr">
+Warn about assigning non-{0,1} values to boolean variables.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  BOOL b = -1; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.CastSize</span><span class="lang">
+(C)</span><div class="descr">
+Check when casting a malloc'ed type T, whether the size is a multiple of the 
+size of T (Works only with <span class="name">unix.Malloc</span>
+or <span class="name">alpha.unix.MallocWithAnnotations</span> 
+checks enabled).</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int *x = (int *)malloc(11); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.CastToStruct</span><span class="lang">
+(C, C++)</span><div class="descr">
+Check for cast from non-struct pointer to struct pointer.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// C
+struct s {};
+
+void test(int *p) {
+  struct s *ps = (struct s *) p; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// C++
+class c {};
+
+void test(int *p) {
+  c *pc = (c *) p; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.FixedAddr</span><span class="lang">
+(C)</span><div class="descr">
+Check for assignment of a fixed address to a pointer.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int *p;
+  p = (int *) 0x10000; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.IdenticalExpr</span><span class="lang">
+(C, C++)</span><div class="descr">
+Warn about suspicious uses of identical expressions.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// C
+void test() {
+  int a = 5;
+  int b = a | 4 | a; // warn: identical expr on both sides
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// C++
+bool f(void);
+
+void test(bool b) {
+  int i = 10;
+  if (f()) { // warn: true and false branches are identical
+    do {
+      i--;
+    } while (f());
+  } else {
+    do {
+      i--;
+    } while (f());
+  }
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.PointerArithm</span><span class="lang">
+(C)</span><div class="descr">
+Check for pointer arithmetic on locations other than array 
+elements.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int x;
+  int *p;
+  p = &x + 1; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.PointerSub</span><span class="lang">
+(C)</span><div class="descr">
+Check for pointer subtractions on two pointers pointing to different memory 
+chunks.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int x, y;
+  int d = &y - &x; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.SizeofPtr</span><span class="lang">
+(C)</span><div class="descr">
+Warn about unintended use of <code>sizeof()</code> on pointer 
+expressions.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+struct s {};
+
+int test(struct s *p) {
+  return sizeof(p); 
+    // warn: sizeof(ptr) can produce an unexpected result
+}
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!--------------------------- cplusplus alpha --------------------------------->
+<h3 id="cplusplus_alpha_checkers">C++ Alpha Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.cplusplus.NewDeleteLeaks</span><span class="lang">
+(C++)</span><div class="descr">
+Check for memory leaks. Traces memory managed by <code>new</code>/<code>
+delete</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int *p = new int;
+} // warn
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.cplusplus.VirtualCall</span><span class="lang">
+(C++)</span><div class="descr">
+Check virtual member function calls during construction or 
+destruction.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+class A {
+public:
+  A() { 
+    f(); // warn
+  }
+  virtual void f();
+};
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+class A {
+public:
+  ~A() {
+    this->f(); // warn
+  }
+  virtual void f();
+};
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!--------------------------- dead code alpha --------------------------------->
+<h3 id="deadcode_alpha_checkers">Dead Code Alpha Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.deadcode.UnreachableCode</span><span class="lang">
+(C, C++, ObjC)</span><div class="descr">
+Check unreachable code.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// C
+int test() {
+  int x = 1;
+  while(x);
+  return x; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// C++
+void test() {
+  int a = 2;
+
+  while (a > 1)
+    a--;
+
+  if (a > 1)
+    a++; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// Objective-C
+void test(id x) {
+  return;
+  [x retain]; // warn
+}
+</pre></div></div></td></tr>
+</tbody></table>
+
+<!---------------------------- OS X alpha -------------------------------------->
+<h3 id="osx_alpha_checkers">OS X Alpha Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.osx.cocoa.Dealloc</span><span class="lang">
+(ObjC)</span><div class="descr">
+Warn about Objective-C classes that lack a correct implementation 
+of <code>-dealloc</code>.
+</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+ at interface MyObject : NSObject {
+  id _myproperty;  
+}
+ at end
+
+ at implementation MyObject // warn: lacks 'dealloc'
+ at end
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+ at interface MyObject : NSObject {}
+ at property(assign) id myproperty;
+ at end
+
+ at implementation MyObject // warn: does not send 'dealloc' to super
+- (void)dealloc {
+  self.myproperty = 0;
+}
+ at end
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+ at interface MyObject : NSObject {
+  id _myproperty;
+}
+ at property(retain) id myproperty;
+ at end
+
+ at implementation MyObject
+ at synthesize myproperty = _myproperty;
+  // warn: var was retained but wasn't released
+- (void)dealloc {
+  [super dealloc];
+}
+ at end
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+ at interface MyObject : NSObject {
+  id _myproperty;
+}
+ at property(assign) id myproperty;
+ at end
+
+ at implementation MyObject
+ at synthesize myproperty = _myproperty;
+  // warn: var wasn't retained but was released
+- (void)dealloc {
+  [_myproperty release];
+  [super dealloc];
+}
+ at end
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.osx.cocoa.DirectIvarAssignment</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check that Objective C properties follow the following rule: the property 
+should be set with the setter, not though a direct assignment.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+ at interface MyClass : NSObject {}
+ at property (readonly) id A;
+- (void) foo;
+ at end
+
+ at implementation MyClass
+- (void) foo {
+  _A = 0; // warn
+}
+ at end
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check for direct assignments to instance variables in the methods annotated 
+with <code>objc_no_direct_instance_variable_assignment</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+ at interface MyClass : NSObject {}
+ at property (readonly) id A;
+- (void) fAnnotated __attribute__((
+    annotate("objc_no_direct_instance_variable_assignment")));
+- (void) fNotAnnotated;
+ at end
+
+ at implementation MyClass
+- (void) fAnnotated {
+  _A = 0; // warn
+}
+- (void) fNotAnnotated {
+  _A = 0; // no warn
+}
+ at end
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.osx.cocoa.InstanceVariableInvalidation</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check that the invalidatable instance variables are invalidated in the methods
+annotated with <code>objc_instance_variable_invalidator</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+ at protocol Invalidation <NSObject>
+- (void) invalidate 
+  __attribute__((annotate("objc_instance_variable_invalidator")));
+ at end 
+
+ at interface InvalidationImpObj : NSObject <Invalidation>
+ at end
+
+ at interface SubclassInvalidationImpObj : InvalidationImpObj {
+  InvalidationImpObj *var;
+}
+- (void)invalidate;
+ at end
+
+ at implementation SubclassInvalidationImpObj
+- (void) invalidate {}
+ at end
+// warn: var needs to be invalidated or set to nil
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.osx.cocoa.MissingInvalidationMethod</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check that the invalidation methods are present in classes that contain 
+invalidatable instance variables.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+ at protocol Invalidation <NSObject>
+- (void)invalidate 
+  __attribute__((annotate("objc_instance_variable_invalidator")));
+ at end
+
+ at interface NeedInvalidation : NSObject <Invalidation>
+ at end
+
+ at interface MissingInvalidationMethodDecl : NSObject {
+  NeedInvalidation *Var; // warn
+}
+ at end
+
+ at implementation MissingInvalidationMethodDecl
+ at end
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!------------------------- security alpha ------------------------------------>
+<h3 id="security_alpha_checkers">Security Alpha Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.security.ArrayBound</span><span class="lang">
+(C)</span><div class="descr">
+Warn about buffer overflows (older checker).</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  char *s = "";
+  char c = s[1]; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+struct seven_words {
+  int c[7];
+};
+
+void test() {
+  struct seven_words a, *p;
+  p = &a;
+  p[0] = a;
+  p[1] = a;
+  p[2] = a; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// note: requires unix.Malloc or 
+// alpha.unix.MallocWithAnnotations checks enabled.
+void test() {
+  int *p = malloc(12);
+  p[3] = 4; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  char a[2];
+  int *b = (int*)a;
+  b[1] = 3; // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.security.ArrayBoundV2</span><span class="lang">
+(C)</span><div class="descr">
+Warn about buffer overflows (newer checker).</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  char *s = "";
+  char c = s[1]; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  int buf[100];
+  int *p = buf;
+  p = p + 99;
+  p[1] = 1; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// note: compiler has internal check for this.
+// Use -Wno-array-bounds to suppress compiler warning.
+void test() {
+  int buf[100][100];
+  buf[0][-1] = 1; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// note: requires alpha.security.taint check turned on.
+void test() {
+  char s[] = "abc";
+  int x = getchar();
+  char c = s[x]; // warn: index is tainted
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.security.MallocOverflow</span><span class="lang">
+(C)</span><div class="descr">
+Check for overflows in the arguments to <code>malloc()</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(int n) {
+  void *p = malloc(n * sizeof(int)); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.security.ReturnPtrRange</span><span class="lang">
+(C)</span><div class="descr">
+Check for an out-of-bound pointer being returned to callers.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+static int A[10];
+
+int *test() {
+  int *p = A + 10;
+  return p; // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+int test(void) {
+  int x;
+  return x; // warn: undefined or garbage returned
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.security.taint.TaintPropagation</span><span class="lang">
+(C)</span><div class="descr">
+Generate taint information used by other checkers.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  char x = getchar(); // 'x' marked as tainted
+  system(&x); // warn: untrusted data is passed to a system call
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// note: compiler internally checks if the second param to
+// sprintf is a string literal or not. 
+// Use -Wno-format-security to suppress compiler warning.
+void test() {
+  char s[10], buf[10];
+  fscanf(stdin, "%s", s); // 's' marked as tainted
+
+  sprintf(buf, s); // warn: untrusted data as a format string
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  size_t ts;
+  scanf("%zd", &ts); // 'ts' marked as tainted
+  int *p = (int *)malloc(ts * sizeof(int)); 
+    // warn: untrusted data as bufer size
+}
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!--------------------------- unix alpha -------------------------------------->
+<h3 id="unix_alpha_checkers">Unix Alpha Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.Chroot</span><span class="lang">
+(C)</span><div class="descr">
+Check improper use of <code>chroot</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void f();
+
+void test() {
+  chroot("/usr/local");
+  f(); // warn: no call of chdir("/") immediately after chroot
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.MallocWithAnnotations</span><span class="lang">
+(C)</span><div class="descr">
+Check for memory leaks, double free, and use-after-free problems. Assumes that
+all user-defined functions which might free a pointer are
+annotated.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
+
+void test() {
+  int *p = my_malloc(1);
+} // warn: potential leak
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
+void __attribute((ownership_takes(malloc, 1))) my_free(void *);
+
+void test() {
+  int *p = my_malloc(1);
+  my_free(p);
+  my_free(p); // warn: attempt to free released
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
+void __attribute((ownership_holds(malloc, 1))) my_hold(void *);
+
+void test() {
+  int *p = my_malloc(1);
+  my_hold(p);
+  free(p); // warn: attempt to free non-owned memory
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void __attribute((ownership_takes(malloc, 1))) my_free(void *);
+
+void test() {
+  int *p = malloc(1);
+  my_free(p);
+  *p = 1; // warn: use after free
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.PthreadLock</span><span class="lang">
+(C)</span><div class="descr">
+Simple lock -> unlock checker; applies to:<div class=functions>
+pthread_mutex_lock<br>
+pthread_rwlock_rdlock<br>
+pthread_rwlock_wrlock<br>
+lck_mtx_lock<br>
+lck_rw_lock_exclusive<br>
+lck_rw_lock_shared<br>
+pthread_mutex_trylock<br>
+pthread_rwlock_tryrdlock<br>
+pthread_rwlock_tryrwlock<br>
+lck_mtx_try_lock<br>
+lck_rw_try_lock_exclusive<br>
+lck_rw_try_lock_shared<br>
+pthread_mutex_unlock<br>
+pthread_rwlock_unlock<br>
+lck_mtx_unlock<br>
+lck_rw_done</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+pthread_mutex_t mtx;
+
+void test() {
+  pthread_mutex_lock(&mtx);
+  pthread_mutex_lock(&mtx); 
+    // warn: this lock has already been acquired
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+lck_mtx_t lck1, lck2;
+
+void test() {
+  lck_mtx_lock(&lck1);
+  lck_mtx_lock(&lck2);
+  lck_mtx_unlock(&lck1); 
+    // warn: this was not the most recently acquired lock
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+lck_mtx_t lck1, lck2;
+
+void test() {
+  if (lck_mtx_try_lock(&lck1) == 0)
+    return;
+
+  lck_mtx_lock(&lck2);
+  lck_mtx_unlock(&lck1);
+    // warn: this was not the most recently acquired lock
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.SimpleStream</span><span class="lang">
+(C)</span><div class="descr">
+Check for misuses of stream APIs:<div class=functions>
+fopen<br>
+fclose</div>(demo checker, the subject of the demo
+(<a href="http://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf">Slides</a>
+,<a href="http://llvm.org/devmtg/2012-11/videos/Zaks-Rose-Checker24Hours.mp4">Video</a>) 
+by Anna Zaks and Jordan Rose presented at the <a href="http://llvm.org/devmtg/2012-11/">
+2012 LLVM Developers' Meeting).</a></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  FILE *F = fopen("myfile.txt", "w");
+} // warn: opened file is never closed
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  FILE *F = fopen("myfile.txt", "w");
+
+  if (F)
+    fclose(F);
+
+  fclose(F); // warn: closing a previously closed file stream
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.Stream</span><span class="lang">
+(C)</span><div class="descr">
+Check stream handling functions:<div class=functions>fopen<br>
+tmpfile<br>
+fclose<br>
+fread<br>
+fwrite<br>
+fseek<br>
+ftell<br>
+rewind<br>
+fgetpos<br>
+fsetpos<br>
+clearerr<br>
+feof<br>
+ferror<br>
+fileno</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  FILE *p = fopen("foo", "r");
+} // warn: opened file is never closed
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  FILE *p = fopen("foo", "r");
+  fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
+  fclose(p); 
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  FILE *p = fopen("foo", "r");
+
+  if (p)
+    fseek(p, 1, 3);
+     // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
+
+  fclose(p); 
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  FILE *p = fopen("foo", "r");
+  fclose(p); 
+  fclose(p); // warn: already closed
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+  FILE *p = tmpfile();
+  ftell(p); // warn: stream pointer might be NULL
+  fclose(p);
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.cstring.BufferOverlap</span><span class="lang">
+(C)</span><div class="descr">
+Checks for overlap in two buffer arguments; applies to:<div class=functions>
+memcpy<br>
+mempcpy</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int a[4] = {0};
+  memcpy(a + 2, a + 1, 8); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.cstring.NotNullTerminated</span><span class="lang">
+(C)</span><div class="descr">
+Check for arguments which are not null-terminated strings; applies
+to:<div class=functions>
+strlen<br>
+strnlen<br>
+strcpy<br>
+strncpy<br>
+strcat<br>
+strncat</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  int y = strlen((char *)&test); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.cstring.OutOfBounds</span><span class="lang">
+(C)</span><div class="descr">
+Check for out-of-bounds access in string functions; applies
+to:<div class=functions>
+strncopy<br>
+strncat</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(char *y) {
+  char x[4];
+  if (strlen(y) == 4)
+    strncpy(x, y, 5); // warn
+}
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+</div> <!-- page -->
+</div> <!-- content -->
+</body>
+</html>

Modified: cfe/trunk/www/analyzer/available_checks.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/available_checks.html?rev=209131&r1=209130&r2=209131&view=diff
==============================================================================
--- cfe/trunk/www/analyzer/available_checks.html (original)
+++ cfe/trunk/www/analyzer/available_checks.html Mon May 19 10:04:55 2014
@@ -47,15 +47,9 @@ Experimental (Alpha) Checkers</a>.
 <h3 id="core_checkers">Core Checkers</h3>
 <table class="checkers">
 <colgroup><col class="namedescr"><col class="example"></colgroup>
-
-<thead>
-<tr><td><div class="namedescr">Name, Description</div></td>
-<td><div class="example">Example</div></td></tr>
-</thead>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
-
-
 <tr><td><div class="namedescr expandable"><span class="name">
 core.CallAndMessage</span><span class="lang">
 (C, C++, ObjC)</span><div class="descr">
@@ -370,11 +364,7 @@ int test() {
 <h3 id="cplusplus_checkers">C++ Checkers</h3>
 <table class="checkers">
 <colgroup><col class="namedescr"><col class="example"></colgroup>
-
-<thead>
-<tr><td><div class="namedescr">Name, Description</div></td>
-<td><div class="example">Example</div></td></tr>
-</thead>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
 <tr><td><div class="namedescr expandable"><span class="name">
@@ -437,11 +427,7 @@ void test() {
 <h3 id="deadcode_checkers">Dead Code Checkers</h3>
 <table class="checkers">
 <colgroup><col class="namedescr"><col class="example"></colgroup>
-
-<thead>
-<tr><td><div class="namedescr">Name, Description</div></td>
-<td><div class="example">Example</div></td></tr>
-</thead>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
 <tr><td><div class="namedescr expandable"><span class="name">
@@ -462,11 +448,7 @@ void test() {
 <h3 id="osx_checkers">OS X Checkers</h3>
 <table class="checkers">
 <colgroup><col class="namedescr"><col class="example"></colgroup>
-
-<thead>
-<tr><td><div class="namedescr">Name, Description</div></td>
-<td><div class="example">Example</div></td></tr>
-</thead>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
 <tr><td><div class="namedescr expandable"><span class="name">
@@ -877,11 +859,7 @@ void test() {
 <h3 id="security_checkers">Security Checkers</h3>
 <table class="checkers">
 <colgroup><col class="namedescr"><col class="example"></colgroup>
-
-<thead>
-<tr><td><div class="namedescr">Name, Description</div></td>
-<td><div class="example">Example</div></td></tr>
-</thead>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
 <tr><td><div class="namedescr expandable"><span class="name">
@@ -1021,11 +999,7 @@ void test() {
 <h3 id="unix_checkers">Unix Checkers</h3>
 <table class="checkers">
 <colgroup><col class="namedescr"><col class="example"></colgroup>
-
-<thead>
-<tr><td><div class="namedescr">Name, Description</div></td>
-<td><div class="example">Example</div></td></tr>
-</thead>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 
 <tbody>
 <tr><td><div class="namedescr expandable"><span class="name">

Modified: cfe/trunk/www/analyzer/checker_dev_manual.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/checker_dev_manual.html?rev=209131&r1=209130&r2=209131&view=diff
==============================================================================
--- cfe/trunk/www/analyzer/checker_dev_manual.html (original)
+++ cfe/trunk/www/analyzer/checker_dev_manual.html Mon May 19 10:04:55 2014
@@ -47,6 +47,7 @@ for developer guidelines and send your q
       <li><a href="#testing">Testing</a></li>
       <li><a href="#commands">Useful Commands/Debugging Hints</a></li>
       <li><a href="#additioninformation">Additional Sources of Information</a></li>
+      <li><a href="#links">Useful Links</a></li>
     </ul>
 
 <h2 id=start>Getting Started</h2>
@@ -605,6 +606,11 @@ href="http://llvm.org/devmtg/2012-11/vid
 are available.
 </ul>
 
+<h2 id=links>Useful Links</h2>
+<ul>
+<li>The list of <a href="implicit_checks.html">Implicit Checkers</a></li>
+</ul>
+
 </div>
 </div>
 </body>

Modified: cfe/trunk/www/analyzer/content.css
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/content.css?rev=209131&r1=209130&r2=209131&view=diff
==============================================================================
--- cfe/trunk/www/analyzer/content.css (original)
+++ cfe/trunk/www/analyzer/content.css Mon May 19 10:04:55 2014
@@ -84,16 +84,17 @@ table.checkers td.aligned { text-align:
 table.checkers col.namedescr { width: 45% }
 table.checkers col.example { width: 55% }
 table.checkers col.progress { width: 84px }
-table.checkers thead div.example,
+table.checkers thead td,
 table.checkers div.namedescr,
 table.checkers div.exampleContainer { overflow: hidden; padding: 5px 8px 10px 8px }
 /* table.checkers tbody div.example { font-family: monospace; white-space: pre } */
 table.checkers div.example { border-top:1px #cccccc dashed; width:100%; padding-top: 5px; margin-top: 5px }
-table.checkers tbody div.example:first-child { border-top:none; padding-top: 0px; margin-top: 0px }
+table.checkers div.example:first-child { border-top:none; padding-top: 0px; margin-top: 0px }
 table.checkers span.name { font-weight: bold }
 table.checkers span.lang { font-weight: bold; padding-left: 7px; /* display:block; */ }
 table.checkers div.descr { margin-top:7px }
 table.checkers div.functions { margin-top: 2px; font-style: italic; font-size: 90%; color:#00B }
 table.checkers pre { margin: 1px; font-size: 100%; word-wrap: break-word }
 table.checkers p { margin: 10px 0px 0px 0px; }
+table.checkers ul, li { margin: 0 }
 

Added: cfe/trunk/www/analyzer/images/expandcollapse/arrows_dark.gif
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/images/expandcollapse/arrows_dark.gif?rev=209131&view=auto
==============================================================================
Binary file - no diff available.

Propchange: cfe/trunk/www/analyzer/images/expandcollapse/arrows_dark.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: cfe/trunk/www/analyzer/images/expandcollapse/arrows_light.gif
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/images/expandcollapse/arrows_light.gif?rev=209131&view=auto
==============================================================================
Binary file - no diff available.

Propchange: cfe/trunk/www/analyzer/images/expandcollapse/arrows_light.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: cfe/trunk/www/analyzer/images/expandcollapse/ellipses_dark.gif
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/images/expandcollapse/ellipses_dark.gif?rev=209131&view=auto
==============================================================================
Binary file - no diff available.

Propchange: cfe/trunk/www/analyzer/images/expandcollapse/ellipses_dark.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: cfe/trunk/www/analyzer/images/expandcollapse/ellipses_light.gif
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/images/expandcollapse/ellipses_light.gif?rev=209131&view=auto
==============================================================================
Binary file - no diff available.

Propchange: cfe/trunk/www/analyzer/images/expandcollapse/ellipses_light.gif
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: cfe/trunk/www/analyzer/implicit_checks.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/implicit_checks.html?rev=209131&view=auto
==============================================================================
--- cfe/trunk/www/analyzer/implicit_checks.html (added)
+++ cfe/trunk/www/analyzer/implicit_checks.html Mon May 19 10:04:55 2014
@@ -0,0 +1,165 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+          "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+  <title>Implicit Checks</title>
+  <link type="text/css" rel="stylesheet" href="menu.css">
+  <link type="text/css" rel="stylesheet" href="content.css">
+  <script type="text/javascript" src="scripts/menu.js"></script>
+  <script type="text/javascript" src="scripts/expandcollapse.js"></script>
+  <style type="text/css">
+  tr:first-child { width:20%; }
+  </style>
+</head>
+<body onload="initExpandCollapse()">
+
+<div id="page">
+<!--#include virtual="menu.html.incl"-->
+
+<div id="content">
+<h1>Implicit Checkers</h1>
+Even though the implicit checkers do not produce any warnings, they are used to 
+support the analyzer core and model known APIs. See also 
+<a href = "available_checks.html">Default Checkers</a>
+and <a href = "alpha_checks.html">Experimental (Alpha) Checkers</a>.
+<ul>
+<li><a href="#core_implicit_checkers">Core Implicit Checkers</a></li>
+<li><a href="#osx_implicit_checkers">OS X Implicit Checkers</a></li>
+</ul>
+
+<!------------------------------- core implicit ------------------------------->
+<h3 id="core_implicit_checkers">Core Implicit Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+core.DynamicTypePropagation</span><span class="lang">
+(C++, ObjC)</span><div class="descr">
+Generate dynamic type information.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// C++
+class A {
+public:
+  A(int x) {}
+  virtual int foo();
+};
+
+class B: public A {
+public:
+  B()
+  :A(foo()) 
+  // DynamicTypeInfo for 'this' rigion will wrap type 'A'
+  // unless the base constructor call expression is processed
+  {} 
+  virtual int foo();
+};
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// Objective-C
+ at interface MyClass : NSObject {}
+ at end
+
+ at implementation MyClass
++ (void)foo {
+  MyClass *x = [[self alloc] init];
+  // DynamicTypeInfo from a cast: from 'id' to 'MyClass *'
+}
+ at end
+
+void test() {
+  MyClass *x = [MyClass alloc];
+  // DynamicTypeInfo from a call to alloc:
+  // from 'id' to 'MyClass *'
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+core.builtin.BuiltinFunctions</span><span class="lang">
+(C)</span><div class="descr">
+Evaluate compiler builtin functions (e.g., <code>alloca()</code>)</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(int x) {
+  int *p = (int *)__builtin_alloca(8);
+    // evaluates to AllocaRegion
+
+  if(__builtin_expect(x > 10, 0)) // evaluates to 'x > 10'
+    x = 0;
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+core.builtin.NoReturnFunctions</span><span class="lang">
+(C, ObjC)</span><div class="descr">
+Evaluate "panic" functions that are known to not return to the caller.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+// C
+void test() {
+  panic(); // generate sink
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+// Objective-C
+ at interface MyObj : NSObject {}
+- (void)foo;
+ at end
+
+ at implementation MyObj
+- (void)foo {
+  [[NSAssertionHandler currentHandler] handleFailureInMethod:_cmd 
+                                       object:self 
+                                       file:(@"somefile.m") 
+                                       lineNumber:1 
+                                       description:(@"some text")];
+    // generate sink
+}
+ at end
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!---------------------------- OS X implicit ---------------------------------->
+<h3 id="osx_implicit_checkers">OS X Implicit Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.Loops</span><span class="lang">
+(ObjC)</span><div class="descr">
+Improved modeling of loops using Cocoa collection types.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+  id x;
+  for (x in [NSArray testObject]) { 
+    // assume the value of 'x' is non-nil
+  }
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.NonNilReturnValue</span><span class="lang">
+(ObjC)</span><div class="descr">
+Model the APIs that are guaranteed to return a non-nil value.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(NSArray *A) {
+  id subscriptObj = A[1]; // assume the value is non-nil
+}
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+</div> <!-- page -->
+</div> <!-- content -->
+</body>
+</html>

Modified: cfe/trunk/www/analyzer/potential_checkers.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/potential_checkers.html?rev=209131&r1=209130&r2=209131&view=diff
==============================================================================
--- cfe/trunk/www/analyzer/potential_checkers.html (original)
+++ cfe/trunk/www/analyzer/potential_checkers.html Mon May 19 10:04:55 2014
@@ -5,9 +5,10 @@
   <title>List of potential checkers</title>
   <link type="text/css" rel="stylesheet" href="content.css">
   <link type="text/css" rel="stylesheet" href="menu.css">
+  <script type="text/javascript" src="scripts/expandcollapse.js"></script>
   <script type="text/javascript" src="scripts/menu.js"></script>
 </head>
-<body>
+<body onload="initExpandCollapse()">
 
 <div id="page">
 
@@ -470,11 +471,22 @@ int i = *p; // warn
 <td class="aligned"></td></tr>
 
 
-<!--<tr><td><div class="namedescr expandable"><span class="name">
+<tr><td><div class="namedescr expandable"><span class="name">
 undefbehavior.DeadReferenced</span><span class="lang">
 (C++)</span><div class="descr">
-Undefined behavior: the following usage of the pointer to the object whose 
-lifetime has ended can result in undefined behavior.
+Undefined behavior: the following usage of the pointer to the object whose
+lifetime has ended can result in undefined behavior:<br>
+The object will be or was of a class type with a non-trivial destructor and
+<ul><li>the pointer is used as the operand of a delete-expression</li></ul>
+The object will be or was of a non-POD class type (C++11: any class type) and
+<ul><li>the pointer is used to access a non-static data member or call a
+non-static member function of the object</li>
+<li>the pointer is implicitly converted to a pointer to a base class
+type</li>
+<li>the pointer is used as the operand of a <code>static_cast</code> (except
+when the conversion is to <code>void*</code>, or to <code>void*</code> and 
+subsequently to <code>char*</code>, or <code>unsigned char*</code>)</li>
+<li>the pointer is used as the operand of a <code>dynamic_cast</code></li></ul>
 <p>Source: C++03 3.8p5, p7; C++11 3.8p5, p7.</p></div></div></td>
 <td><div class="exampleContainer expandable">
 <div class="example"><pre>
@@ -482,15 +494,15 @@ lifetime has ended can result in undefin
 
 class A {
 public:
-  int i;
+  ~A();
 };
 
 class B : public A {};
 
-int test() {
-  B *b = new B;
-  new(b) A;
-  return b->i; // warn
+void test() {
+  A *a = new A;
+  new(a) B;
+  delete a; // warn
 }
 </pre></div>
 <div class="example"><pre>
@@ -498,90 +510,74 @@ int test() {
 
 class A {
 public:
-  void f() {};
+  ~A();
 };
 
-class B : public A {};
+class B {};
 
 void test() {
-  B *b = new B;
-  new(b) A;
-  b->f(); // warn
+  A *a = new A;
+  new(a) B;
+  a->~A();
 }
 </pre></div>
 <div class="example"><pre>
 #include <new>
 
-class A {};
+class A {
+public:
+  ~A();
+};
 
 class B : public A {};
 
-A* test() {
-  B *b = new B;
-  new(b) A;
-  static_cast<A*>(b); // warn
-}
-</pre></div>
-<div class="example"><pre>
-#include <new>
-
-class A {};
+class C {};
 
-class B : public A {};
+void f(A*);
 
-A* test() {
+void test() {
   B *b = new B;
-  new(b) A;
-  dynamic_cast<A*>(b); // warn
+  new(b) C;
+  f(b); // warn
 }
 </pre></div>
 <div class="example"><pre>
 #include <new>
 
-class A {};
+class A {
+public:
+  ~A();
+};
 
 class B : public A {};
 
-A* test() {
-  B *b = new B;
-  new(b) A;
-  dynamic_cast<A*>(b); // warn
-}
-</pre></div>
-<div class="example"><pre>
-#include <new>
+class C {};
 
-class A {};
-
-class B : public A {};
-
-void test() {
+A* test() {
   B *b = new B;
-  new(b) A;
-  delete b; // warn
+  new(b) C;
+  return static_cast<A*>(b); // warn
 }
 </pre></div>
 <div class="example"><pre>
-// C++11
 #include <new>
 
 class A {
 public:
-  int i;
+  ~A();
 };
 
-class B : public A {
-public:
-  ~B() {};
-};
+class B : public A {};
 
-int test() {
-  A *a = new A;
-  new(a) B;
-  return a->i; // warn
+class C {};
+
+A* test() {
+  B *b = new B;
+  new(b) C;
+  return dynamic_cast<A*>(b); // warn
 }
 </pre></div></div></td>
-<td class="aligned"></td></tr>-->
+<td class="aligned"></td></tr>
 
 
 <tr><td><div class="namedescr expandable"><span class="name">

Added: cfe/trunk/www/analyzer/scripts/expandcollapse.js
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/scripts/expandcollapse.js?rev=209131&view=auto
==============================================================================
--- cfe/trunk/www/analyzer/scripts/expandcollapse.js (added)
+++ cfe/trunk/www/analyzer/scripts/expandcollapse.js Mon May 19 10:04:55 2014
@@ -0,0 +1,191 @@
+// expand/collapse button (expander) is added if height of a cell content 
+// exceeds CLIP_HEIGHT px.
+var CLIP_HEIGHT = 135;
+
+// Height in pixels of an expander image.
+var EXPANDER_HEIGHT = 13;
+
+// Path to images for an expander.
+var imgPath = "./images/expandcollapse/";
+
+// array[group][cell] of { 'height', 'expanded' }.
+// group: a number; cells of the same group belong to the same table row.
+// cell: a number; unique index of a cell in a group.
+// height: a number, px; original height of a cell in a table.
+// expanded: boolean; is a cell expanded or collapsed?
+var CellsInfo = [];
+
+// Extracts group and cell indices from an id of the form identifier_group_cell.
+function getCellIdx(id) {
+  var idx = id.substr(id.indexOf("_") + 1).split("_");
+  return { 'group': idx[0], 'cell': idx[1] };
+}
+
+// Returns { 'height', 'expanded' } info for a cell with a given id.
+function getCellInfo(id) { 
+  var idx = getCellIdx(id); 
+  return CellsInfo[idx.group][idx.cell]; 
+}
+
+// Initialization, add nodes, collect info.
+function initExpandCollapse() {
+  if (!document.getElementById)
+    return;
+
+  var groupCount = 0;
+
+  // Examine all table rows in the document.
+  var rows = document.body.getElementsByTagName("tr");
+  for (var i=0; i<rows.length; i+=1) {
+
+    var cellCount=0, newGroupCreated = false;
+
+    // Examine all divs in a table row.
+    var divs = rows[i].getElementsByTagName("div");
+    for (var j=0; j<divs.length; j+=1) {
+
+      var expandableDiv = divs[j];
+
+      if (expandableDiv.className.indexOf("expandable") == -1)
+        continue;
+
+      if (expandableDiv.offsetHeight <= CLIP_HEIGHT)
+        continue;
+
+      // We found a div wrapping a cell content whose height exceeds 
+      // CLIP_HEIGHT.
+      var originalHeight = expandableDiv.offsetHeight;
+      // Unique postfix for ids for generated nodes for a given cell.
+      var idxStr = "_" + groupCount + "_" + cellCount;
+      // Create an expander and an additional wrapper for a cell content.
+      //
+      //                                --- expandableDiv ----
+      //  --- expandableDiv ---         | ------ data ------ |
+      //  |    cell content   |   ->    | |  cell content  | | 
+      //  ---------------------         | ------------------ |
+      //                                | ---- expander ---- |
+      //                                ----------------------
+      var data = document.createElement("div");
+      data.className = "data";
+      data.id = "data" + idxStr;
+      data.innerHTML = expandableDiv.innerHTML;
+      with (data.style) { height = (CLIP_HEIGHT - EXPANDER_HEIGHT) + "px";
+                          overflow = "hidden" }
+
+      var expander = document.createElement("img");
+      with (expander.style) { display = "block"; paddingTop = "5px"; }
+      expander.src = imgPath + "ellipses_light.gif";
+      expander.id = "expander" + idxStr;
+
+      // Add mouse calbacks to expander.
+      expander.onclick = function() {
+        expandCollapse(this.id);
+        // Hack for Opera - onmouseout callback is not invoked when page 
+        // content changes dinamically and mouse pointer goes out of an element.
+        this.src = imgPath + 
+                   (getCellInfo(this.id).expanded ? "arrows_light.gif"
+                                                  : "ellipses_light.gif");
+      }
+      expander.onmouseover = function() { 
+        this.src = imgPath + 
+                   (getCellInfo(this.id).expanded ? "arrows_dark.gif"
+                                                  : "ellipses_dark.gif");
+      }
+      expander.onmouseout = function() { 
+        this.src = imgPath + 
+                   (getCellInfo(this.id).expanded ? "arrows_light.gif"
+                                                  : "ellipses_light.gif");
+      }
+
+      expandableDiv.innerHTML = "";
+      expandableDiv.appendChild(data);
+      expandableDiv.appendChild(expander);
+      expandableDiv.style.height = CLIP_HEIGHT + "px";
+      expandableDiv.id = "cell"+ idxStr;
+
+      // Keep original cell height and its ecpanded/cpllapsed state.
+      if (!newGroupCreated) {
+        CellsInfo[groupCount] = [];
+        newGroupCreated = true;
+      }
+      CellsInfo[groupCount][cellCount] = { 'height' : originalHeight,
+                                           'expanded' : false };
+      cellCount += 1;
+    }
+    groupCount += newGroupCreated ? 1 : 0;
+  }
+}
+
+function isElemTopVisible(elem) {
+  var body = document.body,
+      html = document.documentElement,
+      // Calculate expandableDiv absolute Y coordinate from the top of body.
+      bodyRect = body.getBoundingClientRect(),
+      elemRect = elem.getBoundingClientRect(),
+      elemOffset = Math.floor(elemRect.top - bodyRect.top),
+      // Calculate the absoute Y coordinate of visible area.
+      scrollTop = html.scrollTop || body && body.scrollTop || 0;
+  scrollTop -= html.clientTop; // IE<8
+
+  
+  if (elemOffset < scrollTop)
+    return false;
+
+  return true;
+}
+
+// Invoked when an expander is pressed; expand/collapse a cell.
+function expandCollapse(id) {
+  var cellInfo = getCellInfo(id);
+  var idx = getCellIdx(id);
+
+  // New height of a row.
+  var newHeight;
+  // Smart page scrolling may be done after collapse.
+  var mayNeedScroll;
+
+  if (cellInfo.expanded) {
+    // Cell is expanded - collapse the row height to CLIP_HEIGHT.
+    newHeight = CLIP_HEIGHT;
+    mayNeedScroll = true;
+  }
+  else {
+    // Cell is collapsed - expand the row height to the cells original height.
+    newHeight = cellInfo.height;
+    mayNeedScroll = false;
+  }
+
+  // Update all cells (height and expanded/collapsed state) in a row according 
+  // to the new height of the row.
+  for (var i = 0; i < CellsInfo[idx.group].length; i++) {
+    var idxStr = "_" + idx.group + "_" + i;
+    var expandableDiv = document.getElementById("cell" + idxStr);
+    expandableDiv.style.height = newHeight + "px";
+    var data = document.getElementById("data" + idxStr);
+    var expander = document.getElementById("expander" + idxStr);
+    var state = CellsInfo[idx.group][i];
+
+    if (state.height > newHeight) {
+      // Cell height exceeds row height - collapse a cell.
+      data.style.height = (newHeight - EXPANDER_HEIGHT) + "px";
+      expander.src = imgPath + "ellipses_light.gif";
+      CellsInfo[idx.group][i].expanded = false;
+    } else {
+      // Cell height is less then or equal to row height - expand a cell.
+      data.style.height = "";
+      expander.src = imgPath + "arrows_light.gif";
+      CellsInfo[idx.group][i].expanded = true;
+    }
+  }
+
+  if (mayNeedScroll) {
+    var idxStr = "_" + idx.group + "_" + idx.cell;
+    var clickedExpandableDiv = document.getElementById("cell" + idxStr);
+    // Scroll page up if a row is collapsed and the rows top is above the 
+    // viewport. The amount of scroll is the difference between a new and old 
+    // row height.
+    if (!isElemTopVisible(clickedExpandableDiv)) {
+      window.scrollBy(0, newHeight - cellInfo.height);
+    }
+  }
+}





More information about the cfe-commits mailing list