Issue 136464
Summary Clang checks impossible cast
Labels clang
Assignees
Reporter vzze
    ### Issue

Clang tries to check if cast of `const char*` is ill-formed even though the context of the cast is reduced to only `int` by `if constexpr`

<details>
<summary>Code</summary>

```c++
// main.cc

#include <type_traits>
#include <variant>

int main() {
 using type = std::variant<int, const char*>;

    type a = 12;
    type b = 42;

    int res = std::visit([&](auto a1) -> int {
        return std::visit([&](auto b1) -> int {
            if constexpr(
 std::is_same_v<std::decay_t<decltype(a1)>, std::decay_t<decltype(b1)>> &&
 std::is_same_v<std::decay_t<decltype(a1)>, int>
            )
 return int(a1) + int(b1);
            else
 throw "Wrong type!";
        }, b);
    }, a);
}
```

<details>
<summary>Unix Error</summary>

```
main.cc:16:24: error: cast from pointer to smaller type 'int' loses information
   16 |                 return int(a1) + int(b1);
      |                        ^~~~~~~
main.cc:11:47: note: while substituting into a lambda _expression_ here
   11 |         return std::visit([&](auto b1) -> int {
      | ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1/bits/invoke.h:61:14: note: in instantiation of function template specialization 'main():
:(anonymous class)::operator()<const char *>' requested here
   61 |     { return std::forward<_Fn>(__f)(std::forward<_Args>(__args)...); }
 | ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1/bits/invoke.h:96:19: note: in instantiation of function template specialization 'std::__
invoke_impl<int, (lambda at main.cc:10:26), const char *&>' requested here
   96 |       return std::__invoke_impl<__type>(__tag{}, std::forward<_Callable>(__fn),
      | ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1/variant:1060:16: note: in instantiation of function template specialization 'std::__invo
ke<(lambda at main.cc:10:26), const char *&>' requested here
 1060 |           return std::__invoke(std::forward<_Visitor>(__visitor),
 | ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1/variant:1820:5: note: in instantiation of member function 'std::__detail::__variant::__g
en_vtable_impl<std::__detail::__variant::_Multi_array<std::__detail::__variant::__deduce_visit_result<int> (*)((lambda at main.cc:10:26) &&, std::variant<int, const cha
r *> &)>, std::integer_sequence<unsigned long, 1>>::__visit_invoke' requested here
 1820 |                   _GLIBCXX_VISIT_CASE(1)
      | ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1/variant:1811:4: note: expanded from macro '_GLIBCXX_VISIT_CASE'
 1811 | __visit_invoke(std::forward<_Visitor>(__visitor),             \
      | ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/14.2.1/../../../../include/c++/14.2.1/variant:1882:18: note: in instantiation of function template specialization 'std::__do_v
isit<std::__detail::__variant::__deduce_visit_result<int>, (lambda at main.cc:10:26), std::variant<int, const char *> &>' requested here
 1882 |             return std::__do_visit<_Tag>(
      | ^
main.cc:10:20: note: in instantiation of function template specialization 'std::visit<(lambda at main.cc:10:26), std::variant<int, const char *> &>' requested here
   10 |     int res = std::visit([&](auto a1) -> int {
      |                    ^
1 error generated.
```
</details>

<details>
<summary> Win11 Error </summary>

```
.\main.cc:16:24: warning: cast to smaller integer type 'int' from 'const char *' [-Wpointer-to-int-cast]
   16 | return int(a1) + int(b1);
      | ^~~~~~~
.\main.cc:11:47: note: while substituting into a lambda _expression_ here
   11 |         return std::visit([&](auto b1) -> int {
      | ^
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\include\type_traits:1706:16: note: in
      instantiation of function template specialization 'main()::(anonymous class)::operator()<const char *>' requested
      here
 1706 |         return static_cast<_Callable&&>(_Obj)(static_cast<_Ty1&&>(_Arg1), static_cast<_Types2&&>(_Args2)...);
      |                ^
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\include\variant:1422:25: note: in
      instantiation of function template specialization 'std::invoke<(lambda at ./main.cc:10:26), const char *&>'
      requested here
 1422 |             return _STD invoke(static_cast<_Callable&&>(_Obj),
      | ^
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\include\variant:1492:23: note: in
      instantiation of function template specialization 'std::_Variant_dispatcher<std::integer_sequence<unsigned long
      long, 2>>::_Dispatch2<int, (lambda at ./main.cc:10:26), std::variant<int, const char *> &, false>' requested here
 1492 |         _STL_STAMP(4, _STL_VISIT_STAMP);
      |                       ^
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\include\variant:1546:49: note: in
      instantiation of function template specialization 'std::_Visit_strategy<1>::_Visit2<int,
 std::_Meta_list<std::integer_sequence<unsigned long long, 0>, std::integer_sequence<unsigned long long, 1>,
 std::integer_sequence<unsigned long long, 2>>, (lambda at ./main.cc:10:26), std::variant<int, const char *> &>'
      requested here
 1546 |     return _Visit_strategy<_Strategy>::template _Visit2<_Ret, _ListOfIndexVectors>(
 |                                                 ^
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\include\variant:1591:17: note: in
      instantiation of function template specialization 'std::_Visit_impl<3ULL, int,
 std::_Meta_list<std::integer_sequence<unsigned long long, 0>, std::integer_sequence<unsigned long long, 1>,
 std::integer_sequence<unsigned long long, 2>>, (lambda at ./main.cc:10:26), std::variant<int, const char *> &>'
      requested here
 1591 |     return _STD _Visit_impl<_Size, _Ret, _ListOfIndexVectors>(
      | ^
.\main.cc:10:20: note: in instantiation of function template specialization 'std::visit<(lambda at ./main.cc:10:26),
 std::variant<int, const char *> &, void>' requested here
   10 |     int res = std::visit([&](auto a1) -> int {
      |                    ^
1 warning generated.
```

</details>

</details>

### Test Reproduction

* tested on both `linux` and `win11`

```
clang++ main.cc -std=c++17 -o main
```

### Clang Version

#### Arch Linux

```
clang version 19.1.7
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
```

#### Windows 11

```
clang version 20.1.3
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Users\****\scoop\apps\llvm\20.1.3\bin
```

### Additional information

* compiles just fine with `gcc`

```
g++ main.cc -std=c++17 -o main
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to