https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81525

            Bug ID: 81525
           Summary: [7 Regression] Invalid codegen with constexpr variable
                    template
           Product: gcc
           Version: 7.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ldionne.2 at gmail dot com
  Target Milestone: ---

The following code prints

    i = 0
    N = 0

when it should print

    i = 0
    N = 1

This seems to be a regression since GCC 7, although I am not sure exactly
which minor version introduced it. The problem only triggers when 'N' is
constexpr, when it is assigned from a variable template, and when we go
through enough templates (randomly making functions not templates seems
to fix the issue). The code is (sorry, I reduced a lot but could not
reduce further):

    #include <iostream>

    template <int i>
    struct integral_constant {
      constexpr operator int() const { return i; }
    };

    template <int i>
    constexpr integral_constant<i> int_{};

    template <typename F>
    void with_index(F f) {
      f(integral_constant<0>{});
    }

    template <typename Dummy>
    void print(Dummy) {
      constexpr auto N = ::int_<1>;
      (void)N; // otherwise we get [warning: variable 'N' set but not used]
               // this may be a hint that something is wrong

      auto f = [&](auto i) {
        std::cout << "i = " << static_cast<int>(i) << std::endl;
        std::cout << "N = " << static_cast<int>(N) << std::endl;
      };

      with_index(f);
    }

    int main() {
      ::print(0);
    }


Live example with GCC 6.3.0: https://wandbox.org/permlink/lclToxN6mnRAS3ol
Live example with GCC 7.1.0: https://wandbox.org/permlink/AUqaHBYlsfwHLUrU
Live example with GCC trunk: https://wandbox.org/permlink/8wxi8MqrS03MbujE

This bug report was lifted from a failure in Boost.Hana's test suite [1],
with the relevant original code being [2]. This is quite worrisome as this
breaks mundane constexpr-utilizing code in a nasty way.

[1]: https://travis-ci.org/boostorg/hana/jobs/256518824#L7663
[2]:
https://github.com/boostorg/hana/blob/e50749/example/tutorial/tag_dispatching.cpp#L72-L85

Reply via email to