diff options
Diffstat (limited to 'gcc-4.6/gcc/cp/semantics.c')
-rw-r--r-- | gcc-4.6/gcc/cp/semantics.c | 61 |
1 files changed, 50 insertions, 11 deletions
diff --git a/gcc-4.6/gcc/cp/semantics.c b/gcc-4.6/gcc/cp/semantics.c index 1816e05..6a2c818 100644 --- a/gcc-4.6/gcc/cp/semantics.c +++ b/gcc-4.6/gcc/cp/semantics.c @@ -2911,6 +2911,9 @@ finish_id_expression (tree id_expression, tree lambda_expr = NULL_TREE; tree initializer = convert_from_reference (decl); + /* Mark it as used now even if the use is ill-formed. */ + mark_used (decl); + /* Core issue 696: "[At the July 2009 meeting] the CWG expressed support for an approach in which a reference to a local [constant] automatic variable in a nested class or lambda body @@ -3217,7 +3220,7 @@ finish_id_expression (tree id_expression, if (scope) { decl = (adjust_result_of_qualified_name_lookup - (decl, scope, current_class_type)); + (decl, scope, current_nonlambda_class_type())); if (TREE_CODE (decl) == FUNCTION_DECL) mark_used (decl); @@ -3359,7 +3362,7 @@ finish_offsetof (tree expr) } if (TREE_CODE (expr) == INDIRECT_REF && REFERENCE_REF_P (expr)) expr = TREE_OPERAND (expr, 0); - return fold_offsetof (expr, NULL_TREE); + return fold_offsetof (expr); } /* Replace the AGGR_INIT_EXPR at *TP with an equivalent CALL_EXPR. This @@ -4859,6 +4862,9 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, expr = resolve_nondeduced_context (expr); + if (invalid_nonstatic_memfn_p (expr, complain)) + return error_mark_node; + /* To get the size of a static data member declared as an array of unknown bound, we need to instantiate it. */ if (TREE_CODE (expr) == VAR_DECL @@ -4945,8 +4951,9 @@ finish_decltype_type (tree expr, bool id_expression_or_member_access_p, gcc_unreachable (); case INTEGER_CST: + case PTRMEM_CST: /* We can get here when the id-expression refers to an - enumerator. */ + enumerator or non-type template parameter. */ type = TREE_TYPE (expr); break; @@ -6324,12 +6331,22 @@ cxx_eval_array_reference (const constexpr_call *call, tree t, elem_type = TREE_TYPE (TREE_TYPE (ary)); if (TREE_CODE (ary) == CONSTRUCTOR) len = CONSTRUCTOR_NELTS (ary); - else + else if (TREE_CODE (ary) == STRING_CST) { elem_nchars = (TYPE_PRECISION (elem_type) / TYPE_PRECISION (char_type_node)); len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars; } + else + { + /* We can't do anything with other tree codes, so use + VERIFY_CONSTANT to complain and fail. */ + VERIFY_CONSTANT (ary); + /* This should be unreachable, but be more fault-tolerant on the + release branch. */ + *non_constant_p = true; + return t; + } if (compare_tree_int (index, len) >= 0) { if (tree_int_cst_lt (index, array_type_nelts_top (TREE_TYPE (ary)))) @@ -6399,7 +6416,8 @@ cxx_eval_component_reference (const constexpr_call *call, tree t, if (field == part) return value; } - if (TREE_CODE (TREE_TYPE (whole)) == UNION_TYPE) + if (TREE_CODE (TREE_TYPE (whole)) == UNION_TYPE + && CONSTRUCTOR_NELTS (whole) > 0) { /* FIXME Mike Miller wants this to be OK. */ if (!allow_non_constant) @@ -6408,8 +6426,12 @@ cxx_eval_component_reference (const constexpr_call *call, tree t, *non_constant_p = true; return t; } - gcc_unreachable(); - return error_mark_node; + + /* If there's no explicit init for this field, it's value-initialized. */ + value = build_value_init (TREE_TYPE (t), tf_warning_or_error); + return cxx_eval_constant_expression (call, value, + allow_non_constant, addr, + non_constant_p); } /* Subroutine of cxx_eval_constant_expression. @@ -6506,9 +6528,9 @@ cxx_eval_logical_expression (const constexpr_call *call, tree t, allow_non_constant, addr, non_constant_p); VERIFY_CONSTANT (lhs); - if (lhs == bailout_value) + if (tree_int_cst_equal (lhs, bailout_value)) return lhs; - gcc_assert (lhs == continue_value); + gcc_assert (tree_int_cst_equal (lhs, continue_value)); r = cxx_eval_constant_expression (call, TREE_OPERAND (t, 1), allow_non_constant, addr, non_constant_p); VERIFY_CONSTANT (r); @@ -6613,6 +6635,7 @@ cxx_eval_vec_init_1 (const constexpr_call *call, tree atype, tree init, tree elttype = TREE_TYPE (atype); int max = tree_low_cst (array_type_nelts (atype), 0); VEC(constructor_elt,gc) *n = VEC_alloc (constructor_elt, gc, max + 1); + bool default_init = false; int i; /* For the default constructor, build up a call to the default @@ -6631,6 +6654,7 @@ cxx_eval_vec_init_1 (const constexpr_call *call, tree atype, tree init, release_tree_vector (argvec); init = cxx_eval_constant_expression (call, init, allow_non_constant, addr, non_constant_p); + default_init = true; } if (*non_constant_p && !allow_non_constant) @@ -6658,7 +6682,7 @@ cxx_eval_vec_init_1 (const constexpr_call *call, tree atype, tree init, eltinit = cxx_eval_constant_expression (call, eltinit, allow_non_constant, addr, non_constant_p); } - else if (TREE_CODE (init) == CONSTRUCTOR) + else if (default_init) { /* Initializing an element using the call to the default constructor we just built above. */ @@ -7310,6 +7334,7 @@ maybe_constant_value (tree t) if (type_dependent_expression_p (t) || type_unknown_p (t) + || BRACE_ENCLOSED_INITIALIZER_P (t) || !potential_constant_expression (t) || value_dependent_expression_p (t)) return t; @@ -7468,6 +7493,7 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags) case IDENTIFIER_NODE: /* We can see a FIELD_DECL in a pointer-to-member expression. */ case FIELD_DECL: + case USING_DECL: return true; case PARM_DECL: @@ -7516,7 +7542,17 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags) { tree x = get_nth_callarg (t, 0); if (is_this_parameter (x)) - /* OK. */; + { + if (DECL_CONSTRUCTOR_P (DECL_CONTEXT (x))) + { + if (flags & tf_error) + sorry ("calling a member function of the " + "object being constructed in a constant " + "expression"); + return false; + } + /* Otherwise OK. */; + } else if (!potential_constant_expression_1 (x, rval, flags)) { if (flags & tf_error) @@ -8283,6 +8319,9 @@ add_capture (tree lambda, tree id, tree initializer, bool by_reference_p, if (!real_lvalue_p (initializer)) error ("cannot capture %qE by reference", initializer); } + else + /* Capture by copy requires a complete type. */ + type = complete_type (type); /* Make member variable. */ member = build_lang_decl (FIELD_DECL, id, type); |