re PR c++/11596 (ICE with int templates)
cp: PR c++/11596 * pt.c (maybe_fold_nontype_arg, maybe_fold_nontype_args): Remove. (tsubst_template_arg): New. (tsubst_template_arg_vector): Rename to ... (tsubst_template_args): ... this. Accept a TREE_LIST form. Use tsubst_template_arg. (coerce_template_parms): Use tsubst_template_arg for default value. (tsubst_template_parms): Likewise. (tsubst_aggr_type): Adjust. (tsubst_decl): Likewise. (tsubst): Use tsubst_template_arg for a DOMAIN. Adjust. (tsubst_copy) <TEMPLATE_ID_EXPR case>: Use tsubst_template_args. testsuite: PR 11596 * g++.dg/template/defarg3.C: New test. * g++.dg/ext/packed2.C: Pack member struct too. Explain why. From-SVN: r69776
This commit is contained in:
parent
b6fe0bb8c5
commit
a91db71189
|
@ -1,11 +1,27 @@
|
||||||
|
2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
|
||||||
|
|
||||||
|
PR c++/11596
|
||||||
|
* pt.c (maybe_fold_nontype_arg, maybe_fold_nontype_args): Remove.
|
||||||
|
(tsubst_template_arg): New.
|
||||||
|
(tsubst_template_arg_vector): Rename to ...
|
||||||
|
(tsubst_template_args): ... this. Accept a TREE_LIST form. Use
|
||||||
|
tsubst_template_arg.
|
||||||
|
(coerce_template_parms): Use tsubst_template_arg for default
|
||||||
|
value.
|
||||||
|
(tsubst_template_parms): Likewise.
|
||||||
|
(tsubst_aggr_type): Adjust.
|
||||||
|
(tsubst_decl): Likewise.
|
||||||
|
(tsubst): Use tsubst_template_arg for a DOMAIN. Adjust.
|
||||||
|
(tsubst_copy) <TEMPLATE_ID_EXPR case>: Use tsubst_template_args.
|
||||||
|
|
||||||
2003-07-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
2003-07-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
|
||||||
|
|
||||||
* Make-lang.in (cp/error.o): Depend on DIAGNOSTIC_H.
|
* Make-lang.in (cp/error.o): Depend on DIAGNOSTIC_H.
|
||||||
* error.c: Use the new pretty-printer fraamework.
|
* error.c: Use the new pretty-printer framework.
|
||||||
|
|
||||||
2003-07-24 Per Bothner <pbothner@apple.com>
|
2003-07-24 Per Bothner <pbothner@apple.com>
|
||||||
|
|
||||||
* decl.c (pushdecl_class_level): Don't use push_srcloc/pop_srcloc
|
* decl.c (pushdecl_class_level): Don't use push_srcloc/pop_srcloc
|
||||||
which causes errors messages to incorrectly mention included files.
|
which causes errors messages to incorrectly mention included files.
|
||||||
|
|
||||||
2003-07-24 Mark Mitchell <mark@codesourcery.com>
|
2003-07-24 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
237
gcc/cp/pt.c
237
gcc/cp/pt.c
|
@ -111,8 +111,6 @@ static int maybe_adjust_types_for_deduction (unification_kind_t, tree*, tree*);
|
||||||
static int type_unification_real (tree, tree, tree, tree,
|
static int type_unification_real (tree, tree, tree, tree,
|
||||||
int, unification_kind_t, int, int);
|
int, unification_kind_t, int, int);
|
||||||
static void note_template_header (int);
|
static void note_template_header (int);
|
||||||
static tree maybe_fold_nontype_arg (tree);
|
|
||||||
static void maybe_fold_nontype_args (tree);
|
|
||||||
static tree convert_nontype_argument (tree, tree);
|
static tree convert_nontype_argument (tree, tree);
|
||||||
static tree convert_template_argument (tree, tree, tree,
|
static tree convert_template_argument (tree, tree, tree,
|
||||||
tsubst_flags_t, int, tree);
|
tsubst_flags_t, int, tree);
|
||||||
|
@ -136,7 +134,8 @@ static tree get_bindings (tree, tree, tree);
|
||||||
static tree get_bindings_real (tree, tree, tree, int, int, int);
|
static tree get_bindings_real (tree, tree, tree, int, int, int);
|
||||||
static int template_decl_level (tree);
|
static int template_decl_level (tree);
|
||||||
static int check_cv_quals_for_unify (int, tree, tree);
|
static int check_cv_quals_for_unify (int, tree, tree);
|
||||||
static tree tsubst_template_arg_vector (tree, tree, tsubst_flags_t);
|
static tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree);
|
||||||
|
static tree tsubst_template_args (tree, tree, tsubst_flags_t, tree);
|
||||||
static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
|
static tree tsubst_template_parms (tree, tree, tsubst_flags_t);
|
||||||
static void regenerate_decl_from_template (tree, tree);
|
static void regenerate_decl_from_template (tree, tree);
|
||||||
static tree most_specialized (tree, tree, tree);
|
static tree most_specialized (tree, tree, tree);
|
||||||
|
@ -3641,19 +3640,11 @@ coerce_template_parms (tree parms,
|
||||||
}
|
}
|
||||||
else if (i < nargs)
|
else if (i < nargs)
|
||||||
arg = TREE_VEC_ELT (inner_args, i);
|
arg = TREE_VEC_ELT (inner_args, i);
|
||||||
/* If no template argument was supplied, look for a default
|
|
||||||
value. */
|
|
||||||
else if (TREE_PURPOSE (parm) == NULL_TREE)
|
|
||||||
{
|
|
||||||
/* There was no default value. */
|
|
||||||
my_friendly_assert (!require_all_arguments, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL)
|
|
||||||
arg = tsubst (TREE_PURPOSE (parm), new_args, complain, in_decl);
|
|
||||||
else
|
else
|
||||||
arg = tsubst_expr (TREE_PURPOSE (parm), new_args, complain,
|
/* If no template argument was supplied, look for a default
|
||||||
in_decl);
|
value. */
|
||||||
|
arg = tsubst_template_arg (TREE_PURPOSE (parm), new_args,
|
||||||
|
complain, in_decl);
|
||||||
|
|
||||||
/* Now, convert the Ith argument, as necessary. */
|
/* Now, convert the Ith argument, as necessary. */
|
||||||
if (arg == NULL_TREE)
|
if (arg == NULL_TREE)
|
||||||
|
@ -5473,97 +5464,103 @@ list_eq (tree t1, tree t2)
|
||||||
return list_eq (TREE_CHAIN (t1), TREE_CHAIN (t2));
|
return list_eq (TREE_CHAIN (t1), TREE_CHAIN (t2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If arg is a non-type template parameter that does not depend on template
|
|
||||||
arguments, fold it like we weren't in the body of a template. */
|
|
||||||
|
|
||||||
static tree
|
static tree
|
||||||
maybe_fold_nontype_arg (tree arg)
|
tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||||
{
|
{
|
||||||
if (arg && !TYPE_P (arg) && !uses_template_parms (arg))
|
tree r;
|
||||||
{
|
|
||||||
/* Sometimes, one of the args was an expression involving a
|
if (!t)
|
||||||
template constant parameter, like N - 1. Now that we've
|
r = t;
|
||||||
tsubst'd, we might have something like 2 - 1. This will
|
else if (TYPE_P (t))
|
||||||
confuse lookup_template_class, so we do constant folding
|
r = tsubst (t, args, complain, in_decl);
|
||||||
here. We have to unset processing_template_decl, to fool
|
|
||||||
tsubst_copy_and_build() into building an actual tree. */
|
|
||||||
|
|
||||||
/* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already
|
|
||||||
as simple as it's going to get, and trying to reprocess
|
|
||||||
the trees will break. */
|
|
||||||
if (!TREE_TYPE (arg))
|
|
||||||
{
|
|
||||||
int saved_processing_template_decl = processing_template_decl;
|
|
||||||
processing_template_decl = 0;
|
|
||||||
arg = tsubst_copy_and_build (arg,
|
|
||||||
/*args=*/NULL_TREE,
|
|
||||||
tf_error,
|
|
||||||
/*in_decl=*/NULL_TREE,
|
|
||||||
/*function_p=*/false);
|
|
||||||
processing_template_decl = saved_processing_template_decl;
|
|
||||||
}
|
|
||||||
|
|
||||||
arg = fold (arg);
|
|
||||||
}
|
|
||||||
return arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Apply maybe_fold_nontype_arg on a list or vector of args. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
maybe_fold_nontype_args (tree targs)
|
|
||||||
{
|
|
||||||
if (!targs)
|
|
||||||
/*OK*/;
|
|
||||||
else if (TREE_CODE (targs) == TREE_LIST)
|
|
||||||
{
|
|
||||||
tree chain;
|
|
||||||
for (chain = targs; chain; chain = TREE_CHAIN (chain))
|
|
||||||
TREE_VALUE (chain) = maybe_fold_nontype_arg (TREE_VALUE (chain));
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int i;
|
r = tsubst_expr (t, args, complain, in_decl);
|
||||||
for (i = 0; i < TREE_VEC_LENGTH (targs); ++i)
|
|
||||||
TREE_VEC_ELT (targs, i)
|
if (!uses_template_parms (r))
|
||||||
= maybe_fold_nontype_arg (TREE_VEC_ELT (targs, i));
|
{
|
||||||
|
/* Sometimes, one of the args was an expression involving a
|
||||||
|
template constant parameter, like N - 1. Now that we've
|
||||||
|
tsubst'd, we might have something like 2 - 1. This will
|
||||||
|
confuse lookup_template_class, so we do constant folding
|
||||||
|
here. We have to unset processing_template_decl, to fool
|
||||||
|
tsubst_copy_and_build() into building an actual tree. */
|
||||||
|
|
||||||
|
/* If the TREE_TYPE of ARG is not NULL_TREE, ARG is already
|
||||||
|
as simple as it's going to get, and trying to reprocess
|
||||||
|
the trees will break. Once tsubst_expr et al DTRT for
|
||||||
|
non-dependent exprs, this code can go away, as the type
|
||||||
|
will always be set. */
|
||||||
|
if (!TREE_TYPE (r))
|
||||||
|
{
|
||||||
|
int saved_processing_template_decl = processing_template_decl;
|
||||||
|
processing_template_decl = 0;
|
||||||
|
r = tsubst_copy_and_build (r, /*args=*/NULL_TREE,
|
||||||
|
tf_error, /*in_decl=*/NULL_TREE,
|
||||||
|
/*function_p=*/false);
|
||||||
|
processing_template_decl = saved_processing_template_decl;
|
||||||
|
}
|
||||||
|
r = fold (r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Substitute ARGS into the vector of template arguments T. */
|
/* Substitute ARGS into the vector or list of template arguments T. */
|
||||||
|
|
||||||
static tree
|
static tree
|
||||||
tsubst_template_arg_vector (tree t, tree args, tsubst_flags_t complain)
|
tsubst_template_args (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||||
{
|
{
|
||||||
int len = TREE_VEC_LENGTH (t), need_new = 0, i;
|
int is_list = !(t && TREE_CODE (t) == TREE_VEC);
|
||||||
|
int len = is_list ? list_length (t) : TREE_VEC_LENGTH (t);
|
||||||
|
int need_new = 0, i;
|
||||||
|
tree position = t;
|
||||||
tree *elts = alloca (len * sizeof (tree));
|
tree *elts = alloca (len * sizeof (tree));
|
||||||
|
|
||||||
memset (elts, 0, len * sizeof (tree));
|
|
||||||
|
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
if (TREE_VEC_ELT (t, i) != NULL_TREE
|
tree orig_arg;
|
||||||
&& TREE_CODE (TREE_VEC_ELT (t, i)) == TREE_VEC)
|
tree new_arg = NULL_TREE;
|
||||||
elts[i] = tsubst_template_arg_vector (TREE_VEC_ELT (t, i),
|
|
||||||
args, complain);
|
if (is_list)
|
||||||
|
{
|
||||||
|
orig_arg = TREE_VALUE (position);
|
||||||
|
position = TREE_CHAIN (position);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
elts[i] = maybe_fold_nontype_arg
|
{
|
||||||
(tsubst_expr (TREE_VEC_ELT (t, i), args, complain,
|
orig_arg = TREE_VEC_ELT (t, i);
|
||||||
NULL_TREE));
|
if (TREE_CODE (orig_arg) == TREE_VEC)
|
||||||
|
new_arg = tsubst_template_args (orig_arg, args, complain, in_decl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!new_arg)
|
||||||
|
new_arg = tsubst_template_arg (orig_arg, args, complain, in_decl);
|
||||||
|
|
||||||
if (elts[i] == error_mark_node)
|
if (new_arg == error_mark_node)
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
|
|
||||||
if (elts[i] != TREE_VEC_ELT (t, i))
|
elts[i] = new_arg;
|
||||||
|
if (new_arg != orig_arg)
|
||||||
need_new = 1;
|
need_new = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!need_new)
|
if (!need_new)
|
||||||
return t;
|
return t;
|
||||||
|
|
||||||
t = make_tree_vec (len);
|
if (is_list)
|
||||||
for (i = 0; i < len; i++)
|
{
|
||||||
TREE_VEC_ELT (t, i) = elts[i];
|
t = NULL_TREE;
|
||||||
|
|
||||||
|
for (i = len; i--;)
|
||||||
|
t = tree_cons (NULL_TREE, elts[i], t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t = make_tree_vec (len);
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
TREE_VEC_ELT (t, i) = elts[i];
|
||||||
|
}
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -5597,10 +5594,10 @@ tsubst_template_parms (tree parms, tree args, tsubst_flags_t complain)
|
||||||
tree parm_decl = TREE_VALUE (tuple);
|
tree parm_decl = TREE_VALUE (tuple);
|
||||||
|
|
||||||
parm_decl = tsubst (parm_decl, args, complain, NULL_TREE);
|
parm_decl = tsubst (parm_decl, args, complain, NULL_TREE);
|
||||||
default_value = tsubst_expr (default_value, args,
|
default_value = tsubst_template_arg (default_value, args,
|
||||||
complain, NULL_TREE);
|
complain, NULL_TREE);
|
||||||
tuple = build_tree_list (maybe_fold_nontype_arg (default_value),
|
|
||||||
parm_decl);
|
tuple = build_tree_list (default_value, parm_decl);
|
||||||
TREE_VEC_ELT (new_vec, i) = tuple;
|
TREE_VEC_ELT (new_vec, i) = tuple;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5662,8 +5659,8 @@ tsubst_aggr_type (tree t,
|
||||||
and supposing that we are instantiating f<int, double>,
|
and supposing that we are instantiating f<int, double>,
|
||||||
then our ARGS will be {int, double}, but, when looking up
|
then our ARGS will be {int, double}, but, when looking up
|
||||||
S we only want {double}. */
|
S we only want {double}. */
|
||||||
argvec = tsubst_template_arg_vector (TYPE_TI_ARGS (t), args,
|
argvec = tsubst_template_args (TYPE_TI_ARGS (t), args,
|
||||||
complain);
|
complain, in_decl);
|
||||||
if (argvec == error_mark_node)
|
if (argvec == error_mark_node)
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
|
|
||||||
|
@ -5779,10 +5776,10 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
|
||||||
: DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t));
|
: DECL_TI_ARGS (DECL_TEMPLATE_RESULT (t));
|
||||||
tree full_args;
|
tree full_args;
|
||||||
|
|
||||||
full_args = tsubst_template_arg_vector (tmpl_args, args,
|
full_args = tsubst_template_args (tmpl_args, args,
|
||||||
complain);
|
complain, in_decl);
|
||||||
|
|
||||||
/* tsubst_template_arg_vector doesn't copy the vector if
|
/* tsubst_template_args doesn't copy the vector if
|
||||||
nothing changed. But, *something* should have
|
nothing changed. But, *something* should have
|
||||||
changed. */
|
changed. */
|
||||||
my_friendly_assert (full_args != tmpl_args, 0);
|
my_friendly_assert (full_args != tmpl_args, 0);
|
||||||
|
@ -5895,10 +5892,9 @@ tsubst_decl (tree t, tree args, tree type, tsubst_flags_t complain)
|
||||||
specialization, and the complete set of arguments used to
|
specialization, and the complete set of arguments used to
|
||||||
specialize R. */
|
specialize R. */
|
||||||
gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t));
|
gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t));
|
||||||
argvec
|
argvec = tsubst_template_args (DECL_TI_ARGS
|
||||||
= tsubst_template_arg_vector (DECL_TI_ARGS
|
(DECL_TEMPLATE_RESULT (gen_tmpl)),
|
||||||
(DECL_TEMPLATE_RESULT (gen_tmpl)),
|
args, complain, in_decl);
|
||||||
args, complain);
|
|
||||||
|
|
||||||
/* Check to see if we already have this specialization. */
|
/* Check to see if we already have this specialization. */
|
||||||
spec = retrieve_specialization (gen_tmpl, argvec);
|
spec = retrieve_specialization (gen_tmpl, argvec);
|
||||||
|
@ -6477,12 +6473,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||||
{
|
{
|
||||||
tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
|
tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
|
||||||
|
|
||||||
max = tsubst_expr (omax, args, complain, in_decl);
|
/* The array dimension behaves like a non-type template arg,
|
||||||
if (max == error_mark_node)
|
in that we want to fold it as much as possible. */
|
||||||
return error_mark_node;
|
max = tsubst_template_arg (omax, args, complain, in_decl);
|
||||||
|
|
||||||
/* See if we can reduce this expression to something simpler. */
|
|
||||||
max = maybe_fold_nontype_arg (max);
|
|
||||||
if (!processing_template_decl)
|
if (!processing_template_decl)
|
||||||
max = decl_constant_value (max);
|
max = decl_constant_value (max);
|
||||||
|
|
||||||
|
@ -6726,7 +6719,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, a vector of template arguments. */
|
/* Otherwise, a vector of template arguments. */
|
||||||
return tsubst_template_arg_vector (t, args, complain);
|
return tsubst_template_args (t, args, complain, in_decl);
|
||||||
|
|
||||||
case POINTER_TYPE:
|
case POINTER_TYPE:
|
||||||
case REFERENCE_TYPE:
|
case REFERENCE_TYPE:
|
||||||
|
@ -7157,8 +7150,7 @@ tsubst_qualified_id (tree qualified_id, tree args,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!BASELINK_P (name) && !DECL_P (expr))
|
if (!BASELINK_P (name) && !DECL_P (expr))
|
||||||
expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0,
|
expr = lookup_qualified_name (scope, expr, /*is_type_p=*/0, false);
|
||||||
(complain & tf_error) != 0);
|
|
||||||
if (DECL_P (expr))
|
if (DECL_P (expr))
|
||||||
check_accessibility_of_qualified_id (expr,
|
check_accessibility_of_qualified_id (expr,
|
||||||
/*object_type=*/NULL_TREE,
|
/*object_type=*/NULL_TREE,
|
||||||
|
@ -7175,7 +7167,9 @@ tsubst_qualified_id (tree qualified_id, tree args,
|
||||||
if (is_template)
|
if (is_template)
|
||||||
expr = lookup_template_function (expr, template_args);
|
expr = lookup_template_function (expr, template_args);
|
||||||
|
|
||||||
if (TYPE_P (scope))
|
if (expr == error_mark_node && complain & tf_error)
|
||||||
|
nested_name_lookup_error (scope, TREE_OPERAND (qualified_id, 1));
|
||||||
|
else if (TYPE_P (scope))
|
||||||
{
|
{
|
||||||
expr = (adjust_result_of_qualified_name_lookup
|
expr = (adjust_result_of_qualified_name_lookup
|
||||||
(expr, scope, current_class_type));
|
(expr, scope, current_class_type));
|
||||||
|
@ -7459,12 +7453,13 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||||
case TEMPLATE_ID_EXPR:
|
case TEMPLATE_ID_EXPR:
|
||||||
{
|
{
|
||||||
/* Substituted template arguments */
|
/* Substituted template arguments */
|
||||||
tree targs = tsubst_copy (TREE_OPERAND (t, 1), args, complain,
|
tree fn = TREE_OPERAND (t, 0);
|
||||||
in_decl);
|
tree targs = TREE_OPERAND (t, 1);
|
||||||
|
|
||||||
maybe_fold_nontype_args (targs);
|
fn = tsubst_copy (fn, args, complain, in_decl);
|
||||||
return lookup_template_function
|
targs = tsubst_template_args (targs, args, complain, in_decl);
|
||||||
(tsubst_copy (TREE_OPERAND (t, 0), args, complain, in_decl), targs);
|
|
||||||
|
return lookup_template_function (fn, targs);
|
||||||
}
|
}
|
||||||
|
|
||||||
case TREE_LIST:
|
case TREE_LIST:
|
||||||
|
@ -7595,12 +7590,15 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||||
{
|
{
|
||||||
tree scope = DECL_INITIAL (decl);
|
tree scope = DECL_INITIAL (decl);
|
||||||
tree name = DECL_NAME (decl);
|
tree name = DECL_NAME (decl);
|
||||||
|
tree decl;
|
||||||
|
|
||||||
scope = tsubst_expr (scope, args, complain, in_decl);
|
scope = tsubst_expr (scope, args, complain, in_decl);
|
||||||
do_local_using_decl (lookup_qualified_name (scope,
|
decl = lookup_qualified_name (scope, name,
|
||||||
name,
|
/*is_type_p=*/0, /*complain=*/false);
|
||||||
/*is_type_p=*/0,
|
if (decl == error_mark_node)
|
||||||
/*complain=*/true));
|
nested_name_lookup_error (scope, name);
|
||||||
|
else
|
||||||
|
do_local_using_decl (decl);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -8258,18 +8256,15 @@ tsubst_copy_and_build (tree t,
|
||||||
scope is. */
|
scope is. */
|
||||||
tmpl = TREE_OPERAND (TREE_OPERAND (member, 1), 0);
|
tmpl = TREE_OPERAND (TREE_OPERAND (member, 1), 0);
|
||||||
args = TREE_OPERAND (TREE_OPERAND (member, 1), 1);
|
args = TREE_OPERAND (TREE_OPERAND (member, 1), 1);
|
||||||
member = lookup_qualified_name (TREE_OPERAND (member, 0),
|
member = lookup_qualified_name (TREE_OPERAND (member, 0), tmpl,
|
||||||
tmpl,
|
/*is_type=*/0, /*complain=*/false);
|
||||||
/*is_type=*/0,
|
|
||||||
/*complain=*/true);
|
|
||||||
if (BASELINK_P (member))
|
if (BASELINK_P (member))
|
||||||
BASELINK_FUNCTIONS (member)
|
BASELINK_FUNCTIONS (member)
|
||||||
= build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
|
= build_nt (TEMPLATE_ID_EXPR, BASELINK_FUNCTIONS (member),
|
||||||
args);
|
args);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error ("`%D' is not a member of `%T'",
|
nested_name_lookup_error (TREE_TYPE (object), tmpl);
|
||||||
tmpl, TREE_TYPE (object));
|
|
||||||
return error_mark_node;
|
return error_mark_node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2003-07-25 Nathan Sidwell <nathan@codesourcery.com>
|
||||||
|
|
||||||
|
PR 11596
|
||||||
|
* g++.dg/template/defarg3.C: New test.
|
||||||
|
|
||||||
|
* g++.dg/ext/packed2.C: Pack member struct too. Explain why.
|
||||||
|
|
||||||
2003-07-24 Mark Mitchell <mark@codesourcery.com>
|
2003-07-24 Mark Mitchell <mark@codesourcery.com>
|
||||||
|
|
||||||
* g++.dg/inherit/access5.C: New test.
|
* g++.dg/inherit/access5.C: New test.
|
||||||
|
|
|
@ -1,18 +1,23 @@
|
||||||
// PR c++/10091
|
// PR c++/10091
|
||||||
|
|
||||||
|
// Original synopsis
|
||||||
// Bug: We were dying because in general, B::a doesn't have enough
|
// Bug: We were dying because in general, B::a doesn't have enough
|
||||||
// alignment for us to take its address. But if the B is C::b, it does
|
// alignment for us to take its address. But if the B is C::b, it does
|
||||||
// have enough alignment, and we should be able to determine that.
|
// have enough alignment, and we should be able to determine that.
|
||||||
|
|
||||||
// This only failed on STRICT_ALIGNMENT targets (i.e. not i686)
|
// This only failed on STRICT_ALIGNMENT targets (i.e. not i686)
|
||||||
|
|
||||||
|
// July 2003
|
||||||
|
// packing of non-pods is now only allowed if the non-pod is itself
|
||||||
|
// packed. Also only such pods can be reference bound to non-consts
|
||||||
|
|
||||||
struct A {
|
struct A {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
A();
|
A();
|
||||||
A(const A&);
|
A(const A&);
|
||||||
A& operator=(const A&);
|
A& operator=(const A&);
|
||||||
};
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct B {
|
struct B {
|
||||||
A a;
|
A a;
|
||||||
|
@ -23,8 +28,8 @@ struct C {
|
||||||
int j;
|
int j;
|
||||||
};
|
};
|
||||||
|
|
||||||
void f (const A&);
|
void f (A&);
|
||||||
void g (const C& c)
|
void g (C& c)
|
||||||
{
|
{
|
||||||
f (c.b.a);
|
f (c.b.a);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
// { dg-do compile }
|
||||||
|
|
||||||
|
// Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
// Contributed by Nathan Sidwell 22 Jul 2003 <nathan@codesourcery.com>
|
||||||
|
|
||||||
|
// PR c++ 11596
|
||||||
|
|
||||||
|
template <int V, bool F = V < 1> struct A { enum { value }; };
|
||||||
|
template <int V> struct B { enum { value = A<1>::value }; };
|
||||||
|
int ary[!B<1>::value ? 1 : -1];
|
||||||
|
|
||||||
|
template <int V, bool F = V < 1> struct A1 { enum { value = 1}; };
|
||||||
|
template <int V> struct A1<V,false> { enum { value}; };
|
||||||
|
template <int V> struct B1 { enum { value = A1<1>::value }; };
|
||||||
|
|
||||||
|
int ary1[!B1<1>::value ? 1 : -1];
|
Loading…
Reference in New Issue