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] constexpr template method cannot be used in a constant expression #107018

Open
Pawday opened this issue Sep 2, 2024 · 4 comments
Open
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" constexpr Anything related to constant evaluation

Comments

@Pawday
Copy link

Pawday commented Sep 2, 2024

Online example

struct ConstexprTemplate
{
    static constexpr int sizeof_char()
    {
        return sizeof_template<char>();
    }

    static constexpr int sizeof_short()
    {
        return sizeof_template<short>();
    }

    static constexpr int sizeof_int()
    {
        return sizeof_template<int>();
    }

    static constexpr int sizeof_long()
    {
        return sizeof_template<long>();
    }

    template <typename I>
    static constexpr I sizeof_template()
    {
        return sizeof(I);
    }
};

constexpr int sizeof_char = ConstexprTemplate::sizeof_char();
constexpr int sizeof_short = ConstexprTemplate::sizeof_short();
constexpr int sizeof_int = ConstexprTemplate::sizeof_int();
constexpr int sizeof_long = ConstexprTemplate::sizeof_long();

clang version 18.1.8 ([email protected]:llvm/llvm-project.git 3b5b5c1)

Full diagnostic message:

Example.cc:30:15: error: constexpr variable 'sizeof_char' must be initialized by a constant expression
   30 | constexpr int sizeof_char = ConstexprTemplate::sizeof_char();
      |               ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:5:16: note: undefined function 'sizeof_template<char>' cannot be used in a constant expression
    5 |         return sizeof_template<char>();
      |                ^
Example.cc:30:29: note: in call to 'sizeof_char()'
   30 | constexpr int sizeof_char = ConstexprTemplate::sizeof_char();
      |                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:24:24: note: declared here
   24 |     static constexpr I sizeof_template()
      |                        ^
Example.cc:31:15: error: constexpr variable 'sizeof_short' must be initialized by a constant expression
   31 | constexpr int sizeof_short = ConstexprTemplate::sizeof_short();
      |               ^              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:10:16: note: undefined function 'sizeof_template<short>' cannot be used in a constant expression
   10 |         return sizeof_template<short>();
      |                ^
Example.cc:31:30: note: in call to 'sizeof_short()'
   31 | constexpr int sizeof_short = ConstexprTemplate::sizeof_short();
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:24:24: note: declared here
   24 |     static constexpr I sizeof_template()
      |                        ^
Example.cc:32:15: error: constexpr variable 'sizeof_int' must be initialized by a constant expression
   32 | constexpr int sizeof_int = ConstexprTemplate::sizeof_int();
      |               ^            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:15:16: note: undefined function 'sizeof_template<int>' cannot be used in a constant expression
   15 |         return sizeof_template<int>();
      |                ^
Example.cc:32:28: note: in call to 'sizeof_int()'
   32 | constexpr int sizeof_int = ConstexprTemplate::sizeof_int();
      |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:24:24: note: declared here
   24 |     static constexpr I sizeof_template()
      |                        ^
Example.cc:33:15: error: constexpr variable 'sizeof_long' must be initialized by a constant expression
   33 | constexpr int sizeof_long = ConstexprTemplate::sizeof_long();
      |               ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:20:16: note: undefined function 'sizeof_template<long>' cannot be used in a constant expression
   20 |         return sizeof_template<long>();
      |                ^
Example.cc:33:29: note: in call to 'sizeof_long()'
   33 | constexpr int sizeof_long = ConstexprTemplate::sizeof_long();
      |                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:24:24: note: declared here
   24 |     static constexpr I sizeof_template()
      |                        ^
4 errors generated.
@github-actions github-actions bot added the clang Clang issues not falling into any other category label Sep 2, 2024
@EugeneZelenko EugeneZelenko added clang:frontend Language frontend issues, e.g. anything involving "Sema" constexpr Anything related to constant evaluation and removed clang Clang issues not falling into any other category labels Sep 3, 2024
@llvmbot
Copy link
Member

llvmbot commented Sep 3, 2024

@llvm/issue-subscribers-clang-frontend

Author: Pavel Korotkevich (Pawday)

# [Online example](https://godbolt.org/z/qzaaGfe5h) ```c++ struct ConstexprTemplate { static constexpr int sizeof_char() { return sizeof_template<char>(); }
static constexpr int sizeof_short()
{
    return sizeof_template&lt;short&gt;();
}

static constexpr int sizeof_int()
{
    return sizeof_template&lt;int&gt;();
}

static constexpr int sizeof_long()
{
    return sizeof_template&lt;long&gt;();
}

template &lt;typename I&gt;
static constexpr I sizeof_template()
{
    return sizeof(I);
}

};

constexpr int sizeof_char = ConstexprTemplate::sizeof_char();
constexpr int sizeof_short = ConstexprTemplate::sizeof_short();
constexpr int sizeof_int = ConstexprTemplate::sizeof_int();
constexpr int sizeof_long = ConstexprTemplate::sizeof_long();


clang version 18.1.8 (git@<!-- -->github.com:llvm/llvm-project.git 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff)

Full diagnostic message:
```txt
Example.cc:30:15: error: constexpr variable 'sizeof_char' must be initialized by a constant expression
   30 | constexpr int sizeof_char = ConstexprTemplate::sizeof_char();
      |               ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:5:16: note: undefined function 'sizeof_template&lt;char&gt;' cannot be used in a constant expression
    5 |         return sizeof_template&lt;char&gt;();
      |                ^
Example.cc:30:29: note: in call to 'sizeof_char()'
   30 | constexpr int sizeof_char = ConstexprTemplate::sizeof_char();
      |                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:24:24: note: declared here
   24 |     static constexpr I sizeof_template()
      |                        ^
Example.cc:31:15: error: constexpr variable 'sizeof_short' must be initialized by a constant expression
   31 | constexpr int sizeof_short = ConstexprTemplate::sizeof_short();
      |               ^              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:10:16: note: undefined function 'sizeof_template&lt;short&gt;' cannot be used in a constant expression
   10 |         return sizeof_template&lt;short&gt;();
      |                ^
Example.cc:31:30: note: in call to 'sizeof_short()'
   31 | constexpr int sizeof_short = ConstexprTemplate::sizeof_short();
      |                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:24:24: note: declared here
   24 |     static constexpr I sizeof_template()
      |                        ^
Example.cc:32:15: error: constexpr variable 'sizeof_int' must be initialized by a constant expression
   32 | constexpr int sizeof_int = ConstexprTemplate::sizeof_int();
      |               ^            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:15:16: note: undefined function 'sizeof_template&lt;int&gt;' cannot be used in a constant expression
   15 |         return sizeof_template&lt;int&gt;();
      |                ^
Example.cc:32:28: note: in call to 'sizeof_int()'
   32 | constexpr int sizeof_int = ConstexprTemplate::sizeof_int();
      |                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:24:24: note: declared here
   24 |     static constexpr I sizeof_template()
      |                        ^
Example.cc:33:15: error: constexpr variable 'sizeof_long' must be initialized by a constant expression
   33 | constexpr int sizeof_long = ConstexprTemplate::sizeof_long();
      |               ^             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:20:16: note: undefined function 'sizeof_template&lt;long&gt;' cannot be used in a constant expression
   20 |         return sizeof_template&lt;long&gt;();
      |                ^
Example.cc:33:29: note: in call to 'sizeof_long()'
   33 | constexpr int sizeof_long = ConstexprTemplate::sizeof_long();
      |                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Example.cc:24:24: note: declared here
   24 |     static constexpr I sizeof_template()
      |                        ^
4 errors generated.

@tbaederr
Copy link
Contributor

tbaederr commented Sep 3, 2024

I think this is another case of constant evaluation not causing template instantiation. CC @cor3ntin

@Pawday

This comment was marked as off-topic.

@shafik
Copy link
Collaborator

shafik commented Sep 4, 2024

@tbaederr @cor3ntin I think we are talking about #73232 so folks don't have to go hunting to understand the details.

pr-update bot pushed a commit to oliverlee/rigid-geometric-algebra that referenced this issue Sep 29, 2024
Synthesize `zero_constant` and `multivector` overloads from a complete
type providing `blade` overloads. This is used to workaround
issues with instantiation of function templates in constant expressions
that occur when moving the wedge implementation.

llvm/llvm-project#107018

Change-Id: Iff177db6ad201a07f1f36d5d668c4ffcd4abff9a
oliverlee added a commit to oliverlee/rigid-geometric-algebra that referenced this issue Sep 29, 2024
Synthesize `zero_constant` and `multivector` overloads from a complete
type providing `blade` overloads. This is used to workaround
issues with instantiation of function templates in constant expressions
that occur when moving the wedge implementation.

llvm/llvm-project#107018

Change-Id: Iff177db6ad201a07f1f36d5d668c4ffcd4abff9a
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" constexpr Anything related to constant evaluation
Projects
None yet
Development

No branches or pull requests

5 participants