<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 - [modules] error: constant expression not a constant expression (part II)"
   href="https://bugs.llvm.org/show_bug.cgi?id=33002">33002</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[modules] error: constant expression not a constant expression (part II)
          </td>
        </tr>

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

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

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

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

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

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>Modules
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>gonzalobg88@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>dgregor@apple.com, llvm-bugs@lists.llvm.org
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=18430" name="attach_18430" title="Testcase">attachment 18430</a> <a href="attachment.cgi?id=18430&action=edit" title="Testcase">[details]</a></span>
Testcase

Given the following files:

- include/module_a.hpp
- include/module_b.hpp
- include/module_c.hpp
- include/module.modulemap
- test.cpp

compiling test.cpp with:

clang++ -std=c++1z -fmodules -gmodules -fno-implicit-module-maps -Iinclude
-fmodule-map-file=include/module.modulemap
-fmodule-map-file=/path/to/libcxx/c++/v1/module.modulemap
-fmodules-cache-path=module.cache test.cpp

fails with the following error:

hile building module 'module_c' imported from test.cpp:1:
In file included from <module-includes>:1:
include/module_c.hpp:12:33: error: non-type template argument is not a constant
expression
template <typename T, T Value = module_a::highest<T>>
                                ^~~~~~~~~~~~~~~~~~~~~
include/module_c.hpp:15:40: note: while checking a default template argument
used here
using node_idx = baz<unsigned long long>;
                 ~~~~~~~~~~~~~~~~~~~~~~^
include/module_c.hpp:12:33: note: initializer of 'highest<unsigned long long>'
is not a constant expression
template <typename T, T Value = module_a::highest<T>>
                                ^
include/module_a.hpp:10:26: note: declared here
static const constexpr T highest = std::numeric_limits<T>::max();
                         ^
/include/c++/v1/limits:212:85: note: subexpression not valid in a constant
expression
    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT
{return __max;}
                                                                               
    ^
/include/c++/v1/limits:449:85: note: in call to 'max()'
    _LIBCPP_INLINE_VISIBILITY static _LIBCPP_CONSTEXPR type max() _NOEXCEPT
{return __base::max();}
                                                                               
    ^
include/module_a.hpp:10:36: note: in call to 'max()'
static const constexpr T highest = std::numeric_limits<T>::max();
                                   ^
test.cpp:1:10: fatal error: could not build module 'module_c'
#include <module_c.hpp>
 ~~~~~~~~^
2 errors generated.


include/module_a.hpp:

#pragma once
#include <limits>

namespace module_a {

template <typename T>
static const constexpr T highest = std::numeric_limits<T>::max();

} // namespace module_a

include/module_b.hpp:
#pragma once
#include <module_a.hpp>

namespace module_b {

template <bool V, typename A, typename B> struct if__ { using type = A; };
template <typename A, typename B> struct if__<false, A, B> { using type = B; };
template <bool V, typename A, typename B>
using if_ = typename if__<V, A, B>::type;

// clang-format off

template <std::size_t N>
using smallest_size_t
  = if_<(N < module_a::highest<char>),  char,
    if_<(N < module_a::highest<unsigned long long>), unsigned long long,
    std::size_t>>;

// clang-format on

} // namespace module_b

include/module_c.hpp:

#pragma once
#include <limits>
#include <module_a.hpp>
#include <module_b.hpp>

namespace module_c {

template <class T, T u> struct foo {};

template <class T> struct bar {};

template <typename T, T Value = module_a::highest<T>>
using baz = bar<foo<T, Value>>;

using node_idx = baz<unsigned long long>;

} // namespace module_c

include/module.modulemap:

module module_b { header "module_b.hpp" export * }
module module_a { header "module_a.hpp" export * }
module module_c { header "module_c.hpp" export * }  

test.cpp:

#include <module_c.hpp>

int main() {
  return 0;
}</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>