aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/parser.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2012-10-05 21:30:39 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2012-10-05 21:30:39 +0200
commit0d23cf7a4f9609763b600a7e9edf81e78e3f7a55 (patch)
treecdaa38c550b113c61c8a82ec24f6b0febfad9e1d /gcc/cp/parser.c
parent94645a02dca8b5b103278ec48b4c7e0fe82ccfbf (diff)
downloadgcc-0d23cf7a4f9609763b600a7e9edf81e78e3f7a55.zip
gcc-0d23cf7a4f9609763b600a7e9edf81e78e3f7a55.tar.gz
gcc-0d23cf7a4f9609763b600a7e9edf81e78e3f7a55.tar.bz2
cp-tree.h (SIZEOF_EXPR_TYPE_P): Define.
cp/ * cp-tree.h (SIZEOF_EXPR_TYPE_P): Define. * tree.c (cp_tree_equal): Handle SIZEOF_EXPR with SIZEOF_EXPR_TYPE_P. * mangle.c (write_expression): Likewise. * cxx-pretty-print.c (pp_cxx_unary_expression): Likewise. * error.c (dump_expr): Likewise. * parser.c (cp_parser_unary_expression): For sizeof call cxx_sizeof_or_alignof_{type,expr} just for diagnostics and return SIZEOF_EXPR with the operand. * pt.c (tsubst_copy, tsubst_copy_and_build): For SIZEOF_EXPR, call cxx_sizeof_or_alignof_{type,expr} for diagnostics, but return SIZEOF_EXPR with tsubsted operand. (value_dependent_expression_p): Handle SIZEOF_EXPR with SIZEOF_EXPR_TYPE_P. (instantiation_dependent_r): Likewise. * call.c (null_ptr_cst_p): Call maybe_constant_value for C++98. * semantics.c (finish_call_expr): Call sizeof_pointer_memaccess_warning if needed. (cxx_eval_constant_expression): Handle SIZEOF_EXPR. (potential_constant_expression_1): Remove early exit for C++98. Handle PROPERTY_REF. * decl.c (duplicate_decls): When redeclaring a builtin function, keep the merged decl builtin also if newdecl is a gnu_inline inline definition. (fold_sizeof_expr_r): New function. (compute_array_index_type): Fold SIZEOF_EXPRs in itype. * cp-gimplify.c (cp_genericize_r): Fold SIZEOF_EXPR. * typeck.c (cp_build_binary_op): For warn_for_sign_compare try harder using maybe_constant_value to get INTEGER_CSTs. * decl.c (stabilize_vla_size): Call pointer_set_destroy at the end. testsuite/ * g++.dg/torture/Wsizeof-pointer-memaccess1.C: New test. * g++.dg/torture/Wsizeof-pointer-memaccess2.C: New test. * g++.dg/warn/Wsign-compare-5.C: New test. * g++.dg/warn/Wsizeof-pointer-memaccess-1.C: New test. * g++.dg/warn/Wnull-conversion-1.C: For c++11 add dg-error. * g++.dg/ext/builtin30.C: New test. * g++.dg/ext/vla12.C: New test. * gcc.dg/builtins-85.c: New test. libstdc++-v3/ * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust line numbers. From-SVN: r192141
Diffstat (limited to 'gcc/cp/parser.c')
-rw-r--r--gcc/cp/parser.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 155b51a..baaa809 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -6383,17 +6383,19 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
case RID_ALIGNOF:
case RID_SIZEOF:
{
- tree operand;
+ tree operand, ret;
enum tree_code op;
+ location_t first_loc;
op = keyword == RID_ALIGNOF ? ALIGNOF_EXPR : SIZEOF_EXPR;
/* Consume the token. */
cp_lexer_consume_token (parser->lexer);
+ first_loc = cp_lexer_peek_token (parser->lexer)->location;
/* Parse the operand. */
operand = cp_parser_sizeof_operand (parser, keyword);
if (TYPE_P (operand))
- return cxx_sizeof_or_alignof_type (operand, op, true);
+ ret = cxx_sizeof_or_alignof_type (operand, op, true);
else
{
/* ISO C++ defines alignof only with types, not with
@@ -6404,8 +6406,29 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
"ISO C++ does not allow %<alignof%> "
"with a non-type");
- return cxx_sizeof_or_alignof_expr (operand, op, true);
+ ret = cxx_sizeof_or_alignof_expr (operand, op, true);
}
+ /* For SIZEOF_EXPR, just issue diagnostics, but keep
+ SIZEOF_EXPR with the original operand. */
+ if (op == SIZEOF_EXPR && ret != error_mark_node)
+ {
+ if (TREE_CODE (ret) != SIZEOF_EXPR || TYPE_P (operand))
+ {
+ if (!processing_template_decl && TYPE_P (operand))
+ {
+ ret = build_min (SIZEOF_EXPR, size_type_node,
+ build1 (NOP_EXPR, operand,
+ error_mark_node));
+ SIZEOF_EXPR_TYPE_P (ret) = 1;
+ }
+ else
+ ret = build_min (SIZEOF_EXPR, size_type_node, operand);
+ TREE_SIDE_EFFECTS (ret) = 0;
+ TREE_READONLY (ret) = 1;
+ }
+ SET_EXPR_LOCATION (ret, first_loc);
+ }
+ return ret;
}
case RID_NEW: