aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8/gcc/cp/pt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.8/gcc/cp/pt.c')
-rw-r--r--gcc-4.8/gcc/cp/pt.c98
1 files changed, 74 insertions, 24 deletions
diff --git a/gcc-4.8/gcc/cp/pt.c b/gcc-4.8/gcc/cp/pt.c
index 65bce34c7..e3968ec42 100644
--- a/gcc-4.8/gcc/cp/pt.c
+++ b/gcc-4.8/gcc/cp/pt.c
@@ -138,6 +138,7 @@ static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*,
tree);
static int type_unification_real (tree, tree, tree, const tree *,
unsigned int, int, unification_kind_t, int,
+ vec<deferred_access_check, va_gc> **,
bool);
static void note_template_header (int);
static tree convert_nontype_argument_function (tree, tree);
@@ -183,7 +184,7 @@ static int coerce_template_template_parms (tree, tree, tsubst_flags_t,
tree, tree);
static bool template_template_parm_bindings_ok_p (tree, tree);
static int template_args_equal (tree, tree);
-static void tsubst_default_arguments (tree);
+static void tsubst_default_arguments (tree, tsubst_flags_t);
static tree for_each_template_parm_r (tree *, int *, void *);
static tree copy_default_args_to_explicit_spec_1 (tree, tree);
static void copy_default_args_to_explicit_spec (tree);
@@ -5612,6 +5613,10 @@ convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
else
return NULL_TREE;
}
+
+ /* Avoid typedef problems. */
+ if (TREE_TYPE (expr) != type)
+ expr = fold_convert (type, expr);
}
/* [temp.arg.nontype]/5, bullet 2
@@ -9859,7 +9864,7 @@ tsubst_aggr_type (tree t,
FN), which has the indicated TYPE. */
tree
-tsubst_default_argument (tree fn, tree type, tree arg)
+tsubst_default_argument (tree fn, tree type, tree arg, tsubst_flags_t complain)
{
tree saved_class_ptr = NULL_TREE;
tree saved_class_ref = NULL_TREE;
@@ -9899,7 +9904,7 @@ tsubst_default_argument (tree fn, tree type, tree arg)
stack. */
++function_depth;
arg = tsubst_expr (arg, DECL_TI_ARGS (fn),
- tf_warning_or_error, NULL_TREE,
+ complain, NULL_TREE,
/*integral_constant_expression_p=*/false);
--function_depth;
pop_deferring_access_checks();
@@ -9911,12 +9916,13 @@ tsubst_default_argument (tree fn, tree type, tree arg)
cp_function_chain->x_current_class_ref = saved_class_ref;
}
- if (errorcount+sorrycount > errs)
+ if (errorcount+sorrycount > errs
+ && (complain & tf_warning_or_error))
inform (input_location,
" when instantiating default argument for call to %D", fn);
/* Make sure the default argument is reasonable. */
- arg = check_default_argument (type, arg);
+ arg = check_default_argument (type, arg, complain);
pop_access_scope (fn);
@@ -9926,7 +9932,7 @@ tsubst_default_argument (tree fn, tree type, tree arg)
/* Substitute into all the default arguments for FN. */
static void
-tsubst_default_arguments (tree fn)
+tsubst_default_arguments (tree fn, tsubst_flags_t complain)
{
tree arg;
tree tmpl_args;
@@ -9947,7 +9953,8 @@ tsubst_default_arguments (tree fn)
if (TREE_PURPOSE (arg))
TREE_PURPOSE (arg) = tsubst_default_argument (fn,
TREE_VALUE (arg),
- TREE_PURPOSE (arg));
+ TREE_PURPOSE (arg),
+ complain);
}
/* Substitute the ARGS into the T, which is a _DECL. Return the
@@ -10298,7 +10305,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
if (!member
&& !PRIMARY_TEMPLATE_P (gen_tmpl)
&& !uses_template_parms (argvec))
- tsubst_default_arguments (r);
+ tsubst_default_arguments (r, complain);
}
else
DECL_TEMPLATE_INFO (r) = NULL_TREE;
@@ -12507,6 +12514,9 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
case TYPE_DECL:
return tsubst (t, args, complain, in_decl);
+ case USING_DECL:
+ t = DECL_NAME (t);
+ /* Fall through. */
case IDENTIFIER_NODE:
if (IDENTIFIER_TYPENAME_P (t))
{
@@ -14974,7 +14984,6 @@ fn_type_unification (tree fn,
return error_mark_node;
tinst = build_tree_list (fn, NULL_TREE);
++deduction_depth;
- push_deferring_access_checks (dk_deferred);
gcc_assert (TREE_CODE (fn) == TEMPLATE_DECL);
@@ -15066,8 +15075,13 @@ fn_type_unification (tree fn,
}
processing_template_decl += incomplete;
input_location = DECL_SOURCE_LOCATION (fn);
+ /* Ignore any access checks; we'll see them again in
+ instantiate_template and they might have the wrong
+ access path at this point. */
+ push_deferring_access_checks (dk_deferred);
fntype = tsubst (TREE_TYPE (fn), explicit_targs,
complain | tf_partial, NULL_TREE);
+ pop_deferring_access_checks ();
input_location = loc;
processing_template_decl -= incomplete;
pop_tinst_level ();
@@ -15075,12 +15089,6 @@ fn_type_unification (tree fn,
if (fntype == error_mark_node)
goto fail;
- /* Throw away these access checks; we'll see them again in
- instantiate_template and they might have the wrong
- access path at this point. */
- pop_deferring_access_checks ();
- push_deferring_access_checks (dk_deferred);
-
/* Place the explicitly specified arguments in TARGS. */
for (i = NUM_TMPL_ARGS (explicit_targs); i--;)
TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (explicit_targs, i);
@@ -15106,9 +15114,15 @@ fn_type_unification (tree fn,
callers must be ready to deal with unification failures in any
event. */
+ /* type_unification_real will pass back any access checks from default
+ template argument substitution. */
+ vec<deferred_access_check, va_gc> *checks;
+ checks = NULL;
+
ok = !type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
targs, parms, args, nargs, /*subr=*/0,
- strict, flags, explain_p);
+ strict, flags, &checks, explain_p);
+
if (!ok)
goto fail;
@@ -15155,16 +15169,23 @@ fn_type_unification (tree fn,
excessive_deduction_depth = true;
goto fail;
}
+
+ /* Also collect access checks from the instantiation. */
+ reopen_deferring_access_checks (checks);
+
decl = instantiate_template (fn, targs, complain);
+
+ checks = get_deferred_access_checks ();
+ pop_deferring_access_checks ();
+
pop_tinst_level ();
if (decl == error_mark_node)
goto fail;
- /* Now perform any access checks encountered during deduction, such as
- for default template arguments. */
+ /* Now perform any access checks encountered during substitution. */
push_access_scope (decl);
- ok = perform_deferred_access_checks (complain);
+ ok = perform_access_checks (checks, complain);
pop_access_scope (decl);
if (!ok)
goto fail;
@@ -15193,7 +15214,6 @@ fn_type_unification (tree fn,
r = decl;
fail:
- pop_deferring_access_checks ();
--deduction_depth;
if (excessive_deduction_depth)
{
@@ -15454,7 +15474,10 @@ unify_one_argument (tree tparms, tree targs, tree parm, tree arg,
If SUBR is 1, we're being called recursively (to unify the
arguments of a function or method parameter of a function
- template). */
+ template).
+
+ CHECKS is a pointer to a vector of access checks encountered while
+ substituting default template arguments. */
static int
type_unification_real (tree tparms,
@@ -15465,6 +15488,7 @@ type_unification_real (tree tparms,
int subr,
unification_kind_t strict,
int flags,
+ vec<deferred_access_check, va_gc> **checks,
bool explain_p)
{
tree parm, arg;
@@ -15604,6 +15628,7 @@ type_unification_real (tree tparms,
{
tree parm = TREE_VALUE (TREE_VEC_ELT (tparms, i));
tree arg = TREE_PURPOSE (TREE_VEC_ELT (tparms, i));
+ reopen_deferring_access_checks (*checks);
location_t save_loc = input_location;
if (DECL_P (parm))
input_location = DECL_SOURCE_LOCATION (parm);
@@ -15611,6 +15636,8 @@ type_unification_real (tree tparms,
arg = convert_template_argument (parm, arg, targs, complain,
i, NULL_TREE);
input_location = save_loc;
+ *checks = get_deferred_access_checks ();
+ pop_deferring_access_checks ();
if (arg == error_mark_node)
return 1;
else
@@ -17078,7 +17105,7 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict,
return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm),
args, nargs, 1, DEDUCE_EXACT,
- LOOKUP_NORMAL, explain_p);
+ LOOKUP_NORMAL, NULL, explain_p);
}
case OFFSET_TYPE:
@@ -19888,6 +19915,29 @@ type_dependent_expression_p (tree expression)
&& VAR_HAD_UNKNOWN_BOUND (expression))
return true;
+ /* An array of unknown bound depending on a variadic parameter, eg:
+
+ template<typename... Args>
+ void foo (Args... args)
+ {
+ int arr[] = { args... };
+ }
+
+ template<int... vals>
+ void bar ()
+ {
+ int arr[] = { vals... };
+ }
+
+ If the array has no length and has an initializer, it must be that
+ we couldn't determine its length in cp_complete_array_type because
+ it is dependent. */
+ if (TREE_CODE (expression) == VAR_DECL
+ && TREE_CODE (TREE_TYPE (expression)) == ARRAY_TYPE
+ && !TYPE_DOMAIN (TREE_TYPE (expression))
+ && DECL_INITIAL (expression))
+ return true;
+
if (TREE_TYPE (expression) == unknown_type_node)
{
if (TREE_CODE (expression) == ADDR_EXPR)
@@ -20077,7 +20127,7 @@ bool
any_type_dependent_elements_p (const_tree list)
{
for (; list; list = TREE_CHAIN (list))
- if (value_dependent_expression_p (TREE_VALUE (list)))
+ if (type_dependent_expression_p (TREE_VALUE (list)))
return true;
return false;
@@ -20626,7 +20676,7 @@ do_auto_deduction (tree type, tree init, tree auto_node)
= build_tree_list (NULL_TREE, TYPE_NAME (auto_node));
val = type_unification_real (tparms, targs, parms, args, 1, 0,
DEDUCE_CALL, LOOKUP_NORMAL,
- /*explain_p=*/false);
+ NULL, /*explain_p=*/false);
if (val > 0)
{
if (processing_template_decl)