c++: Handle ARRAY_TYPE in check_bit_cast_type [PR114706]
https://eel.is/c++draft/bit.cast#3 says that std::bit_cast isn't constexpr if To, From and the types of all subobjects have certain properties which the check_bit_cast_type checks (such as it isn't a pointer, reference, union, member pointer, volatile). The function doesn't cp_walk_tree though, so I've missed one important case, for ARRAY_TYPEs we need to recurse on the element type. I think we don't need to handle VECTOR_TYPEs/COMPLEX_TYPEs, because those will not have a pointer/reference/union/member pointer in the element type and if the element type is volatile, I think the whole derived type is volatile as well. 2024-04-16 Jakub Jelinek <jakub@redhat.com> PR c++/114706 * constexpr.cc (check_bit_cast_type): Handle ARRAY_TYPE. * g++.dg/cpp2a/bit-cast17.C: New test.
This commit is contained in:
parent
6e925ba0a8
commit
79ff53453e
2 changed files with 33 additions and 0 deletions
|
@ -4843,6 +4843,8 @@ check_bit_cast_type (const constexpr_ctx *ctx, location_t loc, tree type,
|
|||
if (TREE_CODE (field) == FIELD_DECL
|
||||
&& check_bit_cast_type (ctx, loc, TREE_TYPE (field), orig_type))
|
||||
return true;
|
||||
if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
return check_bit_cast_type (ctx, loc, TREE_TYPE (type), orig_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
31
gcc/testsuite/g++.dg/cpp2a/bit-cast17.C
Normal file
31
gcc/testsuite/g++.dg/cpp2a/bit-cast17.C
Normal file
|
@ -0,0 +1,31 @@
|
|||
// PR c++/114706
|
||||
// { dg-do compile { target c++20 } }
|
||||
|
||||
namespace std {
|
||||
template<typename T, typename F>
|
||||
constexpr T
|
||||
bit_cast (const F& f) noexcept
|
||||
{
|
||||
return __builtin_bit_cast (T, f);
|
||||
}
|
||||
}
|
||||
// { dg-error "'__builtin_bit_cast' is not a constant expression because 'const A' contains a union type" "" { target *-*-* } .-3 }
|
||||
// { dg-error "'__builtin_bit_cast' is not a constant expression because 'A' contains a union type" "" { target *-*-* } .-4 }
|
||||
// { dg-error "'__builtin_bit_cast' is not a constant expression because 'const C' contains a union type" "" { target *-*-* } .-5 }
|
||||
// { dg-error "'__builtin_bit_cast' is not a constant expression because 'C' contains a union type" "" { target *-*-* } .-6 }
|
||||
// { dg-error "'__builtin_bit_cast' is not a constant expression because 'const E' contains a pointer type" "" { target *-*-* } .-7 }
|
||||
// { dg-error "'__builtin_bit_cast' is not a constant expression because 'E' contains a pointer type" "" { target *-*-* } .-8 }
|
||||
|
||||
union U { int a; int b; };
|
||||
struct A { U c[2]; };
|
||||
struct B { int d[2]; };
|
||||
struct C { U e[2][2]; };
|
||||
struct D { int f[2][2]; };
|
||||
struct E { int *g[3]; };
|
||||
struct F { char h[sizeof (int *) * 3]; };
|
||||
constexpr B i = std::bit_cast<B> (A{}); // { dg-message "in 'constexpr' expansion of 'std::bit_cast<" }
|
||||
constexpr A j = std::bit_cast<A> (B{}); // { dg-message "in 'constexpr' expansion of 'std::bit_cast<" }
|
||||
constexpr D k = std::bit_cast<D> (C{}); // { dg-message "in 'constexpr' expansion of 'std::bit_cast<" }
|
||||
constexpr C l = std::bit_cast<C> (D{}); // { dg-message "in 'constexpr' expansion of 'std::bit_cast<" }
|
||||
constexpr F m = std::bit_cast<F> (E{}); // { dg-message "in 'constexpr' expansion of 'std::bit_cast<" }
|
||||
constexpr E n = std::bit_cast<E> (F{}); // { dg-message "in 'constexpr' expansion of 'std::bit_cast<" }
|
Loading…
Add table
Reference in a new issue