aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/cp
diff options
context:
space:
mode:
authorBen Cheng <bccheng@google.com>2014-05-17 17:03:43 -0700
committerBen Cheng <bccheng@google.com>2014-05-17 17:12:35 -0700
commit8c493ead6366b552adee796de296936b78f34c5a (patch)
tree4936e52fb9b84edbcd9293bd321027413d1835bf /gcc-4.9/gcc/cp
parent9750bde7e561731ce8a07cdbd0165a688e74a696 (diff)
downloadtoolchain_gcc-8c493ead6366b552adee796de296936b78f34c5a.tar.gz
toolchain_gcc-8c493ead6366b552adee796de296936b78f34c5a.tar.bz2
toolchain_gcc-8c493ead6366b552adee796de296936b78f34c5a.zip
[4.9] Refresh GCC 4.9 to the 20140514 snapshot.
For critical bug fixes including devirtualization and codegen. Change-Id: I8138d3dc408fc12db5eecb01d2753d39219712f2
Diffstat (limited to 'gcc-4.9/gcc/cp')
-rw-r--r--gcc-4.9/gcc/cp/ChangeLog51
-rw-r--r--gcc-4.9/gcc/cp/call.c13
-rw-r--r--gcc-4.9/gcc/cp/init.c3
-rw-r--r--gcc-4.9/gcc/cp/lambda.c13
-rw-r--r--gcc-4.9/gcc/cp/parser.c38
-rw-r--r--gcc-4.9/gcc/cp/pt.c125
-rw-r--r--gcc-4.9/gcc/cp/typeck2.c2
7 files changed, 180 insertions, 65 deletions
diff --git a/gcc-4.9/gcc/cp/ChangeLog b/gcc-4.9/gcc/cp/ChangeLog
index f95944b9b..f9cf11884 100644
--- a/gcc-4.9/gcc/cp/ChangeLog
+++ b/gcc-4.9/gcc/cp/ChangeLog
@@ -1,3 +1,54 @@
+2014-05-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/61151
+ * lambda.c (is_this): Allow capture proxies too.
+
+ DR 5
+ PR c++/60019
+ * call.c (build_user_type_conversion_1): The copy-init temporary
+ is cv-unqualified.
+
+2014-05-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/61083
+ * pt.c (convert_nontype_argument): Protect all the error calls
+ with complain & tf_error.
+
+2014-05-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/60999
+ * pt.c (maybe_begin_member_template_processing): Use
+ uses_template_parms.
+
+2014-05-02 Jason Merrill <jason@redhat.com>
+
+ PR c++/60992
+ * lambda.c (lambda_capture_field_type): Wrap anything dependent
+ other than 'this' or a VLA.
+ (is_this): New.
+ * pt.c (tsubst_copy) [VAR_DECL]: Also build a new VAR_DECL if
+ the operand was static or constant.
+
+2014-04-30 Jason Merrill <jason@redhat.com>
+
+ PR c++/60980
+ * init.c (build_value_init): Don't try to call an array constructor.
+
+ PR c++/60951
+ * typeck2.c (massage_init_elt): Use maybe_constant_init.
+
+2014-04-24 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_parser_omp_atomic): Allow seq_cst before
+ atomic-clause, allow comma in between atomic-clause and
+ seq_cst.
+
+2014-04-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/59073
+ * parser.c (cp_parser_omp_parallel): If cp_parser_omp_for
+ fails, don't set OM_PARALLEL_COMBINED and return NULL.
+
2014-04-22 Release Manager
* GCC 4.9.0 released.
diff --git a/gcc-4.9/gcc/cp/call.c b/gcc-4.9/gcc/cp/call.c
index 98469e9e4..57e08cb8e 100644
--- a/gcc-4.9/gcc/cp/call.c
+++ b/gcc-4.9/gcc/cp/call.c
@@ -3677,11 +3677,20 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags,
return cand;
}
+ tree convtype;
+ if (!DECL_CONSTRUCTOR_P (cand->fn))
+ convtype = non_reference (TREE_TYPE (TREE_TYPE (cand->fn)));
+ else if (cand->second_conv->kind == ck_rvalue)
+ /* DR 5: [in the first step of copy-initialization]...if the function
+ is a constructor, the call initializes a temporary of the
+ cv-unqualified version of the destination type. */
+ convtype = cv_unqualified (totype);
+ else
+ convtype = totype;
/* Build the user conversion sequence. */
conv = build_conv
(ck_user,
- (DECL_CONSTRUCTOR_P (cand->fn)
- ? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))),
+ convtype,
build_identity_conv (TREE_TYPE (expr), expr));
conv->cand = cand;
if (cand->viable == -1)
diff --git a/gcc-4.9/gcc/cp/init.c b/gcc-4.9/gcc/cp/init.c
index 1a1f6c0fe..4373963a2 100644
--- a/gcc-4.9/gcc/cp/init.c
+++ b/gcc-4.9/gcc/cp/init.c
@@ -339,7 +339,8 @@ build_value_init (tree type, tsubst_flags_t complain)
gcc_assert (!processing_template_decl
|| (SCALAR_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE));
- if (type_build_ctor_call (type))
+ if (CLASS_TYPE_P (type)
+ && type_build_ctor_call (type))
{
tree ctor = build_aggr_init_expr
(type,
diff --git a/gcc-4.9/gcc/cp/lambda.c b/gcc-4.9/gcc/cp/lambda.c
index 0b8b46a81..7bd0de15f 100644
--- a/gcc-4.9/gcc/cp/lambda.c
+++ b/gcc-4.9/gcc/cp/lambda.c
@@ -201,6 +201,14 @@ lambda_function (tree lambda)
return lambda;
}
+static inline bool
+is_this (tree t)
+{
+ return ((TREE_CODE (t) == PARM_DECL
+ || TREE_CODE (t) == VAR_DECL)
+ && DECL_NAME (t) == this_identifier);
+}
+
/* Returns the type to use for the FIELD_DECL corresponding to the
capture of EXPR.
The caller should add REFERENCE_TYPE for capture by reference. */
@@ -216,8 +224,9 @@ lambda_capture_field_type (tree expr, bool explicit_init_p)
}
else
type = non_reference (unlowered_expr_type (expr));
- if (!type || WILDCARD_TYPE_P (type) || type_uses_auto (type)
- || DECL_PACK_P (expr))
+ if (type_dependent_expression_p (expr)
+ && !is_this (tree_strip_nop_conversions (expr))
+ && !array_of_runtime_bound_p (type))
{
type = cxx_make_type (DECLTYPE_TYPE);
DECLTYPE_TYPE_EXPR (type) = expr;
diff --git a/gcc-4.9/gcc/cp/parser.c b/gcc-4.9/gcc/cp/parser.c
index f386eed27..aa00a7b68 100644
--- a/gcc-4.9/gcc/cp/parser.c
+++ b/gcc-4.9/gcc/cp/parser.c
@@ -28530,6 +28530,20 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
tree id = cp_lexer_peek_token (parser->lexer)->u.value;
const char *p = IDENTIFIER_POINTER (id);
+ if (!strcmp (p, "seq_cst"))
+ {
+ seq_cst = true;
+ cp_lexer_consume_token (parser->lexer);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME)
+ cp_lexer_consume_token (parser->lexer);
+ }
+ }
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
if (!strcmp (p, "read"))
code = OMP_ATOMIC_READ;
else if (!strcmp (p, "write"))
@@ -28543,16 +28557,22 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
if (p)
cp_lexer_consume_token (parser->lexer);
}
-
- if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ if (!seq_cst)
{
- tree id = cp_lexer_peek_token (parser->lexer)->u.value;
- const char *p = IDENTIFIER_POINTER (id);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME)
+ cp_lexer_consume_token (parser->lexer);
- if (!strcmp (p, "seq_cst"))
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
- seq_cst = true;
- cp_lexer_consume_token (parser->lexer);
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (!strcmp (p, "seq_cst"))
+ {
+ seq_cst = true;
+ cp_lexer_consume_token (parser->lexer);
+ }
}
}
cp_parser_require_pragma_eol (parser, pragma_tok);
@@ -29825,10 +29845,12 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
return cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses);
block = begin_omp_parallel ();
save = cp_parser_begin_omp_structured_block (parser);
- cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses);
+ tree ret = cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses);
cp_parser_end_omp_structured_block (parser, save);
stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
block);
+ if (ret == NULL_TREE)
+ return ret;
OMP_PARALLEL_COMBINED (stmt) = 1;
return stmt;
}
diff --git a/gcc-4.9/gcc/cp/pt.c b/gcc-4.9/gcc/cp/pt.c
index 318c32507..3951997b0 100644
--- a/gcc-4.9/gcc/cp/pt.c
+++ b/gcc-4.9/gcc/cp/pt.c
@@ -462,9 +462,13 @@ maybe_begin_member_template_processing (tree decl)
bool nsdmi = TREE_CODE (decl) == FIELD_DECL;
if (nsdmi)
- decl = (CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl))
- ? CLASSTYPE_TI_TEMPLATE (DECL_CONTEXT (decl))
- : NULL_TREE);
+ {
+ tree ctx = DECL_CONTEXT (decl);
+ decl = (CLASSTYPE_TEMPLATE_INFO (ctx)
+ /* Disregard full specializations (c++/60999). */
+ && uses_template_parms (ctx)
+ ? CLASSTYPE_TI_TEMPLATE (ctx) : NULL_TREE);
+ }
if (inline_needs_template_parms (decl, nsdmi))
{
@@ -5817,17 +5821,18 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
{
if (VAR_P (expr))
{
- error ("%qD is not a valid template argument "
- "because %qD is a variable, not the address of "
- "a variable",
- expr, expr);
+ if (complain & tf_error)
+ error ("%qD is not a valid template argument "
+ "because %qD is a variable, not the address of "
+ "a variable", expr, expr);
return NULL_TREE;
}
if (POINTER_TYPE_P (expr_type))
{
- error ("%qE is not a valid template argument for %qT "
- "because it is not the address of a variable",
- expr, type);
+ if (complain & tf_error)
+ error ("%qE is not a valid template argument for %qT "
+ "because it is not the address of a variable",
+ expr, type);
return NULL_TREE;
}
/* Other values, like integer constants, might be valid
@@ -5842,23 +5847,24 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
? TREE_OPERAND (expr, 0) : expr);
if (!VAR_P (decl))
{
- error ("%qE is not a valid template argument of type %qT "
- "because %qE is not a variable",
- expr, type, decl);
+ if (complain & tf_error)
+ error ("%qE is not a valid template argument of type %qT "
+ "because %qE is not a variable", expr, type, decl);
return NULL_TREE;
}
else if (cxx_dialect < cxx11 && !DECL_EXTERNAL_LINKAGE_P (decl))
{
- error ("%qE is not a valid template argument of type %qT "
- "because %qD does not have external linkage",
- expr, type, decl);
+ if (complain & tf_error)
+ error ("%qE is not a valid template argument of type %qT "
+ "because %qD does not have external linkage",
+ expr, type, decl);
return NULL_TREE;
}
else if (cxx_dialect >= cxx11 && decl_linkage (decl) == lk_none)
{
- error ("%qE is not a valid template argument of type %qT "
- "because %qD has no linkage",
- expr, type, decl);
+ if (complain & tf_error)
+ error ("%qE is not a valid template argument of type %qT "
+ "because %qD has no linkage", expr, type, decl);
return NULL_TREE;
}
}
@@ -5886,15 +5892,17 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
if (!at_least_as_qualified_p (TREE_TYPE (type), expr_type))
{
- error ("%qE is not a valid template argument for type %qT "
- "because of conflicts in cv-qualification", expr, type);
+ if (complain & tf_error)
+ error ("%qE is not a valid template argument for type %qT "
+ "because of conflicts in cv-qualification", expr, type);
return NULL_TREE;
}
if (!real_lvalue_p (expr))
{
- error ("%qE is not a valid template argument for type %qT "
- "because it is not an lvalue", expr, type);
+ if (complain & tf_error)
+ error ("%qE is not a valid template argument for type %qT "
+ "because it is not an lvalue", expr, type);
return NULL_TREE;
}
@@ -5910,26 +5918,29 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
expr = TREE_OPERAND (expr, 0);
if (DECL_P (expr))
{
- error ("%q#D is not a valid template argument for type %qT "
- "because a reference variable does not have a constant "
- "address", expr, type);
+ if (complain & tf_error)
+ error ("%q#D is not a valid template argument for type %qT "
+ "because a reference variable does not have a constant "
+ "address", expr, type);
return NULL_TREE;
}
}
if (!DECL_P (expr))
{
- error ("%qE is not a valid template argument for type %qT "
- "because it is not an object with external linkage",
- expr, type);
+ if (complain & tf_error)
+ error ("%qE is not a valid template argument for type %qT "
+ "because it is not an object with external linkage",
+ expr, type);
return NULL_TREE;
}
if (!DECL_EXTERNAL_LINKAGE_P (expr))
{
- error ("%qE is not a valid template argument for type %qT "
- "because object %qD has not external linkage",
- expr, type, expr);
+ if (complain & tf_error)
+ error ("%qE is not a valid template argument for type %qT "
+ "because object %qD has not external linkage",
+ expr, type, expr);
return NULL_TREE;
}
@@ -5971,9 +5982,13 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
{
if (TREE_CODE (expr) == ADDR_EXPR)
{
- error ("%qE is not a valid template argument for type %qT "
- "because it is a pointer", expr, type);
- inform (input_location, "try using %qE instead", TREE_OPERAND (expr, 0));
+ if (complain & tf_error)
+ {
+ error ("%qE is not a valid template argument for type %qT "
+ "because it is a pointer", expr, type);
+ inform (input_location, "try using %qE instead",
+ TREE_OPERAND (expr, 0));
+ }
return NULL_TREE;
}
@@ -6011,13 +6026,16 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
provide a superior diagnostic. */
if (!same_type_p (TREE_TYPE (expr), type))
{
- error ("%qE is not a valid template argument for type %qT "
- "because it is of type %qT", expr, type,
- TREE_TYPE (expr));
- /* If we are just one standard conversion off, explain. */
- if (can_convert_standard (type, TREE_TYPE (expr), complain))
- inform (input_location,
- "standard conversions are not allowed in this context");
+ if (complain & tf_error)
+ {
+ error ("%qE is not a valid template argument for type %qT "
+ "because it is of type %qT", expr, type,
+ TREE_TYPE (expr));
+ /* If we are just one standard conversion off, explain. */
+ if (can_convert_standard (type, TREE_TYPE (expr), complain))
+ inform (input_location,
+ "standard conversions are not allowed in this context");
+ }
return NULL_TREE;
}
}
@@ -6040,8 +6058,9 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
{
if (expr != nullptr_node)
{
- error ("%qE is not a valid template argument for type %qT "
- "because it is of type %qT", expr, type, TREE_TYPE (expr));
+ if (complain & tf_error)
+ error ("%qE is not a valid template argument for type %qT "
+ "because it is of type %qT", expr, type, TREE_TYPE (expr));
return NULL_TREE;
}
return expr;
@@ -12638,13 +12657,17 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
}
else
{
- /* This can happen for a variable used in a late-specified
- return type of a local lambda. Just make a dummy decl
- since it's only used for its type. */
- if (cp_unevaluated_operand)
- return tsubst_decl (t, args, complain);
- gcc_assert (errorcount || sorrycount);
- return error_mark_node;
+ /* This can happen for a variable used in a
+ late-specified return type of a local lambda, or for a
+ local static or constant. Building a new VAR_DECL
+ should be OK in all those cases. */
+ r = tsubst_decl (t, args, complain);
+ if (decl_constant_var_p (r))
+ /* A use of a local constant must decay to its value. */
+ return integral_constant_value (r);
+ gcc_assert (cp_unevaluated_operand || TREE_STATIC (r)
+ || errorcount || sorrycount);
+ return r;
}
}
}
diff --git a/gcc-4.9/gcc/cp/typeck2.c b/gcc-4.9/gcc/cp/typeck2.c
index 68e518a5c..85696f6e0 100644
--- a/gcc-4.9/gcc/cp/typeck2.c
+++ b/gcc-4.9/gcc/cp/typeck2.c
@@ -1138,7 +1138,7 @@ massage_init_elt (tree type, tree init, tsubst_flags_t complain)
/* When we defer constant folding within a statement, we may want to
defer this folding as well. */
tree t = fold_non_dependent_expr_sfinae (init, complain);
- t = maybe_constant_value (t);
+ t = maybe_constant_init (t);
if (TREE_CONSTANT (t))
init = t;
return init;