Hi! Now that SIZEOF_EXPR isn't folded immediately, e.g. REAL_TYPE can be an argument of it, and tsubst_copy* doesn't handle that, but tsubst does. Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2012-10-15 Jakub Jelinek <ja...@redhat.com> PR c++/54844 * pt.c (tsubst_copy, tsubst_copy_and_build) <case SIZEOF_EXPR>: Use tsubst instead of tsubst_copy* on types. * g++.dg/template/sizeof14.C: New test. --- gcc/cp/pt.c.jj 2012-10-15 11:45:30.000000000 +0200 +++ gcc/cp/pt.c 2012-10-15 12:08:10.232364822 +0200 @@ -12104,8 +12104,8 @@ tsubst_copy (tree t, tree args, tsubst_f } if (SIZEOF_EXPR_TYPE_P (t)) { - r = tsubst_copy (TREE_TYPE (TREE_OPERAND (t, 0)), - args, complain, in_decl); + r = tsubst (TREE_TYPE (TREE_OPERAND (t, 0)), + args, complain, in_decl); r = build1 (NOP_EXPR, r, error_mark_node); r = build1 (SIZEOF_EXPR, tsubst (TREE_TYPE (t), args, complain, in_decl), r); @@ -13533,10 +13533,13 @@ tsubst_copy_and_build (tree t, { ++cp_unevaluated_operand; ++c_inhibit_evaluation_warnings; - op1 = tsubst_copy_and_build (op1, args, complain, in_decl, - /*function_p=*/false, - /*integral_constant_expression_p=*/ - false); + if (TYPE_P (op1)) + op1 = tsubst (op1, args, complain, in_decl); + else + op1 = tsubst_copy_and_build (op1, args, complain, in_decl, + /*function_p=*/false, + /*integral_constant_expression_p=*/ + false); --cp_unevaluated_operand; --c_inhibit_evaluation_warnings; } --- gcc/testsuite/g++.dg/template/sizeof14.C.jj 2012-10-15 12:01:41.596492966 +0200 +++ gcc/testsuite/g++.dg/template/sizeof14.C 2012-10-15 12:01:31.000000000 +0200 @@ -0,0 +1,4 @@ +// PR c++/54844 +// { dg-do compile } +template <int N> int fn () { return sizeof (double); } +int var = fn <0> (); Jakub