Skip to content

Commit

Permalink
c++: sizeof(expr) in non-templated requires-expr [PR108563]
Browse files Browse the repository at this point in the history
When substituting into sizeof(expr), tsubst_copy_and_build elides
substitution into the operand if args is NULL_TREE, and instead
considers the TREE_TYPE of the operand.  But here the (templated)
operand is a TEMPLATE_ID_EXPR with empty TREE_TYPE, so we can't elide
substitution in this case.

Contrary to the associated comment (dating back to r69130) substituting
args=NULL_TREE should generally work since we do exactly that in e.g.
fold_non_dependent_expr, and I don't see why the operand of sizeof would
be an exception.  So this patch just removes this special case.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?  Diff generated with -w to ignore noisy whitespace changes.

	PR c++/108563

gcc/cp/ChangeLog:

	* pt.cc (tsubst_copy_and_build) <case SIZEOF_EXPR>: Remove
	special case for empty args.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp2a/concepts-requires35.C: New test.
  • Loading branch information
Patrick Palka authored and ouuleilei-bot committed Feb 9, 2023
1 parent b24e9c0 commit 0b6cd3e
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 18 deletions.
25 changes: 7 additions & 18 deletions gcc/cp/pt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20654,25 +20654,14 @@ tsubst_copy_and_build (tree t,
op1 = TREE_TYPE (op1);
bool std_alignof = (TREE_CODE (t) == ALIGNOF_EXPR
&& ALIGNOF_EXPR_STD_P (t));
if (!args)
{
/* When there are no ARGS, we are trying to evaluate a
non-dependent expression from the parser. Trying to do
the substitutions may not work. */
if (!TYPE_P (op1))
op1 = TREE_TYPE (op1);
}
++cp_unevaluated_operand;
++c_inhibit_evaluation_warnings;
if (TYPE_P (op1))
op1 = tsubst (op1, args, complain, in_decl);
else
{
++cp_unevaluated_operand;
++c_inhibit_evaluation_warnings;
if (TYPE_P (op1))
op1 = tsubst (op1, args, complain, in_decl);
else
op1 = tsubst_copy_and_build (op1, args, complain, in_decl);
--cp_unevaluated_operand;
--c_inhibit_evaluation_warnings;
}
op1 = tsubst_copy_and_build (op1, args, complain, in_decl);
--cp_unevaluated_operand;
--c_inhibit_evaluation_warnings;
if (TYPE_P (op1))
r = cxx_sizeof_or_alignof_type (input_location,
op1, TREE_CODE (t), std_alignof,
Expand Down
14 changes: 14 additions & 0 deletions gcc/testsuite/g++.dg/cpp2a/concepts-requires35.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// PR c++/108563
// { dg-do compile { target c++20 } }

template<class T>
struct foo {
static constexpr T value = 0;
};

template<class T>
inline constexpr T foo_v = foo<T>::value;

static_assert(requires { sizeof(foo_v<int>); });
static_assert(requires { requires sizeof(foo_v<int*>) == sizeof(int*); });
static_assert(requires { requires sizeof(foo_v<char>) == sizeof(char); });

0 comments on commit 0b6cd3e

Please sign in to comment.