Nvc++ fails to compile some seemingly fine call to `std::get<f()>`

i was trying to use https://gitlab.cern.ch/LHCbOpt/SOAContainer in this year’s advent of code with nvc++. the code doesn’t compile while g++ accepts it. Adding a few parentheses in the right place in the code seems to fix the issue. (so no urgency to address the issue and no harm done). though it looks to me like this isn’t a bug in the code but rather nvc++'s fault not to accept it (admittedly, i’m leaning on the fact that g++ accepts the code and not so much my confidence in my own c++ legaleese).

You can find an MWE here (you can switch line 29 for 30 to make the compilation pass)

At the core of the issue seems to be a call to std::get<constexpr_function()> where nvc++'s error message “error: expected a ">"” suggests that nvc++ wants to use the function as template argument instead of its return value and the workaround is std::get<(constexpr_function())>. While I’m no expert on c++ standard parsing rules, that snippet looks fine to me. NB: i had to add sufficient template stuff around that get (like the constexpr_function is a templated member of a templated type and it’s called in an enable_if or conditional in a trailing return type), so it might be something else that throws the parser off.

What would be the right place to report nvc++ bugs and any idea what search term to use to check if it’s reported already?

PS: the MWE from the compiler explorer link copied here for convenience.

#include <tuple>

template <typename OTHER>
struct Widget {
    using type = std::tuple<int, double, OTHER>;

    type m_t;

    // Don't look at the logic of that file, it's just a templated constexpr
    // function that shall be used as template argument.
    template <typename T>
    static constexpr std::size_t idx() {
        if constexpr (std::is_same_v<T, int>) {
            return 0;
        } else {
            return 1;
        }
    }
};

template <bool SWITCH, typename MEMBER, typename OTHER>
struct derived : Widget<OTHER> {
    using parent_t = Widget<OTHER>;

    // Again, don't assume this function is doing anything meaningful, I mainly
    // want the trailing return type with std::enable_if / std::conditional.
    auto fun() -> typename std::enable_if_t<
        SWITCH,
        // decltype(std::get<(parent_t::template idx<MEMBER>())>(parent_t::m_t))> {
        decltype(std::get<parent_t::template idx<MEMBER>()>(parent_t::m_t))> {
        return std::get<parent_t::template idx<MEMBER>()>(parent_t::m_t);
    }
};

Hi Paul,

This works. There are other ways to submit issues, such as NVBUGs, but given I’m on the NVHPC compiler team, I can ask our engineers directly if there are questions. The one caveat is that I put the report directly into my team’s bug tracker which isn’t externally visible, while with NVBUGs you can see external comments.

For this issue, yes, it looks like a parsing error by our front-end. I’ve submitted a report, TPR#32769, and we’ll have an engineer investigate. Though given we license the front-end from a third party (EDG), it sometimes takes a bit longer to get these issues resolved. Hopefully not, but possible.

Thanks for the report,
Mat

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.

Hi Paul,

FYI, TPR #32769 was fixed in our 23.3 release.

-Mat

1 Like