diff options
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 98 | ||||
-rw-r--r-- | gcc/cp/call.c | 12 | ||||
-rw-r--r-- | gcc/cp/cp-gimplify.c | 19 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 34 | ||||
-rw-r--r-- | gcc/cp/cvt.c | 8 | ||||
-rw-r--r-- | gcc/cp/cxx-pretty-print.c | 10 | ||||
-rw-r--r-- | gcc/cp/decl.c | 113 | ||||
-rw-r--r-- | gcc/cp/decl2.c | 4 | ||||
-rw-r--r-- | gcc/cp/error.c | 4 | ||||
-rw-r--r-- | gcc/cp/mangle.c | 8 | ||||
-rw-r--r-- | gcc/cp/name-lookup.c | 1 | ||||
-rw-r--r-- | gcc/cp/parser.c | 29 | ||||
-rw-r--r-- | gcc/cp/pt.c | 103 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 56 | ||||
-rw-r--r-- | gcc/cp/tree.c | 6 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 9 |
16 files changed, 408 insertions, 106 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 376cbf671..525efe417 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,93 @@ +2012-10-07 Paolo Carlini <paolo.carlini@oracle.com> + + * pt.c (fold_non_dependent_expr_sfinae): Remove static specifier. + (tsubst_copy_and_build): Use get_target_expr_sfinae. + * call.c (build_conditional_expr_1, convert_like_real): Likewise. + * cvt.c (build_up_reference): Likewise. + (ocp_convert): Use abstract_virtuals_error_sfinae. + (build_up_reference): Propagate complain to cp_build_addr_expr. + * decl.c (compute_array_index_type): Use fold_non_dependent_expr_sfinae. + * cp-tree.h: Update declarations. + + * cvt.c (build_expr_type_conversion): Tidy. + + * tree.c (stabilize_aggr_init): Change to static. + +2012-10-07 Paolo Carlini <paolo.carlini@oracle.com> + + PR c++/51422 + * semantics.c (is_normal_capture_proxy): Return true for + error_mark_node as DECL_VALUE_EXPR. + +2012-10-05 Jakub Jelinek <jakub@redhat.com> + + * 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. + +2012-10-04 Arnaud Charlet <charlet@adacore.com> + + * decl2.c (cp_write_global_declarations): Fix handling of + -fdump-ada-spec*. + +2012-10-03 Jakub Jelinek <jakub@redhat.com> + + PR c++/54777 + * semantics.c (cxx_eval_constant_expression) <case COMPOUND_EXPR>: If + not ignoring the second operand, pass the original second operand + and not one with stripped nops to cxx_eval_constant_expression. + +2012-10-01 Jason Merrill <jason@redhat.com> + + * decl.c (check_initializer): Set DECL_NONTRIVIALLY_INITIALIZED_P + for a constructor call. + (decl_jump_unsafe): So don't bother checking + type_has_nontrivial_default_init. + * call.c (set_up_extended_ref_temp): Set + DECL_NONTRIVIALLY_INITIALIZED_P. + + * cp-tree.h (TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK): New. + (DECL_FRIEND_P, DECL_ANTICIPATED): Use it. + (TYPE_FUNCTION_OR_TEMPLATE_DECL_P): New. + * name-lookup.c (hidden_name_p): Use it. + + * cp-tree.h (DECL_PRETTY_FUNCTION_P): Just look at the name. + * decl.c (cp_make_fname_decl): Adjust. + +2012-09-30 Sharad Singhai <singhai@google.com> + + * decl2.c (cp_write_global_declarations): Use a different method + to determine if the dump has ben initialized. + 2012-09-29 Paolo Carlini <paolo.carlini@oracle.com> PR c++/54738 @@ -367,6 +457,14 @@ (ARGUMENT_PACK_INCOMPLETE_P): Use TREE_ADDRESSABLE instead of TREE_LANG_FLAG_0 on TREE_VECs. +2012-08-20 Florian Weimer <fweimer@redhat.com> + + PR c++/19351 + * call.c (build_operator_new_call): Add size_check argument and + evaluate it. + * cp-tree.h (build_operator_new_call): Adjust declaration. + * init.c (build_new_1): Compute array size check and apply it. + 2012-08-20 Paolo Carlini <paolo.carlini@oracle.com> PR c++/10416 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 6f7e34669..f58dc8a52 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -557,7 +557,7 @@ null_ptr_cst_p (tree t) { /* Core issue 903 says only literal 0 is a null pointer constant. */ if (cxx_dialect < cxx0x) - t = integral_constant_value (t); + t = maybe_constant_value (t); STRIP_NOPS (t); if (integer_zerop (t) && !TREE_OVERFLOW (t)) return true; @@ -4777,7 +4777,7 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3, but now we sometimes wrap them in NOP_EXPRs so the test would fail. */ if (CLASS_TYPE_P (TREE_TYPE (result))) - result = get_target_expr (result); + result = get_target_expr_sfinae (result, complain); /* If this expression is an rvalue, but might be mistaken for an lvalue, we must add a NON_LVALUE_EXPR. */ result = rvalue (result); @@ -5883,7 +5883,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, field = next_initializable_field (DECL_CHAIN (field)); CONSTRUCTOR_APPEND_ELT (vec, field, size_int (len)); new_ctor = build_constructor (totype, vec); - return get_target_expr (new_ctor); + return get_target_expr_sfinae (new_ctor, complain); } case ck_aggr: @@ -5899,7 +5899,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, return fold_if_not_in_template (expr); } expr = reshape_init (totype, expr, complain); - return get_target_expr (digest_init (totype, expr, complain)); + return get_target_expr_sfinae (digest_init (totype, expr, complain), + complain); default: break; @@ -8792,6 +8793,9 @@ set_up_extended_ref_temp (tree decl, tree expr, VEC(tree,gc) **cleanups, TARGET_EXPR_INITIAL (expr) = extend_ref_init_temps (decl, TARGET_EXPR_INITIAL (expr), cleanups); + /* Any reference temp has a non-trivial initializer. */ + DECL_NONTRIVIALLY_INITIALIZED_P (var) = true; + /* If the initializer is constant, put it in DECL_INITIAL so we get static initialization and use in constant expressions. */ init = maybe_constant_init (expr); diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index dd2ef067c..6178993fe 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -1,6 +1,7 @@ /* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c. - Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, + 2012 Free Software Foundation, Inc. Contributed by Jason Merrill <jason@redhat.com> @@ -1119,6 +1120,22 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) genericize_break_stmt (stmt_p); else if (TREE_CODE (stmt) == OMP_FOR) genericize_omp_for_stmt (stmt_p, walk_subtrees, data); + else if (TREE_CODE (stmt) == SIZEOF_EXPR) + { + if (SIZEOF_EXPR_TYPE_P (stmt)) + *stmt_p + = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (stmt, 0)), + SIZEOF_EXPR, false); + else if (TYPE_P (TREE_OPERAND (stmt, 0))) + *stmt_p = cxx_sizeof_or_alignof_type (TREE_OPERAND (stmt, 0), + SIZEOF_EXPR, false); + else + *stmt_p = cxx_sizeof_or_alignof_expr (TREE_OPERAND (stmt, 0), + SIZEOF_EXPR, false); + if (*stmt_p == error_mark_node) + *stmt_p = size_one_node; + return NULL; + } pointer_set_insert (p_set, *stmt_p); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f4370224d..00f2d4a25 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -56,7 +56,6 @@ c-common.h, not after. AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR) PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF, SCOPE_REF) PAREN_STRING_LITERAL (in STRING_CST) - DECL_PRETTY_FUNCTION_P (in VAR_DECL) KOENIG_LOOKUP_P (in CALL_EXPR) STATEMENT_LIST_NO_SCOPE (in STATEMENT_LIST). EXPR_STMT_STMT_EXPR_RESULT (in EXPR_STMT) @@ -79,6 +78,7 @@ c-common.h, not after. OVL_ARG_DEPENDENT (in OVERLOAD) PACK_EXPANSION_LOCAL_P (in *_PACK_EXPANSION) TINFO_RECHECK_ACCESS_P (in TEMPLATE_INFO) + SIZEOF_EXPR_TYPE_P (in SIZEOF_EXPR) 1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE) TI_PENDING_TEMPLATE_FLAG. TEMPLATE_PARMS_FOR_INLINE. @@ -203,6 +203,13 @@ c-common.h, not after. #define VAR_OR_FUNCTION_DECL_CHECK(NODE) \ TREE_CHECK2(NODE,VAR_DECL,FUNCTION_DECL) +#define TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK(NODE) \ + TREE_CHECK3(NODE,TYPE_DECL,TEMPLATE_DECL,FUNCTION_DECL) + +#define TYPE_FUNCTION_OR_TEMPLATE_DECL_P(NODE) \ + (TREE_CODE (NODE) == TYPE_DECL || TREE_CODE (NODE) == TEMPLATE_DECL \ + || TREE_CODE (NODE) == FUNCTION_DECL) + #define VAR_FUNCTION_OR_PARM_DECL_CHECK(NODE) \ TREE_CHECK3(NODE,VAR_DECL,FUNCTION_DECL,PARM_DECL) @@ -1876,8 +1883,8 @@ struct GTY(()) lang_decl_base { unsigned initialized_in_class : 1; /* var or fn */ unsigned repo_available_p : 1; /* var or fn */ unsigned threadprivate_or_deleted_p : 1; /* var or fn */ - unsigned anticipated_p : 1; /* fn or type */ - unsigned friend_attr : 1; /* fn or type */ + unsigned anticipated_p : 1; /* fn, type or template */ + unsigned friend_attr : 1; /* fn, type or template */ unsigned template_conv_p : 1; /* var or template */ unsigned odr_used : 1; /* var or fn */ unsigned u2sel : 1; @@ -2265,12 +2272,13 @@ struct GTY((variable_size)) lang_decl { /* Nonzero for a VAR_DECL means that the variable's initialization (if any) has been processed. (In general, DECL_INITIALIZED_P is - !DECL_EXTERN, but static data members may be initialized even if + !DECL_EXTERNAL, but static data members may be initialized even if not defined.) */ #define DECL_INITIALIZED_P(NODE) \ (TREE_LANG_FLAG_1 (VAR_DECL_CHECK (NODE))) -/* Nonzero for a VAR_DECL iff an explicit initializer was provided. */ +/* Nonzero for a VAR_DECL iff an explicit initializer was provided + or a non-trivial constructor is called. */ #define DECL_NONTRIVIALLY_INITIALIZED_P(NODE) \ (TREE_LANG_FLAG_3 (VAR_DECL_CHECK (NODE))) @@ -2294,7 +2302,9 @@ struct GTY((variable_size)) lang_decl { /* Nonzero for DECL means that this decl is just a friend declaration, and should not be added to the list of members for this class. */ -#define DECL_FRIEND_P(NODE) (DECL_LANG_SPECIFIC (NODE)->u.base.friend_attr) +#define DECL_FRIEND_P(NODE) \ + (DECL_LANG_SPECIFIC (TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK (NODE)) \ + ->u.base.friend_attr) /* A TREE_LIST of the types which have befriended this FUNCTION_DECL. */ #define DECL_BEFRIENDING_CLASSES(NODE) \ @@ -2410,7 +2420,8 @@ struct GTY((variable_size)) lang_decl { /* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a template function. */ #define DECL_PRETTY_FUNCTION_P(NODE) \ - (TREE_LANG_FLAG_0 (VAR_DECL_CHECK (NODE))) + (DECL_NAME (NODE) \ + && !strcmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__PRETTY_FUNCTION__")) /* The _TYPE context in which this _DECL appears. This field holds the class where a virtual function instance is actually defined. */ @@ -3101,7 +3112,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) declared inside a class. In the latter case DECL_HIDDEN_FRIEND_P will be set. */ #define DECL_ANTICIPATED(NODE) \ - (DECL_LANG_SPECIFIC (DECL_COMMON_CHECK (NODE))->u.base.anticipated_p) + (DECL_LANG_SPECIFIC (TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK (NODE)) \ + ->u.base.anticipated_p) /* Nonzero if NODE is a FUNCTION_DECL which was declared as a friend within a class but has not been declared in the surrounding scope. @@ -4044,6 +4056,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define CONVERT_EXPR_VBASE_PATH(NODE) \ TREE_LANG_FLAG_0 (CONVERT_EXPR_CHECK (NODE)) +/* True if SIZEOF_EXPR argument is type. */ +#define SIZEOF_EXPR_TYPE_P(NODE) \ + TREE_LANG_FLAG_0 (SIZEOF_EXPR_CHECK (NODE)) + /* An enumeration of the kind of tags that C++ accepts. */ enum tag_types { none_type = 0, /* Not a tag type. */ @@ -5395,6 +5411,7 @@ extern tree build_non_dependent_expr (tree); extern void make_args_non_dependent (VEC(tree,gc) *); extern bool reregister_specialization (tree, tree, tree); extern tree fold_non_dependent_expr (tree); +extern tree fold_non_dependent_expr_sfinae (tree, tsubst_flags_t); extern bool alias_type_or_template_p (tree); extern bool alias_template_specialization_p (tree); extern bool explicit_class_specialization_p (tree); @@ -5684,7 +5701,6 @@ extern void lang_check_failed (const char *, int, const char *) ATTRIBUTE_NORETURN; extern tree stabilize_expr (tree, tree *); extern void stabilize_call (tree, tree *); -extern void stabilize_aggr_init (tree, tree *); extern bool stabilize_init (tree, tree *); extern tree add_stmt_to_compound (tree, tree); extern void init_tree (void); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 86f01abf2..d30c7e530 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -339,12 +339,12 @@ build_up_reference (tree type, tree arg, int flags, tree decl, LOOKUP_ONLYCONVERTING|DIRECT_BIND); } else if (!(flags & DIRECT_BIND) && ! lvalue_p (arg)) - return get_target_expr (arg); + return get_target_expr_sfinae (arg, complain); /* If we had a way to wrap this up, and say, if we ever needed its address, transform all occurrences of the register, into a memory reference we could win better. */ - rval = cp_build_addr_expr (arg, tf_warning_or_error); + rval = cp_build_addr_expr (arg, complain); if (rval == error_mark_node) return error_mark_node; @@ -842,7 +842,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags, ctor = e; - if (abstract_virtuals_error (NULL_TREE, type)) + if (abstract_virtuals_error_sfinae (NULL_TREE, type, complain)) return error_mark_node; if (BRACE_ENCLOSED_INITIALIZER_P (ctor)) @@ -1514,8 +1514,6 @@ build_expr_type_conversion (int desires, tree expr, bool complain) "converting NULL to non-pointer type"); } - basetype = TREE_TYPE (expr); - if (basetype == error_mark_node) return error_mark_node; diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c index 03d9149f4..ce64a7b23 100644 --- a/gcc/cp/cxx-pretty-print.c +++ b/gcc/cp/cxx-pretty-print.c @@ -1,6 +1,6 @@ /* Implementation of subroutines for the GNU C++ pretty-printer. Copyright (C) 2003, 2004, 2005, 2007, 2008, - 2009, 2010, 2011 Free Software Foundation, Inc. + 2009, 2010, 2011, 2012 Free Software Foundation, Inc. Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> This file is part of GCC. @@ -798,7 +798,13 @@ pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t) case ALIGNOF_EXPR: pp_cxx_ws_string (pp, code == SIZEOF_EXPR ? "sizeof" : "__alignof__"); pp_cxx_whitespace (pp); - if (TYPE_P (TREE_OPERAND (t, 0))) + if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t)) + { + pp_cxx_left_paren (pp); + pp_cxx_type_id (pp, TREE_TYPE (TREE_OPERAND (t, 0))); + pp_cxx_right_paren (pp); + } + else if (TYPE_P (TREE_OPERAND (t, 0))) { pp_cxx_left_paren (pp); pp_cxx_type_id (pp, TREE_OPERAND (t, 0)); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 078b14866..c162734cd 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -2160,39 +2160,40 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) DECL_ARGUMENTS (olddecl) = DECL_ARGUMENTS (newdecl); DECL_RESULT (olddecl) = DECL_RESULT (newdecl); } + /* If redeclaring a builtin function, it stays built in + if newdecl is a gnu_inline definition, or if newdecl is just + a declaration. */ + if (DECL_BUILT_IN (olddecl) + && (new_defines_function ? GNU_INLINE_P (newdecl) : types_match)) + { + DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl); + DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl); + /* If we're keeping the built-in definition, keep the rtl, + regardless of declaration matches. */ + COPY_DECL_RTL (olddecl, newdecl); + if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL) + { + enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl); + switch (fncode) + { + /* If a compatible prototype of these builtin functions + is seen, assume the runtime implements it with the + expected semantics. */ + case BUILT_IN_STPCPY: + if (builtin_decl_explicit_p (fncode)) + set_builtin_decl_implicit_p (fncode, true); + break; + default: + break; + } + } + } if (new_defines_function) /* If defining a function declared with other language linkage, use the previously declared language linkage. */ SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl)); else if (types_match) { - /* If redeclaring a builtin function, and not a definition, - it stays built in. */ - if (DECL_BUILT_IN (olddecl)) - { - DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl); - DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl); - /* If we're keeping the built-in definition, keep the rtl, - regardless of declaration matches. */ - COPY_DECL_RTL (olddecl, newdecl); - if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL) - { - enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl); - switch (fncode) - { - /* If a compatible prototype of these builtin functions - is seen, assume the runtime implements it with the - expected semantics. */ - case BUILT_IN_STPCPY: - if (builtin_decl_explicit_p (fncode)) - set_builtin_decl_implicit_p (fncode, true); - break; - default: - break; - } - } - } - DECL_RESULT (newdecl) = DECL_RESULT (olddecl); /* Don't clear out the arguments if we're just redeclaring a function. */ @@ -2679,8 +2680,7 @@ decl_jump_unsafe (tree decl) type = strip_array_types (type); - if (type_has_nontrivial_default_init (TREE_TYPE (decl)) - || DECL_NONTRIVIALLY_INITIALIZED_P (decl)) + if (DECL_NONTRIVIALLY_INITIALIZED_P (decl)) return 2; if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))) @@ -3829,7 +3829,6 @@ cp_make_fname_decl (location_t loc, tree id, int type_dep) /* As we're using pushdecl_with_scope, we must set the context. */ DECL_CONTEXT (decl) = current_function_decl; - DECL_PRETTY_FUNCTION_P (decl) = type_dep; TREE_STATIC (decl) = 1; TREE_READONLY (decl) = 1; @@ -5582,6 +5581,11 @@ check_initializer (tree decl, tree init, int flags, VEC(tree,gc) **cleanups) { init_code = build_aggr_init_full_exprs (decl, init, flags); + /* A constructor call is a non-trivial initializer even if + it isn't explicitly written. */ + if (TREE_SIDE_EFFECTS (init_code)) + DECL_NONTRIVIALLY_INITIALIZED_P (decl) = true; + /* If this is a constexpr initializer, expand_default_init will have returned an INIT_EXPR rather than a CALL_EXPR. In that case, pull the initializer back out and pass it down into @@ -7928,6 +7932,36 @@ stabilize_vla_size (tree size) struct pointer_set_t *pset = pointer_set_create (); /* Break out any function calls into temporary variables. */ cp_walk_tree (&size, stabilize_save_expr_r, pset, pset); + pointer_set_destroy (pset); +} + +/* Helper function for compute_array_index_type. Look for SIZEOF_EXPR + not inside of SAVE_EXPR and fold them. */ + +static tree +fold_sizeof_expr_r (tree *expr_p, int *walk_subtrees, void *data) +{ + tree expr = *expr_p; + if (TREE_CODE (expr) == SAVE_EXPR || TYPE_P (expr)) + *walk_subtrees = 0; + else if (TREE_CODE (expr) == SIZEOF_EXPR) + { + *(bool *)data = true; + if (SIZEOF_EXPR_TYPE_P (expr)) + expr = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (expr, 0)), + SIZEOF_EXPR, false); + else if (TYPE_P (TREE_OPERAND (expr, 0))) + expr = cxx_sizeof_or_alignof_type (TREE_OPERAND (expr, 0), SIZEOF_EXPR, + false); + else + expr = cxx_sizeof_or_alignof_expr (TREE_OPERAND (expr, 0), SIZEOF_EXPR, + false); + if (expr == error_mark_node) + expr = size_one_node; + *expr_p = expr; + *walk_subtrees = 0; + } + return NULL; } /* Given the SIZE (i.e., number of elements) in an array, compute an @@ -7956,7 +7990,7 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) NOP_EXPR with TREE_SIDE_EFFECTS; don't fold in that case. */; else { - size = fold_non_dependent_expr (size); + size = fold_non_dependent_expr_sfinae (size, complain); if (CLASS_TYPE_P (type) && CLASSTYPE_LITERAL_P (type)) @@ -8123,8 +8157,21 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain) processing_template_decl = saved_processing_template_decl; if (!TREE_CONSTANT (itype)) - /* A variable sized array. */ - itype = variable_size (itype); + { + /* A variable sized array. */ + itype = variable_size (itype); + if (TREE_CODE (itype) != SAVE_EXPR) + { + /* Look for SIZEOF_EXPRs in itype and fold them, otherwise + they might survive till gimplification. */ + tree newitype = itype; + bool found = false; + cp_walk_tree_without_duplicates (&newitype, + fold_sizeof_expr_r, &found); + if (found) + itype = variable_size (fold (newitype)); + } + } /* Make sure that there was no overflow when creating to a signed index type. (For example, on a 32-bit machine, an array with size 2^32 - 1 is too big.) */ diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index 4cff0516d..87e38d3bf 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3698,9 +3698,9 @@ cp_write_global_declarations (void) cgraph_process_same_body_aliases (); /* Handle -fdump-ada-spec[-slim] */ - if (dump_enabled_p (TDI_ada)) + if (flag_dump_ada_spec || flag_dump_ada_spec_slim) { - if (get_dump_file_info (TDI_ada)->flags & TDF_SLIM) + if (flag_dump_ada_spec_slim) collect_source_ref (main_input_filename); else collect_source_refs (global_namespace); diff --git a/gcc/cp/error.c b/gcc/cp/error.c index c8b614b16..e1aa938dd 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -2312,7 +2312,9 @@ dump_expr (tree t, int flags) } pp_cxx_whitespace (cxx_pp); pp_cxx_left_paren (cxx_pp); - if (TYPE_P (TREE_OPERAND (t, 0))) + if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t)) + dump_type (TREE_TYPE (TREE_OPERAND (t, 0)), flags); + else if (TYPE_P (TREE_OPERAND (t, 0))) dump_type (TREE_OPERAND (t, 0), flags); else dump_expr (TREE_OPERAND (t, 0), flags); diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c index 13c658b29..eee44a1ba 100644 --- a/gcc/cp/mangle.c +++ b/gcc/cp/mangle.c @@ -1,6 +1,6 @@ /* Name mangling for the 3.0 C++ ABI. Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, - 2011 Free Software Foundation, Inc. + 2011, 2012 Free Software Foundation, Inc. Written by Alex Samuel <samuel@codesourcery.com> This file is part of GCC. @@ -2581,6 +2581,12 @@ write_expression (tree expr) write_char ('E'); } else if (TREE_CODE (expr) == SIZEOF_EXPR + && SIZEOF_EXPR_TYPE_P (expr)) + { + write_string ("st"); + write_type (TREE_TYPE (TREE_OPERAND (expr, 0))); + } + else if (TREE_CODE (expr) == SIZEOF_EXPR && TYPE_P (TREE_OPERAND (expr, 0))) { write_string ("st"); diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index e4e982764..cd328b31c 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -4174,6 +4174,7 @@ hidden_name_p (tree val) { if (DECL_P (val) && DECL_LANG_SPECIFIC (val) + && TYPE_FUNCTION_OR_TEMPLATE_DECL_P (val) && DECL_ANTICIPATED (val)) return true; return false; diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 155b51a18..baaa80956 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: diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 104d4dd68..1377b3eed 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5020,7 +5020,7 @@ redeclare_class_template (tree type, tree parms) /* Simplify EXPR if it is a non-dependent expression. Returns the (possibly simplified) expression. */ -static tree +tree fold_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain) { if (expr == NULL_TREE) @@ -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: { @@ -14250,7 +14287,8 @@ tsubst_copy_and_build (tree t, FIXME stop folding in cp_parser_initializer_clause. */ gcc_assert (TREE_CONSTANT (t)); { - tree r = get_target_expr (RECUR (TARGET_EXPR_INITIAL (t))); + tree r = get_target_expr_sfinae (RECUR (TARGET_EXPR_INITIAL (t)), + complain); TREE_CONSTANT (r) = true; RETURN (r); } @@ -19288,6 +19326,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 +19668,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) diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 1aa5a8b8b..717492709 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -3,8 +3,7 @@ building RTL. These routines are used both during actual parsing and during the instantiation of template functions. - Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. + Copyright (C) 1998-2012 Free Software Foundation, Inc. Written by Mark Mitchell (mmitchell@usa.net) based on code found formerly in parse.y and pt.c. @@ -2170,8 +2169,25 @@ finish_call_expr (tree fn, VEC(tree,gc) **args, bool disallow_virtual, result = resolve_overloaded_builtin (input_location, fn, *args); if (!result) - /* A call to a namespace-scope function. */ - result = build_new_function_call (fn, args, koenig_p, complain); + { + if (warn_sizeof_pointer_memaccess + && !VEC_empty(tree, *args) + && TREE_CODE (VEC_last(tree, *args)) == SIZEOF_EXPR + && !processing_template_decl) + { + tree sizeof_arg = VEC_last(tree, *args); + if (SIZEOF_EXPR_TYPE_P (sizeof_arg)) + sizeof_arg = TREE_TYPE (TREE_OPERAND (sizeof_arg, 0)); + else + sizeof_arg = TREE_OPERAND (sizeof_arg, 0); + sizeof_pointer_memaccess_warning + (EXPR_LOCATION (VEC_last(tree, *args)), fn, *args, + sizeof_arg, same_type_ignoring_top_level_qualifiers_p); + } + + /* A call to a namespace-scope function. */ + result = build_new_function_call (fn, args, koenig_p, complain); + } } else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR) { @@ -7723,6 +7739,21 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t, non_constant_p); break; + case SIZEOF_EXPR: + if (SIZEOF_EXPR_TYPE_P (t)) + r = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (t, 0)), + SIZEOF_EXPR, false); + else if (TYPE_P (TREE_OPERAND (t, 0))) + r = cxx_sizeof_or_alignof_type (TREE_OPERAND (t, 0), SIZEOF_EXPR, + false); + else + r = cxx_sizeof_or_alignof_expr (TREE_OPERAND (t, 0), SIZEOF_EXPR, + false); + if (r == error_mark_node) + r = size_one_node; + VERIFY_CONSTANT (r); + break; + case COMPOUND_EXPR: { /* check_return_expr sometimes wraps a TARGET_EXPR in a @@ -7740,6 +7771,7 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t, /* Check that the LHS is constant and then discard it. */ cxx_eval_constant_expression (call, op0, allow_non_constant, false, non_constant_p); + op1 = TREE_OPERAND (t, 1); r = cxx_eval_constant_expression (call, op1, allow_non_constant, addr, non_constant_p); } @@ -8106,12 +8138,6 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags) int i; tree tmp; - /* C++98 has different rules for the form of a constant expression that - are enforced in the parser, so we can assume that anything that gets - this far is suitable. */ - if (cxx_dialect < cxx0x) - return true; - if (t == error_mark_node) return false; if (t == NULL_TREE) @@ -8632,6 +8658,9 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags) return false; default: + if (objc_is_property_ref (t)) + return false; + sorry ("unexpected AST of kind %s", tree_code_name[TREE_CODE (t)]); gcc_unreachable(); return false; @@ -8975,14 +9004,15 @@ is_capture_proxy (tree decl) bool is_normal_capture_proxy (tree decl) { - tree val; - if (!is_capture_proxy (decl)) /* It's not a capture proxy. */ return false; /* It is a capture proxy, is it a normal capture? */ - val = DECL_VALUE_EXPR (decl); + tree val = DECL_VALUE_EXPR (decl); + if (val == error_mark_node) + return true; + gcc_assert (TREE_CODE (val) == COMPONENT_REF); val = TREE_OPERAND (val, 1); return DECL_NORMAL_CAPTURE_P (val); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 7dddf2299..e1af37864 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2602,6 +2602,10 @@ cp_tree_equal (tree t1, tree t2) tree o1 = TREE_OPERAND (t1, 0); tree o2 = TREE_OPERAND (t2, 0); + if (SIZEOF_EXPR_TYPE_P (t1)) + o1 = TREE_TYPE (o1); + if (SIZEOF_EXPR_TYPE_P (t2)) + o2 = TREE_TYPE (o2); if (TREE_CODE (o1) != TREE_CODE (o2)) return false; if (TYPE_P (o1)) @@ -3553,7 +3557,7 @@ stabilize_call (tree call, tree *initp) arguments, while, upon return, *INITP contains an expression to compute the arguments. */ -void +static void stabilize_aggr_init (tree call, tree *initp) { tree inits = NULL_TREE; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 884f7d057..ce779075d 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -4624,7 +4624,14 @@ cp_build_binary_op (location_t location, && !enum_cast_to_int (orig_op0) && !enum_cast_to_int (orig_op1)) { - warn_for_sign_compare (location, orig_op0, orig_op1, op0, op1, + tree oop0 = maybe_constant_value (orig_op0); + tree oop1 = maybe_constant_value (orig_op1); + + if (TREE_CODE (oop0) != INTEGER_CST) + oop0 = orig_op0; + if (TREE_CODE (oop1) != INTEGER_CST) + oop1 = orig_op1; + warn_for_sign_compare (location, oop0, oop1, op0, op1, result_type, resultcode); } } |