Skip to content

std::source_location make constexpr size wrong at compile time. #78128

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

Closed
Ghost-LZW opened this issue Jan 15, 2024 · 5 comments · Fixed by #78436
Closed

std::source_location make constexpr size wrong at compile time. #78128

Ghost-LZW opened this issue Jan 15, 2024 · 5 comments · Fixed by #78436
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party constexpr Anything related to constant evaluation miscompilation

Comments

@Ghost-LZW
Copy link
Contributor

background: want to get compile time type name without rtti.

#include <iostream>
#include <string_view>
#include <source_location>
#include <utility>

template<typename T>
void foo() {
  constexpr std::string_view func_name =
      std::source_location::current().function_name();
  constexpr size_t type_anchor_idx = func_name.find_first_of('=');
  constexpr size_t type_end_idx = func_name.find_last_of(']');
  constexpr auto type_str =
      func_name.substr(type_anchor_idx + 2, type_end_idx - type_anchor_idx - 2);
  std::cerr << type_anchor_idx << ' ' << type_end_idx << std::endl;
  std::cerr << func_name.data() << '\n' << type_str.data() << std::endl;
  std::cerr << type_str.size() << ' '
            << std::make_index_sequence<type_str.size()>().size() << std::endl;
}

int main() {
  foo<int>();
}
/*
14 19
void foo() [T = int]
int]
3 9
*/

https://godbolt.org/z/r45d8cjsr

expect output is

14 19
void foo() [T = int]
int]
3 3
@dtcxzyw dtcxzyw added c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" miscompilation constexpr Anything related to constant evaluation and removed new issue labels Jan 15, 2024
@llvmbot
Copy link
Member

llvmbot commented Jan 15, 2024

@llvm/issue-subscribers-clang-frontend

Author: lzw (Ghost-LZW)

background: want to get compile time type name without rtti.
#include &lt;iostream&gt;
#include &lt;string_view&gt;
#include &lt;source_location&gt;
#include &lt;utility&gt;

template&lt;typename T&gt;
void foo() {
  constexpr std::string_view func_name =
      std::source_location::current().function_name();
  constexpr size_t type_anchor_idx = func_name.find_first_of('=');
  constexpr size_t type_end_idx = func_name.find_last_of(']');
  constexpr auto type_str =
      func_name.substr(type_anchor_idx + 2, type_end_idx - type_anchor_idx - 2);
  std::cerr &lt;&lt; type_anchor_idx &lt;&lt; ' ' &lt;&lt; type_end_idx &lt;&lt; std::endl;
  std::cerr &lt;&lt; func_name.data() &lt;&lt; '\n' &lt;&lt; type_str.data() &lt;&lt; std::endl;
  std::cerr &lt;&lt; type_str.size() &lt;&lt; ' '
            &lt;&lt; std::make_index_sequence&lt;type_str.size()&gt;().size() &lt;&lt; std::endl;
}

int main() {
  foo&lt;int&gt;();
}
/*
14 19
void foo() [T = int]
int]
3 9
*/

https://godbolt.org/z/r45d8cjsr

expect output is

14 19
void foo() [T = int]
int]
3 3

@llvmbot
Copy link
Member

llvmbot commented Jan 15, 2024

@llvm/issue-subscribers-c-20

Author: lzw (Ghost-LZW)

background: want to get compile time type name without rtti.
#include &lt;iostream&gt;
#include &lt;string_view&gt;
#include &lt;source_location&gt;
#include &lt;utility&gt;

template&lt;typename T&gt;
void foo() {
  constexpr std::string_view func_name =
      std::source_location::current().function_name();
  constexpr size_t type_anchor_idx = func_name.find_first_of('=');
  constexpr size_t type_end_idx = func_name.find_last_of(']');
  constexpr auto type_str =
      func_name.substr(type_anchor_idx + 2, type_end_idx - type_anchor_idx - 2);
  std::cerr &lt;&lt; type_anchor_idx &lt;&lt; ' ' &lt;&lt; type_end_idx &lt;&lt; std::endl;
  std::cerr &lt;&lt; func_name.data() &lt;&lt; '\n' &lt;&lt; type_str.data() &lt;&lt; std::endl;
  std::cerr &lt;&lt; type_str.size() &lt;&lt; ' '
            &lt;&lt; std::make_index_sequence&lt;type_str.size()&gt;().size() &lt;&lt; std::endl;
}

int main() {
  foo&lt;int&gt;();
}
/*
14 19
void foo() [T = int]
int]
3 9
*/

https://godbolt.org/z/r45d8cjsr

expect output is

14 19
void foo() [T = int]
int]
3 3

@tbaederr
Copy link
Contributor

Here with fewer dependencies:

#include <iostream>
#include <source_location>

template<int N>
constexpr int f() {
  return N;
}



template<typename T>
void foo() {
  constexpr std::string_view func_name = std::source_location::current().function_name();

  std::cout << func_name.size() << "\n";
  std::cout << f<func_name.size()>() << '\n';
}

int main() {
  foo<int>();
}

Prints

20
10

@AaronBallman AaronBallman added the confirmed Verified by a second party label Jan 15, 2024
@shafik
Copy link
Collaborator

shafik commented Jan 16, 2024

CC @cor3ntin @Fznamznon

@cor3ntin
Copy link
Contributor

Without dependencies https://compiler-explorer.com/z/nnYjoc3K9

cor3ntin added a commit to cor3ntin/llvm-project that referenced this issue Jan 17, 2024
SourceLocExpr that may produce a function name
are marked dependent so that the non-instantiated
name of a function does not get evaluated.

In GH78128, the name('s size) is used as
template argument to a Declref that is not
dependent, and therefore not transformed and cached
when the function is instantiated, leading
to 2 different values existing at the same time
for the same function.

Fixes llvm#78128
cor3ntin added a commit that referenced this issue Jan 18, 2024
SourceLocExpr that may produce a function name are marked dependent so that the non-instantiated
name of a function does not get evaluated.

In GH78128, the name('s size) is used as
template argument to a `DeclRef` that is not otherwise dependent, and therefore cached and not transformed when the function is
instantiated, leading to 2 different values existing at the same time for the same function.

Fixes #78128
ampandey-1995 pushed a commit to ampandey-1995/llvm-project that referenced this issue Jan 19, 2024
SourceLocExpr that may produce a function name are marked dependent so that the non-instantiated
name of a function does not get evaluated.

In GH78128, the name('s size) is used as
template argument to a `DeclRef` that is not otherwise dependent, and therefore cached and not transformed when the function is
instantiated, leading to 2 different values existing at the same time for the same function.

Fixes llvm#78128
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++20 clang:frontend Language frontend issues, e.g. anything involving "Sema" confirmed Verified by a second party constexpr Anything related to constant evaluation miscompilation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants