re PR c++/26693 (Access checks not performed for types in templates)

gcc/ChangeLog:
2009-04-02  Dodji Seketeli  <dodji@redhat.com>

    PR c++/26693
    * c-decl.c: (clone_underlying_type): Move this ...
    * c-common.c (set_underlying_type): ... here.
    Also, make sure the function properly sets TYPE_STUB_DECL() on
    the newly created typedef variant type.
    * c-common.h (is_typedef_decl, set_underlying_type): Declare ...
    * c-common.c (is_typedef_decl, set_underlying_type): ... new entry points.

gcc/cp/ChangeLog:
2009-04-02  Dodji Seketeli  <dodji@redhat.com>

    PR c++/26693
    * decl2.c (grokfield): when a typedef appears in a
    class, create the typedef variant type node for it.
    (save_template_attributes): Creating typedef variant type node
     here is now useless.
    * decl.c (grokdeclarator): If the typedef'ed struct/class was
    anonymous, set the proper type name to all its type variants.
    (xref_basetypes) : Fixup the variant types after setting
    TYPE_BINFO on REF.
    * name-lookup.c (pushdecl_maybe_friend): Reuse the
    set_underlying_type function to install typedef variant types.
    * cp-tree.h (MEMBER_TYPES_NEEDING_ACCESS_CHECK): New template accessor
    macro.
    (append_type_to_template_for_access_check): New entry points.
    * semantics.c (check_accessibility_of_qualified_id):
    When a typedef that is a member of a class appears in a template,
    add it to the template. It will be ...
    * class.c (finish_struct_bits): Split type variant fixup into ...
    (fixup_type_variants): A new entry point.
    * pt.c (instantiate_class_template, instantiate_template ): ... access
    checked at template instantiation time.
    (resolve_type_name_type): The type name should be the name of the
    main type variant.
    (retrieve_specialization): Specializations of template typedefs aren't
    to be looked up in DECL_TEMPLATE_INSTANTIATIONS (tmpl).
    (append_type_to_template_for_access_check): New entry point.
    (tsubst_decl): For typedefs, build the variant type from the correct
    original type.
    (get_class_bindings): Fix function comment.
    (perform_typedefs_access_check): New entry point.

gcc/testsuite/ChangeLog:
2009-04-02  Dodji Seketeli  <dodji@redhat.com>

    PR c++/26693
    * g++.dg/template/typedef11.C: New test.
    * g++.dg/template/typedef12.C: Likewise.
    * g++.dg/template/typedef13.C: Likewise.
    * g++.dg/template/typedef14.C: Likewise.
    * g++.dg/template/typedef15.C: Likewise.
    * g++.dg/template/typedef16.C: Likewise.
    * g++.dg/template/sfinae3.C: Compile this pedantically.
    The only errors expected should be the one saying the typedef is ill
    formed.
    * g++.old-deja/g++.pt/typename8.C: Likewise.
    * g++.dg/template/access11.C: Update this.

libstdc++-v3/ChangeLog:
2009-04-02  Dodji Seketeli  <dodji@redhat.com>

    * include/ext/bitmap_allocator.h: the typedefs should be made public
    if we want them to be accessible. This has been revealed by the patch
    that fixes PR c++/26693 in g++.

From-SVN: r145440
This commit is contained in:
Dodji Seketeli 2009-04-02 09:24:19 +00:00 committed by Dodji Seketeli
parent bf1cbdc6e4
commit d0940d5662
24 changed files with 449 additions and 123 deletions

View File

@ -1,3 +1,13 @@
2009-04-02 Dodji Seketeli <dodji@redhat.com>
PR c++/26693
* c-decl.c: (clone_underlying_type): Move this ...
* c-common.c (set_underlying_type): ... here.
Also, make sure the function properly sets TYPE_STUB_DECL() on
the newly created typedef variant type.
* c-common.h (is_typedef_decl, set_underlying_type): Declare ...
* c-common.c (is_typedef_decl, set_underlying_type): ... new entry points.
2009-04-02 Richard Guenther <rguenther@suse.de>
PR tree-optimization/37221

View File

@ -9172,4 +9172,76 @@ warn_for_sign_compare (location_t location,
}
}
/* Setup a TYPE_DECL node as a typedef representation.
X is a TYPE_DECL for a typedef statement. Create a brand new
..._TYPE node (which will be just a variant of the existing
..._TYPE node with identical properties) and then install X
as the TYPE_NAME of this brand new (duplicate) ..._TYPE node.
The whole point here is to end up with a situation where each
and every ..._TYPE node the compiler creates will be uniquely
associated with AT MOST one node representing a typedef name.
This way, even though the compiler substitutes corresponding
..._TYPE nodes for TYPE_DECL (i.e. "typedef name") nodes very
early on, later parts of the compiler can always do the reverse
translation and get back the corresponding typedef name. For
example, given:
typedef struct S MY_TYPE;
MY_TYPE object;
Later parts of the compiler might only know that `object' was of
type `struct S' if it were not for code just below. With this
code however, later parts of the compiler see something like:
struct S' == struct S
typedef struct S' MY_TYPE;
struct S' object;
And they can then deduce (from the node for type struct S') that
the original object declaration was:
MY_TYPE object;
Being able to do this is important for proper support of protoize,
and also for generating precise symbolic debugging information
which takes full account of the programmer's (typedef) vocabulary.
Obviously, we don't want to generate a duplicate ..._TYPE node if
the TYPE_DECL node that we are now processing really represents a
standard built-in type. */
void
set_underlying_type (tree x)
{
if (x == error_mark_node)
return;
if (DECL_IS_BUILTIN (x))
{
if (TYPE_NAME (TREE_TYPE (x)) == 0)
TYPE_NAME (TREE_TYPE (x)) = x;
}
else if (TREE_TYPE (x) != error_mark_node
&& DECL_ORIGINAL_TYPE (x) == NULL_TREE)
{
tree tt = TREE_TYPE (x);
DECL_ORIGINAL_TYPE (x) = tt;
tt = build_variant_type_copy (tt);
TYPE_STUB_DECL (tt) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
TYPE_NAME (tt) = x;
TREE_USED (tt) = TREE_USED (x);
TREE_TYPE (x) = tt;
}
}
/* Returns true if X is a typedef decl. */
bool
is_typedef_decl (tree x)
{
return (x && TREE_CODE (x) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (x) != NULL_TREE);
}
#include "gt-c-common.h"

View File

@ -1009,6 +1009,8 @@ extern void warn_for_sign_compare (location_t,
tree op0, tree op1,
tree result_type,
enum tree_code resultcode);
extern void set_underlying_type (tree x);
extern bool is_typedef_decl (tree x);
/* In c-gimplify.c */
extern void c_genericize (tree);

View File

@ -2002,67 +2002,6 @@ warn_if_shadowing (tree new_decl)
}
}
/* Subroutine of pushdecl.
X is a TYPE_DECL for a typedef statement. Create a brand new
..._TYPE node (which will be just a variant of the existing
..._TYPE node with identical properties) and then install X
as the TYPE_NAME of this brand new (duplicate) ..._TYPE node.
The whole point here is to end up with a situation where each
and every ..._TYPE node the compiler creates will be uniquely
associated with AT MOST one node representing a typedef name.
This way, even though the compiler substitutes corresponding
..._TYPE nodes for TYPE_DECL (i.e. "typedef name") nodes very
early on, later parts of the compiler can always do the reverse
translation and get back the corresponding typedef name. For
example, given:
typedef struct S MY_TYPE;
MY_TYPE object;
Later parts of the compiler might only know that `object' was of
type `struct S' if it were not for code just below. With this
code however, later parts of the compiler see something like:
struct S' == struct S
typedef struct S' MY_TYPE;
struct S' object;
And they can then deduce (from the node for type struct S') that
the original object declaration was:
MY_TYPE object;
Being able to do this is important for proper support of protoize,
and also for generating precise symbolic debugging information
which takes full account of the programmer's (typedef) vocabulary.
Obviously, we don't want to generate a duplicate ..._TYPE node if
the TYPE_DECL node that we are now processing really represents a
standard built-in type. */
static void
clone_underlying_type (tree x)
{
if (DECL_IS_BUILTIN (x))
{
if (TYPE_NAME (TREE_TYPE (x)) == 0)
TYPE_NAME (TREE_TYPE (x)) = x;
}
else if (TREE_TYPE (x) != error_mark_node
&& DECL_ORIGINAL_TYPE (x) == NULL_TREE)
{
tree tt = TREE_TYPE (x);
DECL_ORIGINAL_TYPE (x) = tt;
tt = build_variant_type_copy (tt);
TYPE_NAME (tt) = x;
TREE_USED (tt) = TREE_USED (x);
TREE_TYPE (x) = tt;
}
}
/* Record a decl-node X as belonging to the current lexical scope.
Check for errors (such as an incompatible declaration for the same
name already seen in the same scope).
@ -2288,7 +2227,7 @@ pushdecl (tree x)
skip_external_and_shadow_checks:
if (TREE_CODE (x) == TYPE_DECL)
clone_underlying_type (x);
set_underlying_type (x);
bind (name, x, scope, /*invisible=*/false, nested, locus);

View File

@ -1,3 +1,36 @@
2009-04-02 Dodji Seketeli <dodji@redhat.com>
PR c++/26693
* decl2.c (grokfield): when a typedef appears in a
class, create the typedef variant type node for it.
(save_template_attributes): Creating typedef variant type node
here is now useless.
* decl.c (grokdeclarator): If the typedef'ed struct/class was
anonymous, set the proper type name to all its type variants.
(xref_basetypes) : Fixup the variant types after setting
TYPE_BINFO on REF.
* name-lookup.c (pushdecl_maybe_friend): Reuse the
set_underlying_type function to install typedef variant types.
* cp-tree.h (MEMBER_TYPES_NEEDING_ACCESS_CHECK): New template accessor
macro.
(append_type_to_template_for_access_check): New entry points.
* semantics.c (check_accessibility_of_qualified_id):
When a typedef that is a member of a class appears in a template,
add it to the template. It will be ...
* class.c (finish_struct_bits): Split type variant fixup into ...
(fixup_type_variants): A new entry point.
* pt.c (instantiate_class_template, instantiate_template ): ... access
checked at template instantiation time.
(resolve_type_name_type): The type name should be the name of the
main type variant.
(retrieve_specialization): Specializations of template typedefs aren't
to looked up in DECL_TEMPLATE_INSTANTIATIONS (tmpl).
(append_type_to_template_for_access_check): New entry point.
(tsubst_decl): For typedefs, build the variant type from the correct
original type.
(get_class_bindings): Fix function comment.
(perform_typedefs_access_check): New entry point.
2009-03-31 Jason Merrill <jason@redhat.com>
PR c++/34691

View File

@ -1439,16 +1439,17 @@ determine_primary_bases (tree t)
BINFO_VIRTUALS (type_binfo) = BINFO_VIRTUALS (primary);
}
}
/* Set memoizing fields and bits of T (and its variants) for later
use. */
static void
finish_struct_bits (tree t)
/* Update the variant types of T. */
void
fixup_type_variants (tree t)
{
tree variants;
/* Fix up variants (if any). */
if (!t)
return;
for (variants = TYPE_NEXT_VARIANT (t);
variants;
variants = TYPE_NEXT_VARIANT (variants))
@ -1472,6 +1473,17 @@ finish_struct_bits (tree t)
/* All variants of a class have the same attributes. */
TYPE_ATTRIBUTES (variants) = TYPE_ATTRIBUTES (t);
}
}
/* Set memoizing fields and bits of T (and its variants) for later
use. */
static void
finish_struct_bits (tree t)
{
/* Fix up variants (if any). */
fixup_type_variants (t);
if (BINFO_N_BASE_BINFOS (TYPE_BINFO (t)) && TYPE_POLYMORPHIC_P (t))
/* For a class w/o baseclasses, 'finish_struct' has set

View File

@ -3181,6 +3181,11 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
&& TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == TYPE_DECL \
&& !DECL_TEMPLATE_TEMPLATE_PARM_P (NODE))
/* The chained list of typedefs that are referenced in templates.
These typedefs need to be access checked at template instantiation time.
There are put here at parsing time. */
#define MEMBER_TYPES_NEEDING_ACCESS_CHECK(NODE) DECL_ACCESS (NODE)
/* Nonzero if NODE which declares a type. */
#define DECL_DECLARES_TYPE_P(NODE) \
(TREE_CODE (NODE) == TYPE_DECL || DECL_CLASS_TEMPLATE_P (NODE))
@ -4278,6 +4283,7 @@ extern bool type_has_user_nondefault_constructor (tree);
extern bool type_has_user_provided_constructor (tree);
extern bool type_has_user_provided_default_constructor (tree);
extern bool defaultable_fn_p (tree);
extern void fixup_type_variants (tree);
/* in cvt.c */
extern tree convert_to_reference (tree, tree, int, int, tree);
@ -4548,6 +4554,7 @@ extern tree check_explicit_specialization (tree, tree, int, int);
extern tree make_auto (void);
extern tree do_auto_deduction (tree, tree, tree);
extern tree type_uses_auto (tree);
extern void append_type_to_template_for_access_check (tree, tree, tree);
extern tree splice_late_return_type (tree, tree);
extern bool is_auto (const_tree);
extern tree process_template_parm (tree, tree, bool, bool);

View File

@ -8823,12 +8823,11 @@ grokdeclarator (const cp_declarator *declarator,
&& TYPE_ANONYMOUS_P (type)
&& cp_type_quals (type) == TYPE_UNQUALIFIED)
{
tree oldname = TYPE_NAME (type);
tree t;
/* Replace the anonymous name with the real name everywhere. */
for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
if (TYPE_NAME (t) == oldname)
if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))
TYPE_NAME (t) = decl;
if (TYPE_LANG_SPECIFIC (type))
@ -10787,6 +10786,9 @@ xref_basetypes (tree ref, tree base_list)
BINFO_OFFSET (binfo) = size_zero_node;
BINFO_TYPE (binfo) = ref;
/* Apply base-class info set up to the variants of this type. */
fixup_type_variants (ref);
if (max_bases)
{
BINFO_BASE_ACCESSES (binfo) = VEC_alloc (tree, gc, max_bases);

View File

@ -820,6 +820,9 @@ grokfield (const cp_declarator *declarator,
cplus_decl_attributes (&value, attrlist, attrflags);
}
if (declspecs->specs[(int)ds_typedef])
set_underlying_type (value);
return value;
}
@ -1125,19 +1128,6 @@ save_template_attributes (tree *attr_p, tree *decl_p)
if (!late_attrs)
return;
/* Give this type a name so we know to look it up again at instantiation
time. */
if (TREE_CODE (*decl_p) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (*decl_p) == NULL_TREE)
{
tree oldt = TREE_TYPE (*decl_p);
tree newt = build_variant_type_copy (oldt);
DECL_ORIGINAL_TYPE (*decl_p) = oldt;
TREE_TYPE (*decl_p) = newt;
TYPE_NAME (newt) = *decl_p;
TREE_USED (newt) = TREE_USED (*decl_p);
}
if (DECL_P (*decl_p))
q = &DECL_ATTRIBUTES (*decl_p);
else

View File

@ -862,28 +862,20 @@ pushdecl_maybe_friend (tree x, bool is_friend)
/* If declaring a type as a typedef, copy the type (unless we're
at line 0), and install this TYPE_DECL as the new type's typedef
name. See the extensive comment in ../c-decl.c (pushdecl). */
name. See the extensive comment of set_underlying_type (). */
if (TREE_CODE (x) == TYPE_DECL)
{
tree type = TREE_TYPE (x);
if (DECL_IS_BUILTIN (x))
{
if (TYPE_NAME (type) == 0)
TYPE_NAME (type) = x;
}
else if (type != error_mark_node && TYPE_NAME (type) != x
/* We don't want to copy the type when all we're
doing is making a TYPE_DECL for the purposes of
inlining. */
&& (!TYPE_NAME (type)
|| TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x)))
{
DECL_ORIGINAL_TYPE (x) = type;
type = build_variant_type_copy (type);
TYPE_STUB_DECL (type) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x));
TYPE_NAME (type) = x;
TREE_TYPE (x) = type;
}
if (DECL_IS_BUILTIN (x)
|| (TREE_TYPE (x) != error_mark_node
&& TYPE_NAME (type) != x
/* We don't want to copy the type when all we're
doing is making a TYPE_DECL for the purposes of
inlining. */
&& (!TYPE_NAME (type)
|| TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x))))
set_underlying_type (x);
if (type != error_mark_node
&& TYPE_NAME (type)

View File

@ -175,6 +175,7 @@ static tree tsubst_expr (tree, tree, tsubst_flags_t, tree, bool);
static tree tsubst_copy (tree, tree, tsubst_flags_t, tree);
static tree tsubst_pack_expansion (tree, tree, tsubst_flags_t, tree);
static tree tsubst_decl (tree, tree, tsubst_flags_t);
static void perform_typedefs_access_check (tree tmpl, tree targs);
/* Make the current scope suitable for access checking when we are
processing T. T can be FUNCTION_DECL for instantiated function
@ -949,6 +950,7 @@ retrieve_specialization (tree tmpl, tree args,
DECL_TEMPLATE_SPECIALIZATIONS list. */
if (!class_specializations_p
&& TREE_CODE (DECL_TEMPLATE_RESULT (tmpl)) == TYPE_DECL
&& !is_typedef_decl (DECL_TEMPLATE_RESULT (tmpl))
&& TAGGED_TYPE_P (TREE_TYPE (tmpl)))
sp = &DECL_TEMPLATE_INSTANTIATIONS (tmpl);
else
@ -6928,6 +6930,37 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
}
}
/* Perform (or defer) access check for typedefs that were referenced
from within the template TMPL code.
This is a subroutine of instantiate_template and instantiate_class_template.
TMPL is the template to consider and TARGS is the list of arguments of
that template. */
static void
perform_typedefs_access_check (tree tmpl, tree targs)
{
tree t;
if (!tmpl || TREE_CODE (tmpl) != TEMPLATE_DECL)
return;
for (t = MEMBER_TYPES_NEEDING_ACCESS_CHECK (tmpl); t; t = TREE_CHAIN (t))
{
tree type_decl = TREE_PURPOSE (t);
tree type_scope = TREE_VALUE (t);
if (!type_decl || !type_scope || !CLASS_TYPE_P (type_scope))
continue;
if (uses_template_parms (type_decl))
type_decl = tsubst (type_decl, targs, tf_error, NULL_TREE);
if (uses_template_parms (type_scope))
type_scope = tsubst (type_scope, targs, tf_error, NULL_TREE);
perform_or_defer_access_check (TYPE_BINFO (type_scope), type_decl, type_decl);
}
}
tree
instantiate_class_template (tree type)
{
@ -7403,6 +7436,12 @@ instantiate_class_template (tree type)
&& DECL_TEMPLATE_INFO (t))
tsubst_default_arguments (t);
/* Some typedefs referenced from within the template code need to be access
checked at template instantiation time, i.e now. These types were
added to the template at parsing time. Let's get those and perform
the acces checks then. */
perform_typedefs_access_check (templ, args);
perform_deferred_access_checks ();
pop_nested_class ();
pop_from_top_level ();
pop_deferring_access_checks ();
@ -12024,6 +12063,12 @@ instantiate_template (tree tmpl, tree targ_ptr, tsubst_flags_t complain)
/* Now we know the specialization, compute access previously
deferred. */
push_access_scope (fndecl);
/* Some typedefs referenced from within the template code need to be access
checked at template instantiation time, i.e now. These types were
added to the template at parsing time. Let's get those and perfom
the acces checks then. */
perform_typedefs_access_check (tmpl, targ_ptr);
perform_deferred_access_checks ();
pop_access_scope (fndecl);
pop_deferring_access_checks ();
@ -14404,7 +14449,7 @@ get_bindings (tree fn, tree decl, tree explicit_args, bool check_rettype)
/* Return the innermost template arguments that, when applied to a
template specialization whose innermost template parameters are
TPARMS, and whose specialization arguments are PARMS, yield the
TPARMS, and whose specialization arguments are SPEC_ARGS, yield the
ARGS.
For example, suppose we have:
@ -16722,7 +16767,15 @@ resolve_typename_type (tree type, bool only_current_p)
gcc_assert (TREE_CODE (type) == TYPENAME_TYPE);
scope = TYPE_CONTEXT (type);
name = TYPE_IDENTIFIER (type);
/* Usually the non-qualified identifier of a TYPENAME_TYPE is
TYPE_IDENTIFIER (type). But when 'type' is a typedef variant of
a TYPENAME_TYPE node, then TYPE_NAME (type) is set to the TYPE_DECL representing
the typedef. In that case TYPE_IDENTIFIER (type) is not the non-qualified
identifier of the TYPENAME_TYPE anymore.
So by getting the TYPE_IDENTIFIER of the _main declaration_ of the
TYPENAME_TYPE instead, we avoid messing up with a possible
typedef variant case. */
name = TYPE_IDENTIFIER (TYPE_MAIN_VARIANT (type));
/* If the SCOPE is itself a TYPENAME_TYPE, then we need to resolve
it first before we can figure out what NAME refers to. */
@ -17047,4 +17100,46 @@ type_uses_auto (tree type)
return NULL_TREE;
}
/* Append TYPE_DECL to the template TEMPL.
TEMPL is either a class type or a FUNCTION_DECL associated
to a TEMPLATE_DECL.
At TEMPL instanciation time, TYPE_DECL will be checked to see
if it can be accessed through SCOPE. */
void
append_type_to_template_for_access_check (tree templ,
tree type_decl,
tree scope)
{
tree node, templ_decl;
gcc_assert (templ
&& get_template_info (templ)
&& TI_TEMPLATE (get_template_info (templ))
&& type_decl
&& (TREE_CODE (type_decl) == TYPE_DECL));
templ_decl = TI_TEMPLATE (get_template_info (templ));
gcc_assert (templ_decl);
/* Make sure we don't append the type to the template twice.
If this appears to be too slow, the
MEMBER_TYPE_NEEDING_ACCESS_CHECK property
of templ should be a hash table instead. */
for (node = MEMBER_TYPES_NEEDING_ACCESS_CHECK (templ_decl);
node;
node = TREE_CHAIN (node))
{
tree decl = TREE_PURPOSE (node);
tree type_scope = TREE_VALUE (node);
if (decl == type_decl && type_scope == scope)
return;
}
MEMBER_TYPES_NEEDING_ACCESS_CHECK (templ_decl) =
tree_cons (type_decl, scope,
MEMBER_TYPES_NEEDING_ACCESS_CHECK (templ_decl));
}
#include "gt-cp-pt.h"

View File

@ -1528,6 +1528,32 @@ check_accessibility_of_qualified_id (tree decl,
tree scope;
tree qualifying_type = NULL_TREE;
/* If we are parsing a template declaration and if decl is a typedef,
add it to a list tied to the template.
At template instantiation time, that list will be walked and
access check performed. */
if (is_typedef_decl (decl))
{
/* This the scope through which type_decl is accessed.
It will be useful information later to do access check for
type_decl usage. */
tree scope = nested_name_specifier
? nested_name_specifier
: DECL_CONTEXT (decl);
tree templ_info = NULL;
tree cs = current_scope ();
if (cs && (CLASS_TYPE_P (cs) || TREE_CODE (cs) == FUNCTION_DECL))
templ_info = get_template_info (cs);
if (templ_info
&& TI_TEMPLATE (templ_info)
&& scope
&& CLASS_TYPE_P (scope)
&& !currently_open_class (scope))
append_type_to_template_for_access_check (current_scope (), decl, scope);
}
/* If we're not checking, return immediately. */
if (deferred_access_no_check)
return;

View File

@ -1,3 +1,18 @@
2009-04-02 Dodji Seketeli <dodji@redhat.com>
PR c++/26693
* g++.dg/template/typedef11.C: New test.
* g++.dg/template/typedef12.C: Likewise.
* g++.dg/template/typedef13.C: Likewise.
* g++.dg/template/typedef14.C: Likewise.
* g++.dg/template/typedef15.C: Likewise.
* g++.dg/template/typedef16.C: Likewise.
* g++.dg/template/sfinae3.C: Compile this pedantically.
The only errors expected should be the one saying the typedef is ill
formed.
* g++.old-deja/g++.pt/typename8.C: Likewise.
* g++.dg/template/access11.C: Update this.
2009-04-02 Richard Guenther <rguenther@suse.de>
PR tree-optimization/37221

View File

@ -17,8 +17,8 @@ template <> struct X::Y<int> {
A::X x; // { dg-error "this context" }
};
template <typename T> struct X::Y {
template <typename T> struct X::Y { // { dg-error "this context" }
typename T::X x; // { dg-error "this context" }
};
template struct X::Y<A>; // { dg-message "instantiated" }
template struct X::Y<A>; // { dg-message "instantiated from here" }

View File

@ -1,5 +1,5 @@
// PR c++/24671
// { dg-options "" }
// { dg-do compile }
template<typename> struct A
{
@ -9,9 +9,9 @@ template<typename> struct A
template<typename> struct B
{
B(const B&); // { dg-message "candidate" }
typedef typename A<char[A<B>::i]>::X Y;
template<typename T> B(T, Y); // { dg-error "call" }
B(const B&);
typedef typename A<char[A<B>::i]>::X Y; // { dg-error "forbids zero-size array" }
template<typename T> B(T, Y);
};
B<int> b(0,0);
B<int> b(0,0); // { dg-message "instantiated from here" }

View File

@ -0,0 +1,25 @@
// Author: Dodji Seketeli <dodji@redhat.com>
// Origin: PR c++/26693
// { dg-do compile }
class Alpha
{
typedef int X; // { dg-error "'typedef int Alpha::X' is private" }
};
template<int>
class Beta
{
typedef int Y; // { dg-error "'typedef int Beta<0>::Y' is private" }
};
template <int>
int
bar ()
{
Beta<0>::Y i = 0;
return Alpha::X ();
}
int i = bar<0> (); // { dg-error "within this context" }

View File

@ -0,0 +1,23 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin: Jason Merrill <jason@redhat.com>, PR c++/26693
// { dg-do compile }
class A
{
protected:
typedef int mytype;
};
template <class T> class B;
class C: public A
{
template <class T> friend class B;
};
template <class T> class B
{
C::mytype mem;
};
B<int> b;

View File

@ -0,0 +1,16 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin: PR c++/26693
// { dg-do compile }
class A
{
typedef int mytype; // { dg-error "typedef int A::mytype' is private" }
};
template <class T> class B : public A
{ // { dg-error "within this context" }
mytype mem;
};
B<int> b; // { dg-message "instantiated from here" }

View File

@ -0,0 +1,16 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin: PR c++/26693
// { dg-do compile }
template <class T>
struct A
{
typedef int mytype;
void
foo ()
{
mytype v = ~static_cast<mytype> (0);
}
};

View File

@ -0,0 +1,25 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin: PR c++/26693
// { dg-do compile }
template<class T> struct C0;
struct Foo {
typedef int TypedefedFoo;
typedef C0<Foo> TypedefedC0;
};
template<class T>
struct C0
{
typedef Foo TypedefedFoo;
typename T::TypedefedC0::TypedefedFoo m;
};
template<class U>
struct C1
{
typedef C0<Foo> TypedefedC0;
};
C0<C1<int> > c;

View File

@ -0,0 +1,27 @@
// Contributed by Dodji Seketeli <dodji@redhat.com>
// Origin PR c++/26693
// { dg-do compile }
struct C0
{
};
template<class T, class U>
struct C1
{
typedef C0 TypedefedC0;
template<class W>
void foo (TypedefedC0 *, W)
{
}
template<class W> C1 (W w)
{
TypedefedC0 c;
foo (&c, w);
}
};
C0 c0;
C1<int, char> c1 (&c0);

View File

@ -5,14 +5,14 @@ template < class T > class A
public:
typedef typename T::myT anotherT; // { dg-error "" } undefined type
anotherT t; // { dg-error "" } undefined type
anotherT t;
A() { }
A(anotherT _t) { // { dg-error "" } undefined type
A(anotherT _t) {
t=_t;
}
anotherT getT() { // { dg-error "" } undefined type
anotherT getT() {
return t;
}
};

View File

@ -1,3 +1,9 @@
2009-04-02 Dodji Seketeli <dodji@redhat.com>
* include/ext/bitmap_allocator.h: the typedefs should be made public
if we want them to be accessible. This has been revealed by the patch
that fixes PR c++/26693 in g++.
2009-04-02 Jakub Jelinek <jakub@redhat.com>
* config/abi/post/powerpc64-linux-gnu/32/baseline_symbols.txt:
@ -785,11 +791,6 @@
on HPUX.
* configure: Regenerate.
2009-01-22 Dodji Seketeli <dodji@redhat.com>
* include/ext/bitmap_allocator.h: Reverting changes related to PR
c++/26693.
2009-01-21 Benjamin Kosnik <bkoz@redhat.com>
* testsuite/29_atomics/headers/stdatomic.h/functions.c: Remove
@ -797,10 +798,6 @@
2009-01-21 Dodji Seketeli <dodji@redhat.com>
* include/ext/bitmap_allocator.h: the typedefs should be made public
if we want them to be accessible. This has been revealed by the patch
that fixes PR c++/26693 in g++.
2009-01-20 Benjamin Kosnik <bkoz@redhat.com>
Uros Bizjak <ubizjak@gmail.com>

View File

@ -550,11 +550,13 @@ _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
*/
class free_list
{
public:
typedef size_t* value_type;
typedef __detail::__mini_vector<value_type> vector_type;
typedef vector_type::iterator iterator;
typedef __mutex __mutex_type;
private:
struct _LT_pointer_compare
{
bool