summaryrefslogtreecommitdiff
path: root/gcc/cp
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-11 17:53:07 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-11 17:53:07 +0000
commit91c3ace51288ad603bb71f5b8bf6125f4ede355e (patch)
tree473b4642325a93846dad0753e76e9aebf4091fc9 /gcc/cp
parentd331c123a42208507779a2bed8aaef1c7e3704f6 (diff)
downloadgcc-91c3ace51288ad603bb71f5b8bf6125f4ede355e.tar.gz
PR c++/49855
PR c++/49896 * cp-tree.def (IMPLICIT_CONV_EXPR): New. * call.c (perform_implicit_conversion_flags): Build it instead of NOP_EXPR. * cp-objcp-common.c (cp_common_init_ts): It's typed. * cxx-pretty-print.c (pp_cxx_cast_expression): Handle it. (pp_cxx_expression): Likewise. * error.c (dump_expr): Likewise. * semantics.c (potential_constant_expression_1): Likewise. * tree.c (cp_tree_equal): Likewise. (cp_walk_subtrees): Likewise. * pt.c (iterative_hash_template_arg): Likewise. (for_each_template_parm_r): Likewise. (type_dependent_expression_p): Likewise. (tsubst_copy, tsubst_copy_and_build): Handle IMPLICIT_CONV_EXPR and CONVERT_EXPR. * cp-tree.h (IMPLICIT_CONV_EXPR_DIRECT_INIT): New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@179813 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp')
-rw-r--r--gcc/cp/ChangeLog21
-rw-r--r--gcc/cp/call.c14
-rw-r--r--gcc/cp/cp-objcp-common.c1
-rw-r--r--gcc/cp/cp-tree.def1
-rw-r--r--gcc/cp/cp-tree.h6
-rw-r--r--gcc/cp/cxx-pretty-print.c2
-rw-r--r--gcc/cp/error.c1
-rw-r--r--gcc/cp/pt.c24
-rw-r--r--gcc/cp/semantics.c3
-rw-r--r--gcc/cp/tree.c2
10 files changed, 68 insertions, 7 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3be7f7d8f05..69c0eeb7b6d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,24 @@
+2011-10-11 Jason Merrill <jason@redhat.com>
+
+ PR c++/49855
+ PR c++/49896
+ * cp-tree.def (IMPLICIT_CONV_EXPR): New.
+ * call.c (perform_implicit_conversion_flags): Build it
+ instead of NOP_EXPR.
+ * cp-objcp-common.c (cp_common_init_ts): It's typed.
+ * cxx-pretty-print.c (pp_cxx_cast_expression): Handle it.
+ (pp_cxx_expression): Likewise.
+ * error.c (dump_expr): Likewise.
+ * semantics.c (potential_constant_expression_1): Likewise.
+ * tree.c (cp_tree_equal): Likewise.
+ (cp_walk_subtrees): Likewise.
+ * pt.c (iterative_hash_template_arg): Likewise.
+ (for_each_template_parm_r): Likewise.
+ (type_dependent_expression_p): Likewise.
+ (tsubst_copy, tsubst_copy_and_build): Handle IMPLICIT_CONV_EXPR
+ and CONVERT_EXPR.
+ * cp-tree.h (IMPLICIT_CONV_EXPR_DIRECT_INIT): New.
+
2011-10-11 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/50611
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 4c03e76bb0c..7219afe8f59 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -8397,13 +8397,19 @@ perform_implicit_conversion_flags (tree type, tree expr, tsubst_flags_t complain
}
expr = error_mark_node;
}
- else if (processing_template_decl)
+ else if (processing_template_decl
+ /* As a kludge, we always perform conversions between scalar
+ types, as IMPLICIT_CONV_EXPR confuses c_finish_omp_for. */
+ && !(SCALAR_TYPE_P (type) && SCALAR_TYPE_P (TREE_TYPE (expr))))
{
/* In a template, we are only concerned about determining the
type of non-dependent expressions, so we do not have to
- perform the actual conversion. */
- if (TREE_TYPE (expr) != type)
- expr = build_nop (type, expr);
+ perform the actual conversion. But for initializers, we
+ need to be able to perform it at instantiation
+ (or fold_non_dependent_expr) time. */
+ expr = build1 (IMPLICIT_CONV_EXPR, type, expr);
+ if (!(flags & LOOKUP_ONLYCONVERTING))
+ IMPLICIT_CONV_EXPR_DIRECT_INIT (expr) = true;
}
else
expr = convert_like (conv, expr, complain);
diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index 1866b81f802..035fdcd2f4e 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -267,6 +267,7 @@ cp_common_init_ts (void)
MARK_TS_TYPED (CONST_CAST_EXPR);
MARK_TS_TYPED (STATIC_CAST_EXPR);
MARK_TS_TYPED (DYNAMIC_CAST_EXPR);
+ MARK_TS_TYPED (IMPLICIT_CONV_EXPR);
MARK_TS_TYPED (TEMPLATE_ID_EXPR);
MARK_TS_TYPED (ARROW_EXPR);
MARK_TS_TYPED (SIZEOF_EXPR);
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index bb1b753c71b..be29870d93e 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -250,6 +250,7 @@ DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", tcc_unary, 1)
DEFTREECODE (CONST_CAST_EXPR, "const_cast_expr", tcc_unary, 1)
DEFTREECODE (STATIC_CAST_EXPR, "static_cast_expr", tcc_unary, 1)
DEFTREECODE (DYNAMIC_CAST_EXPR, "dynamic_cast_expr", tcc_unary, 1)
+DEFTREECODE (IMPLICIT_CONV_EXPR, "implicit_conv_expr", tcc_unary, 1)
DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", tcc_expression, 2)
DEFTREECODE (TYPEID_EXPR, "typeid_expr", tcc_expression, 1)
DEFTREECODE (NOEXCEPT_EXPR, "noexcept_expr", tcc_unary, 1)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f824f38b74a..b53accfed65 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -72,6 +72,7 @@ c-common.h, not after.
DECLTYPE_FOR_LAMBDA_CAPTURE (in DECLTYPE_TYPE)
VEC_INIT_EXPR_IS_CONSTEXPR (in VEC_INIT_EXPR)
DECL_OVERRIDE_P (in FUNCTION_DECL)
+ IMPLICIT_CONV_EXPR_DIRECT_INIT (in IMPLICIT_CONV_EXPR)
1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
@@ -3233,6 +3234,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
B b{1,2}, not B b({1,2}) or B b = {1,2}. */
#define CONSTRUCTOR_IS_DIRECT_INIT(NODE) (TREE_LANG_FLAG_0 (CONSTRUCTOR_CHECK (NODE)))
+/* True if NODE represents a conversion for direct-initialization in a
+ template. Set by perform_implicit_conversion_flags. */
+#define IMPLICIT_CONV_EXPR_DIRECT_INIT(NODE) \
+ (TREE_LANG_FLAG_0 (IMPLICIT_CONV_EXPR_CHECK (NODE)))
+
/* Nonzero means that an object of this type can not be initialized using
an initializer list. */
#define CLASSTYPE_NON_AGGREGATE(NODE) \
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index c5f1ac02cad..708afc8cdc2 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -830,6 +830,7 @@ pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
switch (TREE_CODE (t))
{
case CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
pp_cxx_type_id (pp, TREE_TYPE (t));
pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
break;
@@ -1084,6 +1085,7 @@ pp_cxx_expression (cxx_pretty_printer *pp, tree t)
break;
case CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
pp_cxx_cast_expression (pp, t);
break;
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 4d12a0dd43d..7d345c98922 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -2052,6 +2052,7 @@ dump_expr (tree t, int flags)
break;
CASE_CONVERT:
+ case IMPLICIT_CONV_EXPR:
case VIEW_CONVERT_EXPR:
{
tree op = TREE_OPERAND (t, 0);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2cb478d8053..bfbd2444325 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1591,6 +1591,7 @@ iterative_hash_template_arg (tree arg, hashval_t val)
return val;
case CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
case STATIC_CAST_EXPR:
case REINTERPRET_CAST_EXPR:
case CONST_CAST_EXPR:
@@ -7702,6 +7703,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
case MODOP_EXPR:
case CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
case REINTERPRET_CAST_EXPR:
case CONST_CAST_EXPR:
case STATIC_CAST_EXPR:
@@ -11714,7 +11716,7 @@ tsubst_qualified_id (tree qualified_id, tree args,
/* Like tsubst, but deals with expressions. This function just replaces
template parms; to finish processing the resultant expression, use
- tsubst_expr. */
+ tsubst_copy_and_build or tsubst_expr. */
static tree
tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
@@ -11879,6 +11881,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
case CONST_CAST_EXPR:
case STATIC_CAST_EXPR:
case DYNAMIC_CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
+ case CONVERT_EXPR:
case NOP_EXPR:
return build1
(code, tsubst (TREE_TYPE (t), args, complain, in_decl),
@@ -13081,6 +13085,23 @@ tsubst_copy_and_build (tree t,
(tsubst (TREE_TYPE (t), args, complain, in_decl),
RECUR (TREE_OPERAND (t, 0)));
+ case IMPLICIT_CONV_EXPR:
+ {
+ tree type = tsubst (TREE_TYPE (t), args, complain, in_decl);
+ tree expr = RECUR (TREE_OPERAND (t, 0));
+ int flags = LOOKUP_IMPLICIT;
+ if (IMPLICIT_CONV_EXPR_DIRECT_INIT (t))
+ flags = LOOKUP_NORMAL;
+ return perform_implicit_conversion_flags (type, expr, complain,
+ flags);
+ }
+
+ case CONVERT_EXPR:
+ return build1
+ (CONVERT_EXPR,
+ tsubst (TREE_TYPE (t), args, complain, in_decl),
+ RECUR (TREE_OPERAND (t, 0)));
+
case CAST_EXPR:
case REINTERPRET_CAST_EXPR:
case CONST_CAST_EXPR:
@@ -19176,6 +19197,7 @@ type_dependent_expression_p (tree expression)
|| TREE_CODE (expression) == STATIC_CAST_EXPR
|| TREE_CODE (expression) == CONST_CAST_EXPR
|| TREE_CODE (expression) == REINTERPRET_CAST_EXPR
+ || TREE_CODE (expression) == IMPLICIT_CONV_EXPR
|| TREE_CODE (expression) == CAST_EXPR)
return dependent_type_p (TREE_TYPE (expression));
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 7ad1e8d5ebd..189c13ad3e9 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -7481,8 +7481,6 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t,
return t;
case LAMBDA_EXPR:
- case DYNAMIC_CAST_EXPR:
- case PSEUDO_DTOR_EXPR:
case PREINCREMENT_EXPR:
case POSTINCREMENT_EXPR:
case PREDECREMENT_EXPR:
@@ -8023,6 +8021,7 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
case CONST_CAST_EXPR:
case STATIC_CAST_EXPR:
case REINTERPRET_CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
return (potential_constant_expression_1
(TREE_OPERAND (t, 0),
TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE, flags));
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index f23b888f376..75aa2650300 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2384,6 +2384,7 @@ cp_tree_equal (tree t1, tree t2)
case REINTERPRET_CAST_EXPR:
case CONST_CAST_EXPR:
case DYNAMIC_CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
case NEW_EXPR:
if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
return false;
@@ -2994,6 +2995,7 @@ cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
case STATIC_CAST_EXPR:
case CONST_CAST_EXPR:
case DYNAMIC_CAST_EXPR:
+ case IMPLICIT_CONV_EXPR:
if (TREE_TYPE (*tp))
WALK_SUBTREE (TREE_TYPE (*tp));