Index: gcc/testsuite/g++.dg/template/using16.C
===================================================================
--- gcc/testsuite/g++.dg/template/using16.C	(revision 0)
+++ gcc/testsuite/g++.dg/template/using16.C	(revision 0)
@@ -0,0 +1,42 @@
+// { 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" }
+};
Index: gcc/testsuite/g++.dg/template/using17.C
===================================================================
--- gcc/testsuite/g++.dg/template/using17.C	(revision 0)
+++ gcc/testsuite/g++.dg/template/using17.C	(revision 0)
@@ -0,0 +1,44 @@
+// 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();
+}
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 182075)
+++ gcc/cp/parser.c	(working copy)
@@ -13807,9 +13807,26 @@ cp_parser_nonclass_name (cp_parser* pars
   /* 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)))
     {
@@ -14947,6 +14964,9 @@ cp_parser_using_declaration (cp_parser*
 	  /* 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
Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 182075)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -130,6 +130,7 @@ c-common.h, not after.
       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.
@@ -2521,6 +2522,9 @@ extern void decl_shadowed_for_var_insert
 /* 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) \
