Patchwork C++ PATCH for c++/49181 (error reporting re-entered)

login
register
mail settings
Submitter Jason Merrill
Date May 27, 2011, 7:28 p.m.
Message ID <4DDFFB63.8000006@redhat.com>
Download mbox | patch
Permalink /patch/97742/
State New
Headers show

Comments

Jason Merrill - May 27, 2011, 7:28 p.m.
Here, the problem was that when we went to generate the 
partially-instantiated function type in the mangler, we weren't in the 
proper scope so lookup of an identifier failed.  Fixed by doing 
push_access_scope like we do in other situations.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit 5d930ac29cdc6d91f6e5325b4946bb784cfdb6f4
Author: Jason Merrill <jason@redhat.com>
Date:   Fri May 27 10:45:51 2011 -0400

    	PR c++/49181
    	* pt.c (get_mostly_instantiated_function_type): Use push_access_scope.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 767c4f6..71fe0a0 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -18080,9 +18080,9 @@  get_mostly_instantiated_function_type (tree decl)
 			   TMPL_ARGS_DEPTH (targs),
 			   make_tree_vec (DECL_NTPARMS (tmpl)));
 
-      /* Disable access control as this function is used only during
-	 name-mangling.  */
-      push_deferring_access_checks (dk_no_check);
+      /* Make sure that we can see identifiers, and compute access
+	 correctly.  */
+      push_access_scope (decl);
 
       ++processing_template_decl;
       /* Now, do the (partial) substitution to figure out the
@@ -18097,7 +18097,7 @@  get_mostly_instantiated_function_type (tree decl)
       TREE_VEC_LENGTH (partial_args)--;
       tparms = tsubst_template_parms (tparms, partial_args, tf_error);
 
-      pop_deferring_access_checks ();
+      pop_access_scope (decl);
     }
 
   return fn_type;
diff --git a/gcc/testsuite/g++.dg/cpp0x/error5.C b/gcc/testsuite/g++.dg/cpp0x/error5.C
new file mode 100644
index 0000000..1931926
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/error5.C
@@ -0,0 +1,107 @@ 
+// PR c++/49181
+// { dg-options -std=c++0x }
+
+namespace std
+{
+  typedef __SIZE_TYPE__ size_t;
+
+  template<typename _Tp, _Tp>
+    struct integral_constant;
+
+  template<typename _Tp, _Tp __v>
+    struct integral_constant
+    {
+      static constexpr _Tp value = __v;
+      typedef _Tp value_type;
+      typedef integral_constant<_Tp, __v> type;
+      constexpr operator value_type() { return value; }
+    };
+
+  typedef integral_constant<bool, true> true_type;
+
+  typedef integral_constant<bool, false> false_type;
+
+  template<typename _Tp, _Tp __v>
+    constexpr _Tp integral_constant<_Tp, __v>::value;
+
+  template<bool, typename _Tp = void>
+    struct enable_if
+    { };
+
+  template<typename _Tp>
+    struct enable_if<true, _Tp>
+    { typedef _Tp type; };
+
+  template<typename _Tp>
+    inline _Tp
+    declval();
+
+struct bad_alloc { };
+}
+
+void* operator new(std::size_t) throw (std::bad_alloc);
+
+namespace std
+{
+
+  template<typename _Tp>
+    class allocator
+    {
+    public:
+      typedef _Tp* pointer;
+      typedef _Tp value_type;
+
+      pointer
+      allocate(size_t, const void* = 0);
+    };
+
+  template<typename _Alloc>
+    struct allocator_traits
+    {
+      typedef typename _Alloc::value_type value_type;
+
+      template<typename _Tp> static typename _Tp::pointer
+_S_pointer_helper(_Tp*);
+      static value_type* _S_pointer_helper(...);
+      typedef decltype(_S_pointer_helper((_Alloc*)0)) __pointer;
+
+      typedef __pointer pointer;
+
+      typedef const void* const_void_pointer;
+
+      private:
+      template<typename _Alloc2>
+    struct __allocate_helper
+    {
+      template<typename _Alloc3,
+        typename = decltype(std::declval<_Alloc3*>()->allocate(
+          std::declval<size_t>(),
+          std::declval<const_void_pointer>()))>
+          static true_type __test(int);
+
+      template<typename>
+        static false_type __test(...);
+
+      typedef decltype(__test<_Alloc>(0)) type;
+      static const bool value = type::value;
+    };
+
+      template<typename _Alloc2>
+    static typename
+    enable_if<__allocate_helper<_Alloc2>::value, pointer>::type
+    _S_allocate(_Alloc2& __a, size_t __n, const_void_pointer __hint)
+    { return __a.allocate(__n, __hint); }
+
+      public:
+      static pointer
+    allocate(_Alloc& __a, size_t __n, const_void_pointer __hint)
+    { return _S_allocate(__a, __n, __hint); }
+    };
+
+}
+
+namespace std
+{
+  typedef short test_type;
+  template struct allocator_traits<allocator<test_type>>;
+}