mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-08 19:20:44 +08:00
c++: Don't shortcut TREE_CONSTANT vector type CONSTRUCTORs in cxx_eval_constant_expression [PR107295]
The excess precision support broke building skia (dependency of firefox) on ia32 (it has something like the a constexpr variable), but as the other cases show, it is actually a preexisting problem if one uses casts from constants with wider floating point types. The problem is that cxx_eval_constant_expression tries to short-cut processing of TREE_CONSTANT CONSTRUCTORs if they satisfy reduced_constant_expression_p - instead of calling cxx_eval_bare_aggregate on them it just verifies flags and if they are TREE_CONSTANT even after that, just fold. Now, on the testcase we have a TREE_CONSTANT CONSTRUCTOR containing TREE_CONSTANT NOP_EXPR of REAL_CST. And, fold, which isn't recursive, doesn't optimize that into VECTOR_CST, while later on we are only able to optimize VECTOR_CST arithmetics, not arithmetics with vector CONSTRUCTORs. The following patch fixes that by rejecting CONSTRUCTORs with vector type in reduced_constant_expression_p regardless of whether they have CONSTRUCTOR_NO_CLEARING set or not, folding result in cxx_eval_bare_aggregate even if nothing has changed but it wasn't non-constant and removing folding from the TREE_CONSTANT reduced_constant_expression_p short-cut. 2022-10-21 Jakub Jelinek <jakub@redhat.com> PR c++/107295 * constexpr.cc (reduced_constant_expression_p) <case CONSTRUCTOR>: Return false for VECTOR_TYPE CONSTRUCTORs even without CONSTRUCTOR_NO_CLEARING set on them. (cxx_eval_bare_aggregate): If constant but !changed, fold before returning VECTOR_TYPE_P CONSTRUCTOR. (cxx_eval_constant_expression) <case CONSTRUCTOR>: Don't fold TREE_CONSTANT CONSTRUCTOR, just return it. * g++.dg/ext/vector42.C: New test.
This commit is contained in:
parent
bf3b532b52
commit
2cc41601d9
@ -3104,12 +3104,12 @@ reduced_constant_expression_p (tree t)
|
||||
case CONSTRUCTOR:
|
||||
/* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR. */
|
||||
tree field;
|
||||
if (TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
|
||||
/* An initialized vector would have a VECTOR_CST. */
|
||||
return false;
|
||||
if (CONSTRUCTOR_NO_CLEARING (t))
|
||||
{
|
||||
if (TREE_CODE (TREE_TYPE (t)) == VECTOR_TYPE)
|
||||
/* An initialized vector would have a VECTOR_CST. */
|
||||
return false;
|
||||
else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
|
||||
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
|
||||
{
|
||||
/* There must be a valid constant initializer at every array
|
||||
index. */
|
||||
@ -4956,8 +4956,14 @@ cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
|
||||
TREE_SIDE_EFFECTS (ctx->ctor) = side_effects_p;
|
||||
}
|
||||
}
|
||||
if (*non_constant_p || !changed)
|
||||
if (*non_constant_p)
|
||||
return t;
|
||||
if (!changed)
|
||||
{
|
||||
if (VECTOR_TYPE_P (type))
|
||||
t = fold (t);
|
||||
return t;
|
||||
}
|
||||
t = ctx->ctor;
|
||||
if (!t)
|
||||
t = build_constructor (type, NULL);
|
||||
@ -7387,11 +7393,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
|
||||
case CONSTRUCTOR:
|
||||
if (TREE_CONSTANT (t) && reduced_constant_expression_p (t))
|
||||
{
|
||||
/* Don't re-process a constant CONSTRUCTOR, but do fold it to
|
||||
VECTOR_CST if applicable. */
|
||||
/* Don't re-process a constant CONSTRUCTOR. */
|
||||
verify_constructor_flags (t);
|
||||
if (TREE_CONSTANT (t))
|
||||
return fold (t);
|
||||
return t;
|
||||
}
|
||||
r = cxx_eval_bare_aggregate (ctx, t, lval,
|
||||
non_constant_p, overflow_p);
|
||||
|
12
gcc/testsuite/g++.dg/ext/vector42.C
Normal file
12
gcc/testsuite/g++.dg/ext/vector42.C
Normal file
@ -0,0 +1,12 @@
|
||||
// PR c++/107295
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
template <typename T> struct A {
|
||||
typedef T __attribute__((vector_size (sizeof (int)))) V;
|
||||
};
|
||||
template <int, typename T> using B = typename A<T>::V;
|
||||
template <typename T> using V = B<4, T>;
|
||||
using F = V<float>;
|
||||
constexpr F a = F () + 0.0f;
|
||||
constexpr F b = F () + (float) 0.0;
|
||||
constexpr F c = F () + (float) 0.0L;
|
Loading…
x
Reference in New Issue
Block a user