diff options
Diffstat (limited to 'gcc/cp/pt.c')
-rw-r--r-- | gcc/cp/pt.c | 98 |
1 files changed, 70 insertions, 28 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 104d4dd..c3fb5e8 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -12031,14 +12031,16 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (PACK_EXPANSION_P (TREE_OPERAND (t, 0))) { - tree expanded; + tree expanded, op = TREE_OPERAND (t, 0); int len = 0; + if (SIZEOF_EXPR_TYPE_P (t)) + op = TREE_TYPE (op); + ++cp_unevaluated_operand; ++c_inhibit_evaluation_warnings; /* We only want to compute the number of arguments. */ - expanded = tsubst_pack_expansion (TREE_OPERAND (t, 0), args, - complain, in_decl); + expanded = tsubst_pack_expansion (op, args, complain, in_decl); --cp_unevaluated_operand; --c_inhibit_evaluation_warnings; @@ -12065,6 +12067,16 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) else return build_int_cst (size_type_node, len); } + if (SIZEOF_EXPR_TYPE_P (t)) + { + r = tsubst_copy (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); + SIZEOF_EXPR_TYPE_P (r) = 1; + return r; + } /* Fall through */ case INDIRECT_REF: @@ -13468,31 +13480,56 @@ tsubst_copy_and_build (tree t, /* Fall through */ case ALIGNOF_EXPR: - op1 = TREE_OPERAND (t, 0); - 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); - } - else - { - ++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); - --cp_unevaluated_operand; - --c_inhibit_evaluation_warnings; - } - if (TYPE_P (op1)) - RETURN (cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), - complain & tf_error)); - else - RETURN (cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t), - complain & tf_error)); + { + tree r; + + op1 = TREE_OPERAND (t, 0); + if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t)) + op1 = TREE_TYPE (op1); + 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); + } + else + { + ++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); + --cp_unevaluated_operand; + --c_inhibit_evaluation_warnings; + } + if (TYPE_P (op1)) + r = cxx_sizeof_or_alignof_type (op1, TREE_CODE (t), + complain & tf_error); + else + r = cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t), + complain & tf_error); + if (TREE_CODE (t) == SIZEOF_EXPR && r != error_mark_node) + { + if (TREE_CODE (r) != SIZEOF_EXPR || TYPE_P (op1)) + { + if (TYPE_P (op1)) + { + r = build_min (SIZEOF_EXPR, size_type_node, + build1 (NOP_EXPR, op1, error_mark_node)); + SIZEOF_EXPR_TYPE_P (r) = 1; + } + else + r = build_min (SIZEOF_EXPR, size_type_node, op1); + TREE_SIDE_EFFECTS (r) = 0; + TREE_READONLY (r) = 1; + } + SET_EXPR_LOCATION (r, EXPR_LOCATION (t)); + } + RETURN (r); + } case AT_ENCODE_EXPR: { @@ -19288,6 +19325,9 @@ value_dependent_expression_p (tree expression) } case SIZEOF_EXPR: + if (SIZEOF_EXPR_TYPE_P (expression)) + return dependent_type_p (TREE_TYPE (TREE_OPERAND (expression, 0))); + /* FALLTHRU */ case ALIGNOF_EXPR: case TYPEID_EXPR: /* A `sizeof' expression is value-dependent if the operand is @@ -19627,6 +19667,8 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees, case TRAIT_EXPR: { tree op = TREE_OPERAND (*tp, 0); + if (code == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (*tp)) + op = TREE_TYPE (op); if (TYPE_P (op)) { if (dependent_type_p (op) |