2011-12-11 Fabien Chene <fabien@gcc.gnu.org>
PR c++/14258
* g++.dg/template/using16.C: New.
* g++.dg/template/using17.C: New.
gcc/cp/ChangeLog
2011-12-11 Fabien Chene <fabien@gcc.gnu.org>
PR c++/14258
* cp-tree.h (USING_DECL_TYPENAME_P): New macro.
* parser.c (cp_parser_nonclass_name): Handle using declarations
that refer to a dependent type.
(cp_parser_using_declaration): Set USING_DECL_TYPENAME_P to 1 if
the using declaration refers to a dependent type.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182292
138bc75d-0d04-0410-961f-
82ee72b054a4
+2011-12-13 Fabien ChĂȘne <fabien@gcc.gnu.org>
+
+ PR c++/14258
+ * cp-tree.h (USING_DECL_TYPENAME_P): New macro.
+ * parser.c (cp_parser_nonclass_name): Handle using declarations
+ that refer to a dependent type.
+ (cp_parser_using_declaration): Set USING_DECL_TYPENAME_P to 1 if
+ the using declaration refers to a dependent type.
+
2011-12-12 Jakub Jelinek <jakub@redhat.com>
PR c++/51496
DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL)
DECL_MEMBER_TEMPLATE_P (in TEMPLATE_DECL)
FUNCTION_PARAMETER_PACK_P (in PARM_DECL)
+ USING_DECL_TYPENAME_P (in USING_DECL)
2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL).
DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL)
3: DECL_IN_AGGR_P.
/* The decls named by a using decl. */
#define USING_DECL_DECLS(NODE) DECL_INITIAL (USING_DECL_CHECK (NODE))
+/* Non zero if the using decl refers to a dependent type. */
+#define USING_DECL_TYPENAME_P(NODE) DECL_LANG_FLAG_1 (USING_DECL_CHECK (NODE))
+
/* In a VAR_DECL, true if we have a shadowed local variable
in the shadowed var table for this VAR_DECL. */
#define DECL_HAS_SHADOWED_FOR_VAR_P(NODE) \
/* Look up the type-name. */
type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);
- /* If it is a using decl, use its underlying decl. */
- type_decl = strip_using_decl (type_decl);
-
+ if (TREE_CODE (type_decl) == USING_DECL)
+ {
+ if (!DECL_DEPENDENT_P (type_decl))
+ type_decl = strip_using_decl (type_decl);
+ else if (USING_DECL_TYPENAME_P (type_decl))
+ {
+ /* We have found a type introduced by a using
+ declaration at class scope that refers to a dependent
+ type.
+
+ using typename :: [opt] nested-name-specifier unqualified-id ;
+ */
+ type_decl = make_typename_type (TREE_TYPE (type_decl),
+ DECL_NAME (type_decl),
+ typename_type, tf_error);
+ if (type_decl != error_mark_node)
+ type_decl = TYPE_NAME (type_decl);
+ }
+ }
+
if (TREE_CODE (type_decl) != TYPE_DECL
&& (objc_is_id (identifier) || objc_is_class_name (identifier)))
{
/* Create the USING_DECL. */
decl = do_class_using_decl (parser->scope, identifier);
+ if (typename_p)
+ USING_DECL_TYPENAME_P (decl) = 1;
+
if (check_for_bare_parameter_packs (decl))
return false;
else
parser->colon_corrects_to_scope_p = false;
if (cp_parser_using_declaration (parser, /*access_declaration=*/true))
- goto out;
+ {
+ warning (OPT_Wdeprecated, "access declarations are deprecated; "
+ "employ using declarations instead");
+ goto out;
+ }
/* Parse the decl-specifier-seq. */
decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
+2011-12-11 Fabien ChĂȘne <fabien@gcc.gnu.org>
+
+ PR c++/14258
+ * g++.dg/template/using16.C: New.
+ * g++.dg/template/using17.C: New.
+
2011-12-13 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/51362
--- /dev/null
+// { dg-do compile }
+
+template <class T>
+struct A
+{
+ typedef T type;
+};
+
+template <class T>
+struct B
+{
+ class type
+ {
+ type(); // { dg-error "private" }
+ };
+};
+
+template <class T>
+struct C : A<T>, B<T>
+{
+ using typename B<T>::type;
+
+ void f()
+ {
+ type j; // { dg-error "context" }
+ }
+};
+
+template class C<int>; // { dg-message "required" }
+
+template <class T>
+struct D
+{
+ typedef T type;
+};
+
+template <class T>
+class E : D<T>
+{
+ using typename D<T>::type; // { dg-message "previous" }
+ using typename D<T>::type; // { dg-error "redeclaration" }
+};
--- /dev/null
+// PR c++/14258
+// { dg-do run }
+
+template<typename T>
+struct A
+{
+ typedef T type;
+ typedef A type2;
+};
+
+template<typename T>
+struct B : A<T>
+{
+ using typename A<T>::type;
+ type t;
+
+ using typename A<T>::type2;
+
+ type f()
+ {
+ type i = 1;
+ return i;
+ }
+};
+
+int main()
+{
+ B<int>::type t = 4;
+ if (t != 4)
+ __builtin_abort();
+
+ B<double> b;
+ b.t = 3;
+ if (b.t != 3)
+ __builtin_abort();
+
+ B<long> b2;
+ if (b2.f() != 1)
+ __builtin_abort();
+
+ B<double>::type2::type tt = 12;
+ if (tt != 12)
+ __builtin_abort();
+}