Commit 56cde077 by Jason Merrill Committed by Jason Merrill

re PR c++/69958 (sizeof... computes wrong size)

	PR c++/69958
	* pt.c (make_argument_pack): New.
	(tsubst_copy) [SIZEOF_EXPR]: Handle partial expansion.
	(tsubst_copy_and_build): Likewise.

From-SVN: r233758
parent 622174b2
2016-02-26 Jason Merrill <jason@redhat.com>
PR c++/69958
* pt.c (make_argument_pack): New.
(tsubst_copy) [SIZEOF_EXPR]: Handle partial expansion.
(tsubst_copy_and_build): Likewise.
2016-02-25 Jason Merrill <jason@redhat.com>
PR c++/69889
......
......@@ -11117,6 +11117,25 @@ get_pattern_parm (tree parm, tree tmpl)
return patparm;
}
/* Make an argument pack out of the TREE_VEC VEC. */
static tree
make_argument_pack (tree vec)
{
tree pack;
tree elt = TREE_VEC_ELT (vec, 0);
if (TYPE_P (elt))
pack = cxx_make_type (TYPE_ARGUMENT_PACK);
else
{
pack = make_node (NONTYPE_ARGUMENT_PACK);
TREE_TYPE (pack) = TREE_TYPE (elt);
TREE_CONSTANT (pack) = 1;
}
SET_ARGUMENT_PACK_ARGS (pack, vec);
return pack;
}
/* Substitute ARGS into the vector or list of template arguments T. */
static tree
......@@ -14066,7 +14085,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
}
case SIZEOF_EXPR:
if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
if (PACK_EXPANSION_P (TREE_OPERAND (t, 0))
|| ARGUMENT_PACK_P (TREE_OPERAND (t, 0)))
{
tree expanded, op = TREE_OPERAND (t, 0);
int len = 0;
......@@ -14077,7 +14097,11 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
++cp_unevaluated_operand;
++c_inhibit_evaluation_warnings;
/* We only want to compute the number of arguments. */
expanded = tsubst_pack_expansion (op, args, complain, in_decl);
if (PACK_EXPANSION_P (op))
expanded = tsubst_pack_expansion (op, args, complain, in_decl);
else
expanded = tsubst_template_args (ARGUMENT_PACK_ARGS (op),
args, complain, in_decl);
--cp_unevaluated_operand;
--c_inhibit_evaluation_warnings;
......@@ -14093,13 +14117,15 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
return error_mark_node;
else if (PACK_EXPANSION_P (expanded)
|| (TREE_CODE (expanded) == TREE_VEC
&& len > 0
&& PACK_EXPANSION_P (TREE_VEC_ELT (expanded, len-1))))
&& pack_expansion_args_count (expanded)))
{
if (TREE_CODE (expanded) == TREE_VEC)
expanded = TREE_VEC_ELT (expanded, len - 1);
if (PACK_EXPANSION_P (expanded))
/* OK. */;
else if (TREE_VEC_LENGTH (expanded) == 1)
expanded = TREE_VEC_ELT (expanded, 0);
else
PACK_EXPANSION_SIZEOF_P (expanded) = true;
expanded = make_argument_pack (expanded);
if (TYPE_P (expanded))
return cxx_sizeof_or_alignof_type (expanded, SIZEOF_EXPR,
......@@ -16162,7 +16188,8 @@ tsubst_copy_and_build (tree t,
length, stride, TREE_TYPE (op1)));
}
case SIZEOF_EXPR:
if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
if (PACK_EXPANSION_P (TREE_OPERAND (t, 0))
|| ARGUMENT_PACK_P (TREE_OPERAND (t, 0)))
RETURN (tsubst_copy (t, args, complain, in_decl));
/* Fall through */
......
// PR c++/69958
// { dg-do compile { target c++11 } }
typedef decltype(sizeof(int)) size_t;
template <typename...Ts>
struct list { };
template <size_t N>
struct size { };
template <typename...Ts>
using size_for = size<sizeof...(Ts)>;
template<class T, class U> struct assert_same;
template<class T> struct assert_same<T,T> {};
template <typename T, typename...Ts>
using wrapped = list<T, size_for<T, Ts...>>;
// This assertion fails (produces size<4>)
assert_same<
list<float, size<5>>,
wrapped<float, int, double, char, unsigned>> a3;
template <typename T, typename...Ts>
using wrapped2 = list<T, size_for<Ts..., T>>;
// This assertion fails (produces size<2>)
assert_same<
list<float, size<5>>,
wrapped2<float, int, double, char, unsigned>> a4;
// PR c++/69958
// { dg-do compile { target c++11 } }
typedef decltype(sizeof(int)) size_t;
template <typename...Ts>
struct list { };
template <size_t N>
struct size { };
template <unsigned...Ts>
using size_for = size<sizeof...(Ts)>;
template<class T, class U> struct assert_same;
template<class T> struct assert_same<T,T> {};
template <typename T, unsigned...Ts>
using wrapped = list<T, size_for<0, Ts...>>;
// This assertion fails (produces size<4>)
assert_same<
list<float, size<5>>,
wrapped<float,2,3,4,5>> a3;
template <typename T, unsigned...Ts>
using wrapped2 = list<T, size_for<Ts..., 0>>;
// This assertion fails (produces size<2>)
assert_same<
list<float, size<5>>,
wrapped2<float,2,3,4,5>> a4;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment