aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/cp
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/cp')
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog74
-rw-r--r--gcc-4.9/gcc/cp/call.c5
-rw-r--r--gcc-4.9/gcc/cp/class.c23
-rw-r--r--gcc-4.9/gcc/cp/cp-array-notation.c30
-rw-r--r--gcc-4.9/gcc/cp/cp-tree.h1
-rw-r--r--gcc-4.9/gcc/cp/decl.c24
-rw-r--r--gcc-4.9/gcc/cp/decl2.c5
-rw-r--r--gcc-4.9/gcc/cp/expr.c8
-rw-r--r--gcc-4.9/gcc/cp/init.c57
-rw-r--r--gcc-4.9/gcc/cp/lambda.c5
-rw-r--r--gcc-4.9/gcc/cp/parser.c2
-rw-r--r--gcc-4.9/gcc/cp/pt.c18
-rw-r--r--gcc-4.9/gcc/cp/semantics.c5
-rw-r--r--gcc-4.9/gcc/cp/tree.c4
-rw-r--r--gcc-4.9/gcc/cp/typeck2.c3
15 files changed, 214 insertions, 50 deletions
diff --git a/gcc-4.9/gcc/cp/ChangeLog b/gcc-4.9/gcc/cp/ChangeLog
index b0a474daf..0c7ab3320 100644
--- a/gcc-4.9/gcc/cp/ChangeLog
+++ b/gcc-4.9/gcc/cp/ChangeLog
@@ -1,3 +1,77 @@
+2014-08-26 Jason Merrill <jason@redhat.com>
+
+ PR c++/58624
+ * pt.c (tsubst_copy_and_build) [VAR_DECL]: Use TLS wrapper.
+ * semantics.c (finish_id_expression): Don't call TLS wrapper in a
+ template.
+
+2014-08-25 Jason Merrill <jason@redhat.com>
+
+ PR c++/62129
+ * class.c (outermost_open_class): New.
+ * cp-tree.h: Declare it.
+ * decl.c (maybe_register_incomplete_var): Use it.
+ (complete_vars): Handle any constant variable.
+ * expr.c (cplus_expand_constant): Handle CONSTRUCTOR.
+
+2014-08-22 Igor Zamyatin <igor.zamyatin@intel.com>
+
+ PR other/62008
+ * cp-array-notation.c (build_array_notation_ref): Added correct
+ handling of case with incorrect array.
+
+2014-08-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/61214
+ PR tree-optimization/62091
+ * decl2.c (decl_needed_p): Return true for virtual functions when
+ devirtualizing.
+
+ Backport:
+ PR c++/61566
+ * pt.c (instantiate_class_template_1): Ignore lambda on
+ CLASSTYPE_DECL_LIST.
+ (push_template_decl_real): A lambda is not primary.
+ * lambda.c (maybe_add_lambda_conv_op): Distinguish between being
+ currently in a function and the lambda living in a function.
+
+ Backport:
+ PR c++/60417
+ * init.c (build_vec_init): Set CONSTRUCTOR_IS_DIRECT_INIT on
+ init-list for trailing elements.
+ * typeck2.c (process_init_constructor_array): Likewise.
+
+2014-08-07 Jason Merrill <jason@redhat.com>
+
+ PR c++/61959
+ * semantics.c (cxx_eval_bare_aggregate): Handle POINTER_PLUS_EXPR.
+
+ PR c++/61994
+ * init.c (build_vec_init): Leave atype an ARRAY_TYPE
+ if we're just returning an INIT_EXPR.
+
+ PR c++/60872
+ * call.c (standard_conversion): Don't try to apply restrict to void.
+
+ PR c++/58714
+ * tree.c (stabilize_expr): A stabilized prvalue is an xvalue.
+
+2014-08-01 Igor Zamyatin <igor.zamyatin@intel.com>
+
+ * cp-array-notation.c (expand_an_in_modify_expr): Fix the misprint
+ in error output.
+
+2014-08-01 Igor Zamyatin <igor.zamyatin@intel.com>
+
+ PR other/61963
+ * parser.c (cp_parser_array_notation): Added check for array_type.
+
+2014-08-01 Igor Zamyatin <igor.zamyatin@intel.com>
+
+ PR middle-end/61455
+ * cp-array-notation.c (expand_array_notation_exprs): Handling of
+ DECL_EXPR improved. Changed handling for INIT_EXPR.
+
2014-07-16 Release Manager
* GCC 4.9.1 released.
diff --git a/gcc-4.9/gcc/cp/call.c b/gcc-4.9/gcc/cp/call.c
index 2c67c03e4..223188a51 100644
--- a/gcc-4.9/gcc/cp/call.c
+++ b/gcc-4.9/gcc/cp/call.c
@@ -1208,9 +1208,10 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
&& TREE_CODE (TREE_TYPE (from)) != FUNCTION_TYPE)
{
tree nfrom = TREE_TYPE (from);
+ /* Don't try to apply restrict to void. */
+ int quals = cp_type_quals (nfrom) & ~TYPE_QUAL_RESTRICT;
from = build_pointer_type
- (cp_build_qualified_type (void_type_node,
- cp_type_quals (nfrom)));
+ (cp_build_qualified_type (void_type_node, quals));
conv = build_conv (ck_ptr, from, conv);
}
else if (TYPE_PTRDATAMEM_P (from))
diff --git a/gcc-4.9/gcc/cp/class.c b/gcc-4.9/gcc/cp/class.c
index 265afc486..711a567cb 100644
--- a/gcc-4.9/gcc/cp/class.c
+++ b/gcc-4.9/gcc/cp/class.c
@@ -7251,6 +7251,29 @@ currently_open_derived_class (tree t)
return NULL_TREE;
}
+/* Return the outermost enclosing class type that is still open, or
+ NULL_TREE. */
+
+tree
+outermost_open_class (void)
+{
+ if (!current_class_type)
+ return NULL_TREE;
+ tree r = NULL_TREE;
+ if (TYPE_BEING_DEFINED (current_class_type))
+ r = current_class_type;
+ for (int i = current_class_depth - 1; i > 0; --i)
+ {
+ if (current_class_stack[i].hidden)
+ break;
+ tree t = current_class_stack[i].type;
+ if (!TYPE_BEING_DEFINED (t))
+ break;
+ r = t;
+ }
+ return r;
+}
+
/* Returns the innermost class type which is not a lambda closure type. */
tree
diff --git a/gcc-4.9/gcc/cp/cp-array-notation.c b/gcc-4.9/gcc/cp/cp-array-notation.c
index fed60c953..a50ff1dc9 100644
--- a/gcc-4.9/gcc/cp/cp-array-notation.c
+++ b/gcc-4.9/gcc/cp/cp-array-notation.c
@@ -607,7 +607,7 @@ expand_an_in_modify_expr (location_t location, tree lhs,
if (lhs_rank == 0 && rhs_rank != 0)
{
- error_at (location, "%qD cannot be scalar when %qD is not", lhs, rhs);
+ error_at (location, "%qE cannot be scalar when %qE is not", lhs, rhs);
return error_mark_node;
}
if (lhs_rank != 0 && rhs_rank != 0 && lhs_rank != rhs_rank)
@@ -1147,13 +1147,13 @@ expand_array_notation_exprs (tree t)
case PARM_DECL:
case NON_LVALUE_EXPR:
case NOP_EXPR:
- case INIT_EXPR:
case ADDR_EXPR:
case ARRAY_REF:
case BIT_FIELD_REF:
case VECTOR_CST:
case COMPLEX_CST:
return t;
+ case INIT_EXPR:
case MODIFY_EXPR:
if (contains_array_notation_expr (t))
t = expand_an_in_modify_expr (loc, TREE_OPERAND (t, 0), NOP_EXPR,
@@ -1175,13 +1175,24 @@ expand_array_notation_exprs (tree t)
return t;
}
case DECL_EXPR:
- {
- tree x = DECL_EXPR_DECL (t);
- if (t && TREE_CODE (x) != FUNCTION_DECL)
+ if (contains_array_notation_expr (t))
+ {
+ tree x = DECL_EXPR_DECL (t);
if (DECL_INITIAL (x))
- t = expand_unary_array_notation_exprs (t);
+ {
+ location_t loc = DECL_SOURCE_LOCATION (x);
+ tree lhs = x;
+ tree rhs = DECL_INITIAL (x);
+ DECL_INITIAL (x) = NULL;
+ tree new_modify_expr = build_modify_expr (loc, lhs,
+ TREE_TYPE (lhs),
+ NOP_EXPR,
+ loc, rhs,
+ TREE_TYPE(rhs));
+ t = expand_array_notation_exprs (new_modify_expr);
+ }
+ }
return t;
- }
case STATEMENT_LIST:
{
tree_stmt_iterator i;
@@ -1392,7 +1403,10 @@ build_array_notation_ref (location_t loc, tree array, tree start, tree length,
if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == POINTER_TYPE)
TREE_TYPE (array_ntn_expr) = TREE_TYPE (type);
else
- gcc_unreachable ();
+ {
+ error_at (loc, "base of array section must be pointer or array type");
+ return error_mark_node;
+ }
SET_EXPR_LOCATION (array_ntn_expr, loc);
return array_ntn_expr;
diff --git a/gcc-4.9/gcc/cp/cp-tree.h b/gcc-4.9/gcc/cp/cp-tree.h
index e6323e7eb..b062b9733 100644
--- a/gcc-4.9/gcc/cp/cp-tree.h
+++ b/gcc-4.9/gcc/cp/cp-tree.h
@@ -5113,6 +5113,7 @@ extern void resort_type_method_vec (void *, void *,
extern bool add_method (tree, tree, tree);
extern bool currently_open_class (tree);
extern tree currently_open_derived_class (tree);
+extern tree outermost_open_class (void);
extern tree current_nonlambda_class_type (void);
extern tree finish_struct (tree, tree);
extern void finish_struct_1 (tree);
diff --git a/gcc-4.9/gcc/cp/decl.c b/gcc-4.9/gcc/cp/decl.c
index 4dd0ec09f..df4813deb 100644
--- a/gcc-4.9/gcc/cp/decl.c
+++ b/gcc-4.9/gcc/cp/decl.c
@@ -14211,8 +14211,8 @@ grokmethod (cp_decl_specifier_seq *declspecs,
/* VAR is a VAR_DECL. If its type is incomplete, remember VAR so that
we can lay it out later, when and if its type becomes complete.
- Also handle constexpr pointer to member variables where the initializer
- is an unlowered PTRMEM_CST because the class isn't complete yet. */
+ Also handle constexpr variables where the initializer involves
+ an unlowered PTRMEM_CST because the class isn't complete yet. */
void
maybe_register_incomplete_var (tree var)
@@ -14237,12 +14237,13 @@ maybe_register_incomplete_var (tree var)
incomplete_var iv = {var, inner_type};
vec_safe_push (incomplete_vars, iv);
}
- else if (TYPE_PTRMEM_P (inner_type)
- && DECL_INITIAL (var)
- && TREE_CODE (DECL_INITIAL (var)) == PTRMEM_CST)
+ else if (!(DECL_LANG_SPECIFIC (var) && DECL_TEMPLATE_INFO (var))
+ && decl_constant_var_p (var)
+ && (TYPE_PTRMEM_P (inner_type) || CLASS_TYPE_P (inner_type)))
{
- tree context = TYPE_PTRMEM_CLASS_TYPE (inner_type);
- gcc_assert (TYPE_BEING_DEFINED (context));
+ /* When the outermost open class is complete we can resolve any
+ pointers-to-members. */
+ tree context = outermost_open_class ();
incomplete_var iv = {var, context};
vec_safe_push (incomplete_vars, iv);
}
@@ -14266,9 +14267,8 @@ complete_vars (tree type)
tree var = iv->decl;
tree type = TREE_TYPE (var);
- if (TYPE_PTRMEM_P (type))
- DECL_INITIAL (var) = cplus_expand_constant (DECL_INITIAL (var));
- else
+ if (TYPE_MAIN_VARIANT (strip_array_types (type))
+ == iv->incomplete_type)
{
/* Complete the type of the variable. The VAR_DECL itself
will be laid out in expand_expr. */
@@ -14276,6 +14276,10 @@ complete_vars (tree type)
cp_apply_type_quals_to_decl (cp_type_quals (type), var);
}
+ if (DECL_INITIAL (var)
+ && decl_constant_var_p (var))
+ DECL_INITIAL (var) = cplus_expand_constant (DECL_INITIAL (var));
+
/* Remove this entry from the list. */
incomplete_vars->unordered_remove (ix);
}
diff --git a/gcc-4.9/gcc/cp/decl2.c b/gcc-4.9/gcc/cp/decl2.c
index 3088918cd..4fc03e912 100644
--- a/gcc-4.9/gcc/cp/decl2.c
+++ b/gcc-4.9/gcc/cp/decl2.c
@@ -1931,6 +1931,11 @@ decl_needed_p (tree decl)
if (flag_keep_inline_dllexport
&& lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl)))
return true;
+ /* Virtual functions might be needed for devirtualization. */
+ if (flag_devirtualize
+ && TREE_CODE (decl) == FUNCTION_DECL
+ && DECL_VIRTUAL_P (decl))
+ return true;
/* Otherwise, DECL does not need to be emitted -- yet. A subsequent
reference to DECL might cause it to be emitted later. */
return false;
diff --git a/gcc-4.9/gcc/cp/expr.c b/gcc-4.9/gcc/cp/expr.c
index a62e0f9b5..99f8006fb 100644
--- a/gcc-4.9/gcc/cp/expr.c
+++ b/gcc-4.9/gcc/cp/expr.c
@@ -74,6 +74,14 @@ cplus_expand_constant (tree cst)
}
break;
+ case CONSTRUCTOR:
+ {
+ constructor_elt *elt;
+ unsigned HOST_WIDE_INT idx;
+ FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (cst), idx, elt)
+ elt->value = cplus_expand_constant (elt->value);
+ }
+
default:
/* There's nothing to do. */
break;
diff --git a/gcc-4.9/gcc/cp/init.c b/gcc-4.9/gcc/cp/init.c
index ecb103a99..283843ae9 100644
--- a/gcc-4.9/gcc/cp/init.c
+++ b/gcc-4.9/gcc/cp/init.c
@@ -3565,19 +3565,11 @@ build_vec_init (tree base, tree maxindex, tree init,
try_block = begin_try_block ();
}
- /* If the initializer is {}, then all elements are initialized from {}.
- But for non-classes, that's the same as value-initialization. */
+ bool empty_list = false;
if (init && BRACE_ENCLOSED_INITIALIZER_P (init)
&& CONSTRUCTOR_NELTS (init) == 0)
- {
- if (CLASS_TYPE_P (type))
- /* Leave init alone. */;
- else
- {
- init = NULL_TREE;
- explicit_value_init_p = true;
- }
- }
+ /* Skip over the handling of non-empty init lists. */
+ empty_list = true;
/* Maybe pull out constant value when from_array? */
@@ -3697,14 +3689,8 @@ build_vec_init (tree base, tree maxindex, tree init,
vec_free (new_vec);
}
- /* Any elements without explicit initializers get {}. */
- if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type))
- init = build_constructor (init_list_type_node, NULL);
- else
- {
- init = NULL_TREE;
- explicit_value_init_p = true;
- }
+ /* Any elements without explicit initializers get T{}. */
+ empty_list = true;
}
else if (from_array)
{
@@ -3750,6 +3736,26 @@ build_vec_init (tree base, tree maxindex, tree init,
to = build1 (INDIRECT_REF, type, base);
+ /* If the initializer is {}, then all elements are initialized from T{}.
+ But for non-classes, that's the same as value-initialization. */
+ if (empty_list)
+ {
+ if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type))
+ {
+ if (BRACE_ENCLOSED_INITIALIZER_P (init)
+ && CONSTRUCTOR_NELTS (init) == 0)
+ /* Reuse it. */;
+ else
+ init = build_constructor (init_list_type_node, NULL);
+ CONSTRUCTOR_IS_DIRECT_INIT (init) = true;
+ }
+ else
+ {
+ init = NULL_TREE;
+ explicit_value_init_p = true;
+ }
+ }
+
if (from_array)
{
tree from;
@@ -3854,6 +3860,13 @@ build_vec_init (tree base, tree maxindex, tree init,
stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
+ current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
+
+ if (errors)
+ return error_mark_node;
+ if (const_init)
+ return build2 (INIT_EXPR, atype, obase, const_init);
+
/* Now make the result have the correct type. */
if (TREE_CODE (atype) == ARRAY_TYPE)
{
@@ -3863,12 +3876,6 @@ build_vec_init (tree base, tree maxindex, tree init,
TREE_NO_WARNING (stmt_expr) = 1;
}
- current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
-
- if (const_init)
- return build2 (INIT_EXPR, atype, obase, const_init);
- if (errors)
- return error_mark_node;
return stmt_expr;
}
diff --git a/gcc-4.9/gcc/cp/lambda.c b/gcc-4.9/gcc/cp/lambda.c
index 7bd0de15f..6acbdd9ee 100644
--- a/gcc-4.9/gcc/cp/lambda.c
+++ b/gcc-4.9/gcc/cp/lambda.c
@@ -820,6 +820,7 @@ void
maybe_add_lambda_conv_op (tree type)
{
bool nested = (current_function_decl != NULL_TREE);
+ bool nested_def = decl_function_context (TYPE_MAIN_DECL (type));
tree callop = lambda_function (type);
if (LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (type)) != NULL_TREE)
@@ -972,7 +973,7 @@ maybe_add_lambda_conv_op (tree type)
DECL_NOT_REALLY_EXTERN (fn) = 1;
DECL_DECLARED_INLINE_P (fn) = 1;
DECL_ARGUMENTS (fn) = build_this_parm (fntype, TYPE_QUAL_CONST);
- if (nested)
+ if (nested_def)
DECL_INTERFACE_KNOWN (fn) = 1;
if (generic_lambda_p)
@@ -1012,7 +1013,7 @@ maybe_add_lambda_conv_op (tree type)
DECL_NAME (arg) = NULL_TREE;
DECL_CONTEXT (arg) = fn;
}
- if (nested)
+ if (nested_def)
DECL_INTERFACE_KNOWN (fn) = 1;
if (generic_lambda_p)
diff --git a/gcc-4.9/gcc/cp/parser.c b/gcc-4.9/gcc/cp/parser.c
index 706f6c020..88478bf13 100644
--- a/gcc-4.9/gcc/cp/parser.c
+++ b/gcc-4.9/gcc/cp/parser.c
@@ -6306,7 +6306,7 @@ cp_parser_array_notation (location_t loc, cp_parser *parser, tree *init_index,
parser->colon_corrects_to_scope_p = saved_colon_corrects;
if (*init_index == error_mark_node || length_index == error_mark_node
- || stride == error_mark_node)
+ || stride == error_mark_node || array_type == error_mark_node)
{
if (cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_SQUARE)
cp_lexer_consume_token (parser->lexer);
diff --git a/gcc-4.9/gcc/cp/pt.c b/gcc-4.9/gcc/cp/pt.c
index 54676afcc..a049a1e21 100644
--- a/gcc-4.9/gcc/cp/pt.c
+++ b/gcc-4.9/gcc/cp/pt.c
@@ -4706,6 +4706,9 @@ push_template_decl_real (tree decl, bool is_friend)
template <typename T> friend void A<T>::f();
is not primary. */
is_primary = false;
+ else if (TREE_CODE (decl) == TYPE_DECL
+ && LAMBDA_TYPE_P (TREE_TYPE (decl)))
+ is_primary = false;
else
is_primary = template_parm_scope_p ();
@@ -9144,6 +9147,11 @@ instantiate_class_template_1 (tree type)
&& DECL_OMP_DECLARE_REDUCTION_P (r))
cp_check_omp_declare_reduction (r);
}
+ else if (DECL_CLASS_TEMPLATE_P (t)
+ && LAMBDA_TYPE_P (TREE_TYPE (t)))
+ /* A closure type for a lambda in a default argument for a
+ member template. Ignore it; it will be instantiated with
+ the default argument. */;
else
{
/* Build new TYPE_FIELDS. */
@@ -15190,6 +15198,16 @@ tsubst_copy_and_build (tree t,
case PARM_DECL:
{
tree r = tsubst_copy (t, args, complain, in_decl);
+ if (TREE_CODE (r) == VAR_DECL
+ && !processing_template_decl
+ && !cp_unevaluated_operand
+ && DECL_THREAD_LOCAL_P (r))
+ {
+ if (tree wrap = get_tls_wrapper_fn (r))
+ /* Replace an evaluated use of the thread_local variable with
+ a call to its wrapper. */
+ r = build_cxx_call (wrap, 0, NULL, tf_warning_or_error);
+ }
if (TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE)
/* If the original type was a reference, we'll be wrapped in
diff --git a/gcc-4.9/gcc/cp/semantics.c b/gcc-4.9/gcc/cp/semantics.c
index de5e536f5..db4f9fdcd 100644
--- a/gcc-4.9/gcc/cp/semantics.c
+++ b/gcc-4.9/gcc/cp/semantics.c
@@ -3496,6 +3496,7 @@ finish_id_expression (tree id_expression,
tree wrap;
if (VAR_P (decl)
&& !cp_unevaluated_operand
+ && !processing_template_decl
&& DECL_THREAD_LOCAL_P (decl)
&& (wrap = get_tls_wrapper_fn (decl)))
{
@@ -8982,7 +8983,9 @@ cxx_eval_bare_aggregate (const constexpr_call *call, tree t,
constructor_elt *inner = base_field_constructor_elt (n, ce->index);
inner->value = elt;
}
- else if (ce->index && TREE_CODE (ce->index) == NOP_EXPR)
+ else if (ce->index
+ && (TREE_CODE (ce->index) == NOP_EXPR
+ || TREE_CODE (ce->index) == POINTER_PLUS_EXPR))
{
/* This is an initializer for an empty base; now that we've
checked that it's constant, we can ignore it. */
diff --git a/gcc-4.9/gcc/cp/tree.c b/gcc-4.9/gcc/cp/tree.c
index 622ba99f7..2820ba0f9 100644
--- a/gcc-4.9/gcc/cp/tree.c
+++ b/gcc-4.9/gcc/cp/tree.c
@@ -3795,6 +3795,10 @@ stabilize_expr (tree exp, tree* initp)
{
init_expr = get_target_expr (exp);
exp = TARGET_EXPR_SLOT (init_expr);
+ if (CLASS_TYPE_P (TREE_TYPE (exp)))
+ exp = move (exp);
+ else
+ exp = rvalue (exp);
}
else
{
diff --git a/gcc-4.9/gcc/cp/typeck2.c b/gcc-4.9/gcc/cp/typeck2.c
index 0bdad2a51..f8af0964c 100644
--- a/gcc-4.9/gcc/cp/typeck2.c
+++ b/gcc-4.9/gcc/cp/typeck2.c
@@ -1237,8 +1237,9 @@ process_init_constructor_array (tree type, tree init,
{
/* If this type needs constructors run for default-initialization,
we can't rely on the back end to do it for us, so make the
- initialization explicit by list-initializing from {}. */
+ initialization explicit by list-initializing from T{}. */
next = build_constructor (init_list_type_node, NULL);
+ CONSTRUCTOR_IS_DIRECT_INIT (next) = true;
next = massage_init_elt (TREE_TYPE (type), next, complain);
if (initializer_zerop (next))
/* The default zero-initialization is fine for us; don't