Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Clang] template with NTTP param is static array element failed to compile #133047

Closed
wanghenshui opened this issue Mar 26, 2025 · 3 comments · Fixed by #133212
Closed

[Clang] template with NTTP param is static array element failed to compile #133047

wanghenshui opened this issue Mar 26, 2025 · 3 comments · Fixed by #133212
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" rejects-valid

Comments

@wanghenshui
Copy link

it's code from CV-cuda, migrate to clang

#include <cstddef>
#include <stdint.h>
#include <utility>
#include <tuple>
template<bool Active = true, typename T>
constexpr inline bool IsOutside(T c, T s)
{
    if constexpr (Active)
    {
        return (c < 0) || (c >= s);
    }
    return false;
}


template<bool... ActiveDimensions>
class BoolDimension
{
public:
    static constexpr int  kNumDimensions = sizeof...(ActiveDimensions);
    struct ActiveMap
    {
        bool from[kNumDimensions];

        constexpr ActiveMap()
            : from()
        {
            int j = 0;
            for (int i = 0; i < kNumDimensions; ++i)
            {
                if (kActiveDimensions[i])
                {
                    from[i] = j++;
                }
            }
        }
    };

    static constexpr ActiveMap kMap{};
    static constexpr bool kActiveDimensions[]  = {ActiveDimensions...};
    static constexpr int  kNumActiveDimensions = ((ActiveDimensions ? 1 : 0) + ...);
    int64_t          m_tensorShape[kNumActiveDimensions] = {0};

    template<typename... Args, std::size_t... Is>
    inline  bool check(std::index_sequence<Is...>, Args... c) const
    {
        //static constexpr const  auto kDimensions = std::make_tuple(ActiveDimensions...);
        //if ((IsOutside<std::get<Is>(kDimensions)>(c,false) || ...))
        if ((IsOutside<kActiveDimensions[Is]>(c,false) || ...))
        {
            return true;
        }
        return false;
    }
};

int main() {
    BoolDimension<true, true, false, false> d;
    constexpr auto Is = std::make_index_sequence<1>{};
    return d.check(Is, false);
}

in check function, IsOutside not accept array element, change to tuple with get is ok

https://godbolt.org/z/n1K5vGcrE

@llvmbot llvmbot added the clang Clang issues not falling into any other category label Mar 26, 2025
@wanghenshui
Copy link
Author

https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2647r1.html

use lambda workaround also ok

@frederick-vs-ja
Copy link
Contributor

frederick-vs-ja commented Mar 26, 2025

Clang correctly accepts this with the following change (Godbolt link):

-    static constexpr bool kActiveDimensions[]  = {ActiveDimensions...};
+    static constexpr bool kActiveDimensions[kNumDimensions]  = {ActiveDimensions...};

This is probably duplicate of either #79750 or #113936.

@frederick-vs-ja frederick-vs-ja added clang:frontend Language frontend issues, e.g. anything involving "Sema" rejects-valid and removed clang Clang issues not falling into any other category labels Mar 26, 2025
@llvmbot
Copy link
Member

llvmbot commented Mar 26, 2025

@llvm/issue-subscribers-clang-frontend

Author: Ted Mostly (wanghenshui)

it's code from CV-cuda, migrate to clang
#include &lt;cstddef&gt;
#include &lt;stdint.h&gt;
#include &lt;utility&gt;
#include &lt;tuple&gt;
template&lt;bool Active = true, typename T&gt;
constexpr inline bool IsOutside(T c, T s)
{
    if constexpr (Active)
    {
        return (c &lt; 0) || (c &gt;= s);
    }
    return false;
}


template&lt;bool... ActiveDimensions&gt;
class BoolDimension
{
public:
    static constexpr int  kNumDimensions = sizeof...(ActiveDimensions);
    struct ActiveMap
    {
        bool from[kNumDimensions];

        constexpr ActiveMap()
            : from()
        {
            int j = 0;
            for (int i = 0; i &lt; kNumDimensions; ++i)
            {
                if (kActiveDimensions[i])
                {
                    from[i] = j++;
                }
            }
        }
    };

    static constexpr ActiveMap kMap{};
    static constexpr bool kActiveDimensions[]  = {ActiveDimensions...};
    static constexpr int  kNumActiveDimensions = ((ActiveDimensions ? 1 : 0) + ...);
    int64_t          m_tensorShape[kNumActiveDimensions] = {0};

    template&lt;typename... Args, std::size_t... Is&gt;
    inline  bool check(std::index_sequence&lt;Is...&gt;, Args... c) const
    {
        //static constexpr const  auto kDimensions = std::make_tuple(ActiveDimensions...);
        //if ((IsOutside&lt;std::get&lt;Is&gt;(kDimensions)&gt;(c,false) || ...))
        if ((IsOutside&lt;kActiveDimensions[Is]&gt;(c,false) || ...))
        {
            return true;
        }
        return false;
    }
};

int main() {
    BoolDimension&lt;true, true, false, false&gt; d;
    constexpr auto Is = std::make_index_sequence&lt;1&gt;{};
    return d.check(Is, false);
}

in check function, IsOutside not accept array element, change to tuple with get is ok

https://godbolt.org/z/n1K5vGcrE

@zyn0217 zyn0217 closed this as completed Mar 27, 2025
zyn0217 added a commit that referenced this issue Mar 27, 2025
…tantiated (#133212)

The instantiation of a VarDecl's initializer might be deferred until the
variable is actually used. However, we were still building the
DeclRefExpr with a type that could later be changed by the initializer's
instantiation, which is incorrect when incomplete arrays are involved.

Fixes #79750
Fixes #113936
Fixes #133047
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" rejects-valid
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants