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> 2016-02-25 Jason Merrill <jason@redhat.com>
PR c++/69889 PR c++/69889
......
...@@ -11117,6 +11117,25 @@ get_pattern_parm (tree parm, tree tmpl) ...@@ -11117,6 +11117,25 @@ get_pattern_parm (tree parm, tree tmpl)
return patparm; 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. */ /* Substitute ARGS into the vector or list of template arguments T. */
static tree static tree
...@@ -14066,7 +14085,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -14066,7 +14085,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
} }
case SIZEOF_EXPR: 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); tree expanded, op = TREE_OPERAND (t, 0);
int len = 0; int len = 0;
...@@ -14077,7 +14097,11 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -14077,7 +14097,11 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
++cp_unevaluated_operand; ++cp_unevaluated_operand;
++c_inhibit_evaluation_warnings; ++c_inhibit_evaluation_warnings;
/* We only want to compute the number of arguments. */ /* 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; --cp_unevaluated_operand;
--c_inhibit_evaluation_warnings; --c_inhibit_evaluation_warnings;
...@@ -14093,13 +14117,15 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) ...@@ -14093,13 +14117,15 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
return error_mark_node; return error_mark_node;
else if (PACK_EXPANSION_P (expanded) else if (PACK_EXPANSION_P (expanded)
|| (TREE_CODE (expanded) == TREE_VEC || (TREE_CODE (expanded) == TREE_VEC
&& len > 0 && pack_expansion_args_count (expanded)))
&& PACK_EXPANSION_P (TREE_VEC_ELT (expanded, len-1))))
{ {
if (TREE_CODE (expanded) == TREE_VEC) if (PACK_EXPANSION_P (expanded))
expanded = TREE_VEC_ELT (expanded, len - 1); /* OK. */;
else if (TREE_VEC_LENGTH (expanded) == 1)
expanded = TREE_VEC_ELT (expanded, 0);
else else
PACK_EXPANSION_SIZEOF_P (expanded) = true; expanded = make_argument_pack (expanded);
if (TYPE_P (expanded)) if (TYPE_P (expanded))
return cxx_sizeof_or_alignof_type (expanded, SIZEOF_EXPR, return cxx_sizeof_or_alignof_type (expanded, SIZEOF_EXPR,
...@@ -16162,7 +16188,8 @@ tsubst_copy_and_build (tree t, ...@@ -16162,7 +16188,8 @@ tsubst_copy_and_build (tree t,
length, stride, TREE_TYPE (op1))); length, stride, TREE_TYPE (op1)));
} }
case SIZEOF_EXPR: 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)); RETURN (tsubst_copy (t, args, complain, in_decl));
/* Fall through */ /* 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