Merge remote-tracking branch 'origin/swift-3.1-branch' into stable

* origin/swift-3.1-branch:
  [analyzer][scan-build-py] subprocess output handling reviewed in clang module
  [www] Add nullability questions to analyzer FAQ.
  [www] Add analyzer FAQ about not releasing ivars in -dealloc.
  [analyzer] Update alpha and potential checker documentation, esp. alpha.valist
diff --git a/tools/scan-build-py/libscanbuild/analyze.py b/tools/scan-build-py/libscanbuild/analyze.py
index 0ed0aef..244c34b 100644
--- a/tools/scan-build-py/libscanbuild/analyze.py
+++ b/tools/scan-build-py/libscanbuild/analyze.py
@@ -269,6 +269,9 @@
     """ Validation done by the parser itself, but semantic check still
     needs to be done. This method is doing that. """
 
+    # Make plugins always a list. (It might be None when not specified.)
+    args.plugins = args.plugins if args.plugins else []
+
     if args.help_checkers_verbose:
         print_checkers(get_checkers(args.clang, args.plugins))
         parser.exit()
diff --git a/tools/scan-build-py/libscanbuild/clang.py b/tools/scan-build-py/libscanbuild/clang.py
index 0c3454b..833e77d 100644
--- a/tools/scan-build-py/libscanbuild/clang.py
+++ b/tools/scan-build-py/libscanbuild/clang.py
@@ -15,142 +15,143 @@
 
 __all__ = ['get_version', 'get_arguments', 'get_checkers']
 
+# regex for activated checker
+ACTIVE_CHECKER_PATTERN = re.compile(r'^-analyzer-checker=(.*)$')
 
-def get_version(cmd):
-    """ Returns the compiler version as string. """
 
-    lines = subprocess.check_output([cmd, '-v'], stderr=subprocess.STDOUT)
-    return lines.decode('ascii').splitlines()[0]
+def get_version(clang):
+    """ Returns the compiler version as string.
+
+    :param clang:   the compiler we are using
+    :return:        the version string printed to stderr """
+
+    output = subprocess.check_output([clang, '-v'], stderr=subprocess.STDOUT)
+    return output.decode('utf-8').splitlines()[0]
 
 
 def get_arguments(command, cwd):
     """ Capture Clang invocation.
 
-    This method returns the front-end invocation that would be executed as
-    a result of the given driver invocation. """
-
-    def lastline(stream):
-        last = None
-        for line in stream:
-            last = line
-        if last is None:
-            raise Exception("output not found")
-        return last
+    :param command: the compilation command
+    :param cwd:     the current working directory
+    :return:        the detailed front-end invocation command """
 
     cmd = command[:]
     cmd.insert(1, '-###')
     logging.debug('exec command in %s: %s', cwd, ' '.join(cmd))
-    child = subprocess.Popen(cmd,
-                             cwd=cwd,
-                             universal_newlines=True,
-                             stdout=subprocess.PIPE,
-                             stderr=subprocess.STDOUT)
-    line = lastline(child.stdout)
-    child.stdout.close()
-    child.wait()
-    if child.returncode == 0:
-        if re.search(r'clang(.*): error:', line):
-            raise Exception(line)
-        return decode(line)
-    else:
-        raise Exception(line)
+
+    output = subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.STDOUT)
+    # The relevant information is in the last line of the output.
+    # Don't check if finding last line fails, would throw exception anyway.
+    last_line = output.decode('utf-8').splitlines()[-1]
+    if re.search(r'clang(.*): error:', last_line):
+        raise Exception(last_line)
+    return decode(last_line)
 
 
 def get_active_checkers(clang, plugins):
-    """ To get the default plugins we execute Clang to print how this
-    compilation would be called.
+    """ Get the active checker list.
 
-    For input file we specify stdin and pass only language information. """
+    :param clang:   the compiler we are using
+    :param plugins: list of plugins which was requested by the user
+    :return:        list of checker names which are active
 
-    def checkers(language):
+    To get the default checkers we execute Clang to print how this
+    compilation would be called. And take out the enabled checker from the
+    arguments. For input file we specify stdin and pass only language
+    information. """
+
+    def get_active_checkers_for(language):
         """ Returns a list of active checkers for the given language. """
 
-        load = [elem
-                for plugin in plugins
-                for elem in ['-Xclang', '-load', '-Xclang', plugin]]
-        cmd = [clang, '--analyze'] + load + ['-x', language, '-']
-        pattern = re.compile(r'^-analyzer-checker=(.*)$')
-        return [pattern.match(arg).group(1)
-                for arg in get_arguments(cmd, '.') if pattern.match(arg)]
+        load_args = [arg
+                     for plugin in plugins
+                     for arg in ['-Xclang', '-load', '-Xclang', plugin]]
+        cmd = [clang, '--analyze'] + load_args + ['-x', language, '-']
+        return [ACTIVE_CHECKER_PATTERN.match(arg).group(1)
+                for arg in get_arguments(cmd, '.')
+                if ACTIVE_CHECKER_PATTERN.match(arg)]
 
     result = set()
     for language in ['c', 'c++', 'objective-c', 'objective-c++']:
-        result.update(checkers(language))
-    return result
+        result.update(get_active_checkers_for(language))
+    return frozenset(result)
+
+
+def is_active(checkers):
+    """ Returns a method, which classifies the checker active or not,
+    based on the received checker name list. """
+
+    def predicate(checker):
+        """ Returns True if the given checker is active. """
+
+        return any(pattern.match(checker) for pattern in predicate.patterns)
+
+    predicate.patterns = [re.compile(r'^' + a + r'(\.|$)') for a in checkers]
+    return predicate
+
+
+def parse_checkers(stream):
+    """ Parse clang -analyzer-checker-help output.
+
+    Below the line 'CHECKERS:' are there the name description pairs.
+    Many of them are in one line, but some long named checker has the
+    name and the description in separate lines.
+
+    The checker name is always prefixed with two space character. The
+    name contains no whitespaces. Then followed by newline (if it's
+    too long) or other space characters comes the description of the
+    checker. The description ends with a newline character.
+
+    :param stream:  list of lines to parse
+    :return:        generator of tuples
+
+    (<checker name>, <checker description>) """
+
+    lines = iter(stream)
+    # find checkers header
+    for line in lines:
+        if re.match(r'^CHECKERS:', line):
+            break
+    # find entries
+    state = None
+    for line in lines:
+        if state and not re.match(r'^\s\s\S', line):
+            yield (state, line.strip())
+            state = None
+        elif re.match(r'^\s\s\S+$', line.rstrip()):
+            state = line.strip()
+        else:
+            pattern = re.compile(r'^\s\s(?P<key>\S*)\s*(?P<value>.*)')
+            match = pattern.match(line.rstrip())
+            if match:
+                current = match.groupdict()
+                yield (current['key'], current['value'])
 
 
 def get_checkers(clang, plugins):
     """ Get all the available checkers from default and from the plugins.
 
-    clang -- the compiler we are using
-    plugins -- list of plugins which was requested by the user
+    :param clang:   the compiler we are using
+    :param plugins: list of plugins which was requested by the user
+    :return:        a dictionary of all available checkers and its status
 
-    This method returns a dictionary of all available checkers and status.
-
-    {<plugin name>: (<plugin description>, <is active by default>)} """
-
-    plugins = plugins if plugins else []
-
-    def parse_checkers(stream):
-        """ Parse clang -analyzer-checker-help output.
-
-        Below the line 'CHECKERS:' are there the name description pairs.
-        Many of them are in one line, but some long named plugins has the
-        name and the description in separate lines.
-
-        The plugin name is always prefixed with two space character. The
-        name contains no whitespaces. Then followed by newline (if it's
-        too long) or other space characters comes the description of the
-        plugin. The description ends with a newline character. """
-
-        # find checkers header
-        for line in stream:
-            if re.match(r'^CHECKERS:', line):
-                break
-        # find entries
-        state = None
-        for line in stream:
-            if state and not re.match(r'^\s\s\S', line):
-                yield (state, line.strip())
-                state = None
-            elif re.match(r'^\s\s\S+$', line.rstrip()):
-                state = line.strip()
-            else:
-                pattern = re.compile(r'^\s\s(?P<key>\S*)\s*(?P<value>.*)')
-                match = pattern.match(line.rstrip())
-                if match:
-                    current = match.groupdict()
-                    yield (current['key'], current['value'])
-
-    def is_active(actives, entry):
-        """ Returns true if plugin name is matching the active plugin names.
-
-        actives -- set of active plugin names (or prefixes).
-        entry -- the current plugin name to judge.
-
-        The active plugin names are specific plugin names or prefix of some
-        names. One example for prefix, when it say 'unix' and it shall match
-        on 'unix.API', 'unix.Malloc' and 'unix.MallocSizeof'. """
-
-        return any(re.match(r'^' + a + r'(\.|$)', entry) for a in actives)
-
-    actives = get_active_checkers(clang, plugins)
+    {<checker name>: (<checker description>, <is active by default>)} """
 
     load = [elem for plugin in plugins for elem in ['-load', plugin]]
     cmd = [clang, '-cc1'] + load + ['-analyzer-checker-help']
 
     logging.debug('exec command: %s', ' '.join(cmd))
-    child = subprocess.Popen(cmd,
-                             universal_newlines=True,
-                             stdout=subprocess.PIPE,
-                             stderr=subprocess.STDOUT)
+    output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
+    lines = output.decode('utf-8').splitlines()
+
+    is_active_checker = is_active(get_active_checkers(clang, plugins))
+
     checkers = {
-        k: (v, is_active(actives, k))
-        for k, v in parse_checkers(child.stdout)
+        name: (description, is_active_checker(name))
+        for name, description in parse_checkers(lines)
     }
-    child.stdout.close()
-    child.wait()
-    if child.returncode == 0 and len(checkers):
-        return checkers
-    else:
+    if not checkers:
         raise Exception('Could not query Clang for available checkers.')
+
+    return checkers
diff --git a/tools/scan-build-py/tests/unit/test_clang.py b/tools/scan-build-py/tests/unit/test_clang.py
index 04414a8..eef8c26 100644
--- a/tools/scan-build-py/tests/unit/test_clang.py
+++ b/tools/scan-build-py/tests/unit/test_clang.py
@@ -8,9 +8,19 @@
 import libscanbuild.clang as sut
 import unittest
 import os.path
+import sys
 
 
-class GetClangArgumentsTest(unittest.TestCase):
+class ClangGetVersion(unittest.TestCase):
+    def test_get_version_is_not_empty(self):
+        self.assertTrue(sut.get_version('clang'))
+
+    def test_get_version_throws(self):
+        with self.assertRaises(OSError):
+            sut.get_version('notexists')
+
+
+class ClangGetArgumentsTest(unittest.TestCase):
     def test_get_clang_arguments(self):
         with libear.TemporaryDirectory() as tmpdir:
             filename = os.path.join(tmpdir, 'test.c')
@@ -25,18 +35,60 @@
             self.assertTrue('var="this is it"' in result)
 
     def test_get_clang_arguments_fails(self):
-        self.assertRaises(
-            Exception, sut.get_arguments,
-            ['clang', '-###', '-fsyntax-only', '-x', 'c', 'notexist.c'], '.')
+        with self.assertRaises(Exception):
+            sut.get_arguments(['clang', '-x', 'c', 'notexist.c'], '.')
+
+    def test_get_clang_arguments_fails_badly(self):
+        with self.assertRaises(OSError):
+            sut.get_arguments(['notexist'], '.')
 
 
-class GetCheckersTest(unittest.TestCase):
+class ClangGetCheckersTest(unittest.TestCase):
     def test_get_checkers(self):
         # this test is only to see is not crashing
         result = sut.get_checkers('clang', [])
         self.assertTrue(len(result))
+        # do check result types
+        string_type = unicode if sys.version_info < (3,) else str
+        for key, value in result.items():
+            self.assertEqual(string_type, type(key))
+            self.assertEqual(string_type, type(value[0]))
+            self.assertEqual(bool, type(value[1]))
 
     def test_get_active_checkers(self):
         # this test is only to see is not crashing
         result = sut.get_active_checkers('clang', [])
         self.assertTrue(len(result))
+        # do check result types
+        for value in result:
+            self.assertEqual(str, type(value))
+
+    def test_is_active(self):
+        test = sut.is_active(['a', 'b.b', 'c.c.c'])
+
+        self.assertTrue(test('a'))
+        self.assertTrue(test('a.b'))
+        self.assertTrue(test('b.b'))
+        self.assertTrue(test('b.b.c'))
+        self.assertTrue(test('c.c.c.p'))
+
+        self.assertFalse(test('ab'))
+        self.assertFalse(test('ba'))
+        self.assertFalse(test('bb'))
+        self.assertFalse(test('c.c'))
+        self.assertFalse(test('b'))
+        self.assertFalse(test('d'))
+
+    def test_parse_checkers(self):
+        lines = [
+            'OVERVIEW: Clang Static Analyzer Checkers List',
+            '',
+            'CHECKERS:',
+            '  checker.one       Checker One description',
+            '  checker.two',
+            '                    Checker Two description']
+        result = dict(sut.parse_checkers(lines))
+        self.assertTrue('checker.one' in result)
+        self.assertEqual('Checker One description', result.get('checker.one'))
+        self.assertTrue('checker.two' in result)
+        self.assertEqual('Checker Two description', result.get('checker.two'))
diff --git a/www/analyzer/alpha_checks.html b/www/analyzer/alpha_checks.html
index 6f5e4f1..0312d16 100644
--- a/www/analyzer/alpha_checks.html
+++ b/www/analyzer/alpha_checks.html
@@ -26,13 +26,14 @@
 <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="#valist_alpha_checkers">Variable Argument 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 ----------------------------------->
+<!-- ============================= core alpha ============================= -->
 <h3 id="core_alpha_checkers">Core Alpha Checkers</h3>
 <table class="checkers">
 <colgroup><col class="namedescr"><col class="example"></colgroup>
@@ -179,7 +180,7 @@
 
 </tbody></table>
 
-<!--------------------------- cplusplus alpha --------------------------------->
+<!-- =========================== cplusplus alpha =========================== -->
 <h3 id="cplusplus_alpha_checkers">C++ Alpha Checkers</h3>
 <table class="checkers">
 <colgroup><col class="namedescr"><col class="example"></colgroup>
@@ -226,7 +227,76 @@
 
 </tbody></table>
 
-<!--------------------------- dead code alpha --------------------------------->
+
+
+<!-- =============================== va_list =============================== -->
+<h3 id="valist_alpha_checkers">Variable Argument 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.valist.CopyToSelf</span><span class="lang">
+(C)</span><div class="descr">
+Calls to the <code>va_copy</code> macro should not copy onto itself.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+#include &lt;stdarg.h&gt;
+
+void test(int x, ...) {
+  va_list args;
+  va_start(args, x);
+  va_copy(args, args); // warn
+  va_end(args);
+}
+</pre></div></div></td></tr>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.valist.Uninitialized</span><span class="lang">
+(C)</span><div class="descr">
+Calls to the <code>va_arg</code>, <code>va_copy</code>, or
+<code>va_end</code> macro must happen after calling <code>va_start</code> and
+before calling <code>va_end</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+#include &lt;stdarg.h&gt;
+
+void test(int x, ...) {
+  va_list args;
+  int y = va_arg(args, int); // warn
+}
+</pre></div>
+<div class="example"><pre>
+#include &lt;stdarg.h&gt;
+
+void test(int x, ...) {
+  va_list args;
+  va_start(args, x);
+  va_end(args);
+  int z = va_arg(args, int); // warn
+}
+</pre></div></div></td></tr>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.valist.Unterminated</span><span class="lang">
+(C)</span><div class="descr">
+Every <code>va_start</code> must be matched by a <code>va_end</code>. A va_list
+can only be ended once.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+#include &lt;stdarg.h&gt;
+
+void test(int x, ...) {
+  va_list args;
+  va_start(args, x);
+  int y = x + va_arg(args, int);
+} // warn: missing va_end
+</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>
@@ -267,7 +337,7 @@
 </pre></div></div></td></tr>
 </tbody></table>
 
-<!---------------------------- OS X alpha -------------------------------------->
+<!-- ============================== OS X alpha ============================== -->
 <h3 id="osx_alpha_checkers">OS X Alpha Checkers</h3>
 <table class="checkers">
 <colgroup><col class="namedescr"><col class="example"></colgroup>
@@ -433,7 +503,7 @@
 
 </tbody></table>
 
-<!------------------------- security alpha ------------------------------------>
+<!-- =========================== security alpha =========================== -->
 <h3 id="security_alpha_checkers">Security Alpha Checkers</h3>
 <table class="checkers">
 <colgroup><col class="namedescr"><col class="example"></colgroup>
@@ -584,7 +654,7 @@
 
 </tbody></table>
 
-<!--------------------------- unix alpha -------------------------------------->
+<!-- ============================= unix alpha ============================= -->
 <h3 id="unix_alpha_checkers">Unix Alpha Checkers</h3>
 <table class="checkers">
 <colgroup><col class="namedescr"><col class="example"></colgroup>
diff --git a/www/analyzer/faq.html b/www/analyzer/faq.html
index cf3dc70..516233b 100644
--- a/www/analyzer/faq.html
+++ b/www/analyzer/faq.html
@@ -29,6 +29,9 @@
   <li><a href="#dead_store">How do I tell the static analyzer that I don't care about a specific dead store?</a></li>
   <li><a href="#unused_ivar">How do I tell the static analyzer that I don't care about a specific unused instance variable in Objective C?</a></li>
   <li><a href="#unlocalized_string">How do I tell the static analyzer that I don't care about a specific unlocalized string?</a></li>
+  <li><a href="#dealloc_mrr">How do I tell the analyzer that my instance variable does not need to be released in -dealloc under Manual Retain/Release?</a></li>
+  <li><a href="#decide_nullability">How do I decide whether a method's return type should be _Nullable or _Nonnull?</a></li>
+  <li><a href="#nullability_intentional_violation">How do I tell the analyzer that I am intentionally violating nullability?</a></li>
   <li><a href="#use_assert">The analyzer assumes that a loop body is never entered.  How can I tell it that the loop body will be entered at least once?</a></li>
   <li><a href="#suppress_issue">How can I suppress a specific analyzer warning?</a></li>
   <li><a href="#exclude_code">How can I selectively exclude code the analyzer examines?</a></li>
@@ -105,6 +108,67 @@
 </pre>
 </p>
 
+<h4 id="dealloc_mrr" class="faq">Q: How do I tell the analyzer that my instance variable does not need to be released in -dealloc under Manual Retain/Release?</h4>
+
+<p>If your class only uses an instance variable for part of its lifetime, it may
+maintain an invariant guaranteeing that the instance variable is always released
+before -dealloc. In this case, you can silence a warning about a missing release
+by either adding <tt>assert(_ivar == nil)</tt> or an explicit release
+<tt>[_ivar release]</tt> (which will be a no-op when the variable is nil) in
+-dealloc. </p>
+
+<h4 id="decide_nullability" class="faq">Q: How do I decide whether a method's return type should be _Nullable or _Nonnull?</h4>
+
+<p> Depending on the implementation of the method, this puts you in one of five situations:
+<ol>
+<li>You actually never return nil.</li>
+<li>You do return nil sometimes, and callers are supposed to handle that. This
+includes cases where your method is documented to return nil given certain
+inputs.</li>
+<li>You return nil based on some external condition (such as an out-of-memory
+error), but the client can't do anything about it either.</li>
+<li>You return nil only when the caller passes input documented to be invalid.
+That means it's the client's fault.</li>
+<li>You return nil in some totally undocumented case.</li>
+</ol>
+</p>
+
+<p>In (1) you should annotate the method as returning a <tt>_Nonnull</tt>
+object.</p>
+<p>In (2) the method should be marked <tt>_Nullable.</tt></p>
+<p>In (3) you should probably annotate the method <tt>_Nonnull</tt>. Why?
+Because no callers will actually check for nil, given that they can't do
+anything about the situation and don't know what went wrong. At this point
+things have gone so poorly that there's basically no way to recover.</p>
+<p>The least happy case is (4) because the resulting program will almost
+certainly either crash or just silently do the wrong thing.
+If this is a new method or you control the callers, you can use
+<tt>NSParameterAssert()</tt> (or the equivalent) to check the precondition and
+remove the nil return. But if you don't control the callers and they rely on
+this behavior, you should return mark the method <tt>_Nonnull</tt> and return
+nil <a href="#nullability_intentional_violation">cast to _Nonnull</a> anyway.
+(Note that (4) doesn't apply in cases where the caller can't know they passed
+bad parameters. For example,
+<tt>+[NSData dataWithContentsOfFile:options:error:]</tt> will fail if the file
+doesn't exist, but there's no way to check for that in advance. This means
+you're really in (2).)</p>
+<p>If you're in (5), document it, then figure out if you're now in (2), (3), or
+(4). :-)</p>
+
+<h4 id="nullability_intentional_violation" class="faq">Q: How do I tell the analyzer that I am intentionally violating nullability?</h4>
+
+<p>In some cases, it may make sense for methods to intentionally violate
+nullability. For example, your method may &mdash; for reasons of backward
+compatibility &mdash; chose to return nil and log an error message in a method
+with a non-null return type when the client violated a documented precondition
+rather than check the precondition with <tt>NSAssert()</tt>. In these cases, you
+can suppress the analyzer warning with a cast:
+<pre class="code_example">
+    return (id _Nonnull)nil;
+</pre>
+Note that this cast does not affect code generation.
+</p>
+
 <h4 id="use_assert" class="faq">Q: The analyzer assumes that a loop body is never entered.  How can I tell it that the loop body will be entered at least once?</h4>
 
 <img src="images/example_use_assert.png" alt="example use assert">
diff --git a/www/analyzer/potential_checkers.html b/www/analyzer/potential_checkers.html
index 0e5fba3..2e6a201 100644
--- a/www/analyzer/potential_checkers.html
+++ b/www/analyzer/potential_checkers.html
@@ -180,64 +180,6 @@
 
 </table>
 
-<!-- =============================== va_list =============================== -->
-<h3>va_list</h3>
-<table class="checkers">
-<col class="namedescr"><col class="example"><col class="progress">
-<thead><tr><td>Name, Description</td><td>Example</td><td>Progress</td></tr></thead>
-
-<tr><td><div class="namedescr expandable"><span class="name">
-valist.Uninitialized</span><span class="lang">
-(C)</span><div class="descr">
-Calls to the <code>va_arg</code>, <code>va_copy</code>, or
-<code>va_end</code> macro must happen after calling <code>va_start</code> and
-before calling <code>va_end</code>.</div></div></td>
-<td><div class="exampleContainer expandable">
-<div class="example"><pre>
-#include &lt;stdarg.h&gt;
-
-void test(int x, ...) {
-  va_list args;
-  int y = va_arg(args, int); // warn
-}
-</pre></div>
-<div class="example"><pre>
-#include &lt;stdarg.h&gt;
-
-void test(int x, ...) {
-  va_list args;
-  va_start(args, x); 
-  va_end(args);
-  int z = va_arg(args, int); // warn
-}
-</pre></div></div></td>
-<td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=16812">
-PR16811</a></td></tr>
-
-<tr><td><div class="namedescr expandable"><span class="name">
-valist.Unterminated</span><span class="lang">
-(C)</span><div class="descr">
-Every <code>va_start</code> must be matched by a <code>va_end</code>. A va_list
-can only be ended once.
-
-<i>This should be folded into the generalized "ownership checker"
-described on the <a href="open_projects.html">
-Open Projects</a> page.</i></div></div></td>
-<td><div class="exampleContainer expandable">
-<div class="example"><pre>
-#include &lt;stdarg.h&gt;
-
-void test(int x, ...) {
-  va_list args;
-  va_start(args, x);
-  int y = x + va_arg(args, int);
-} // warn: missing va_end
-</pre></div></div></td>
-<td class="aligned"><a href="http://llvm.org/bugs/show_bug.cgi?id=16812">
-PR16812</a></td></tr>
-
-</table>
-
 <!-- ============================== exceptions ============================= -->
 <h3>exceptions</h3>
 <table class="checkers">
@@ -384,7 +326,8 @@
    // warn: the right operand to '-' is always 0
 }
 </pre></div></div></td>
-<td class="aligned">removed from alpha.deadcode.* at r198476</td></tr>
+<td class="aligned">removed from alpha.deadcode.* at
+<a href="https://reviews.llvm.org/rL198476">r198476</a></td></tr>
 
 </table>