<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - parsing regression"
   href="https://llvm.org/bugs/show_bug.cgi?id=23552">23552</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>parsing regression
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>release blocker
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>new bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>legalize@xmission.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=14334" name="attach_14334" title="clang-query session">attachment 14334</a> <a href="attachment.cgi?id=14334&action=edit" title="clang-query session">[details]</a></span>
clang-query session

See the attached clang-query session.  The installed version is 3.5.0 and the
version run from my build tree is trunk.

In 3.5.0 clang-query correctly reports two if statements for this code from
clang/lib/AST/ExprConstant.cpp:

    bool isOnePastTheEnd() const {
      assert(!Invalid);
      if (IsOnePastTheEnd)
        return true;
      if (MostDerivedArraySize &&
          Entries[MostDerivedPathLength - 1].ArrayIndex ==
MostDerivedArraySize)
        return true;
      return false;
    }

In trunk, the 2nd if statement is missing from the parse tree.  I noticed this
while working on an enhancement for clang-tidy's
readability-simplify-boolean-expr check.  I was adding a simplification of:

    if (expr)
      return true;
    return false;

into

    return expr;

When I tried it out on llvm/clang trunk, I got all kinds of erroneous changes. 
I didn't find anything in the debugger so I went to clang-query to dump out the
AST and the 2nd if statement in the above method is completely missing from the
AST.  This causes the matcher to fire on the first if statement and the last
return statement, changing the meaning of the code.

My simplifier was doing this pretty consistently throughout the code matching
stuff of the form:

    if (expr)
      return true;
    arbitrary_stmt;
    return false;

and stuff of the form:

    if (expr) {
      arbitrary_stmt;
      return true;
    }
    return false;

My matcher was using an expression like this:

      compoundStmt(
          allOf(hasAnySubstatement(
                    ifStmt(
                        hasThen(returnsBool(Value, CompoundId)),
                       
unless(hasElse(stmt()))).bind(CompoundIfReturnsBoolId)),
                hasAnySubstatement(returnStmt(has(boolLiteral(equals(!Value))))
                                       .bind(CompoundReturnId)))).bind(Id)

where returnsBool is my own helper that does:

    internal::Matcher<Stmt> returnsBool(bool Value, StringRef Id = "") {
      auto SimpleReturnsBool =
          returnStmt(
              has(boolLiteral(equals(Value)).bind(Id.empty() ? "ignored" :
Id)))
              .bind("returns-bool");
      return anyOf(SimpleReturnsBool,
                   compoundStmt(statementCountIs(1), has(SimpleReturnsBool)));
    }

...which means that there's something even more wrong afoot because if
statements with a then clause containing a compound statement of more than one
statement shouldn't even trigger a match, but they are.

I don't think anything I've done caused this problem, since I am only making
changes on clang-tidy.  The full changeset is available for review at
<a href="http://reviews.llvm.org/D9810">http://reviews.llvm.org/D9810</a>.  I am on master branch of llvm and clang using
the github mirror.</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>