<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </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 - -Wrange-loop-analysis is too strict in templates"
   href="https://bugs.llvm.org/show_bug.cgi?id=44556">44556</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>-Wrange-loop-analysis is too strict in templates
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

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

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>Frontend
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>aaronpuchert@alice-dsl.net
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>The warning -Wrange-loop-analysis diagnoses two issues:

* When the return value of the iterator's operator* is a reference type, but it
is captured by value: this means we've made an unnecessary copy.
* When the return value of the iterator's operator* is not a reference type,
but is captured by reference: this is fine, but suggests there is no copy when
in fact there is one. (Well, because of RVO there might actually be no copy.)

Unfortunately the warning flips in template code:

struct Rng {
    struct iterator {
        int operator*() const;
        iterator& operator++();
        bool operator!=(const iterator&) const;
    };
    iterator begin() const;
    iterator end() const;
};

struct X {
    X() = default;
    X(const X&);
};

template<typename T>
void f(const T& t) {
    // Variant 1.
    for (const auto& _ : t)    // Warning from (1).
        ;
    // Variant 2.
    for (const auto _ : t)     // Warning from (2).
        ;
}

void g()
{
    X array[3];
    f(array);    // (1)
    f(Rng{});    // (2)
}

This means however I write f, there will always be a warning, although the
first variant is actually correct. I think that we should either not warn about
the second issue, or drop the warning when template-dependent types are
involved. However, we should in my opinion always warn about the first issue.</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>