Patchwork C++ PATCH for c++/50075 (ICE on recursive late-specified return type)

login
register
mail settings
Submitter Jason Merrill
Date Aug. 14, 2011, 5:08 a.m.
Message ID <4E475869.1080309@redhat.com>
Download mbox | patch
Permalink /patch/109956/
State New
Headers show

Comments

Jason Merrill - Aug. 14, 2011, 5:08 a.m.
We were assuming that if current_function_decl is set, then we are at a 
local binding level.  But that isn't the case with a late-specified 
return type, so we need to check something else instead.  Since what we 
are interested in the binding level, let's check that directly.

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

Patch

commit c81176e5a49c52dfba88206b3c73aa38ee287db1
Author: Jason Merrill <jason@redhat.com>
Date:   Sat Aug 13 17:58:45 2011 -0400

    	PR c++/50075
    	* name-lookup.c (local_bindings_p): New.
    	* name-lookup.h: Declare it.
    	* lex.c (unqualified_name_lookup_error): Use it.

diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 691a2ec..c11e3b3 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -456,7 +456,7 @@  unqualified_name_lookup_error (tree name)
 	}
       /* Prevent repeated error messages by creating a VAR_DECL with
 	 this NAME in the innermost block scope.  */
-      if (current_function_decl)
+      if (local_bindings_p ())
 	{
 	  tree decl;
 	  decl = build_decl (input_location,
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 1afd9ed..64456b4 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -1608,6 +1608,15 @@  namespace_bindings_p (void)
   return b->kind == sk_namespace;
 }
 
+/* True if the innermost non-class scope is a block scope.  */
+
+bool
+local_bindings_p (void)
+{
+  cp_binding_level *b = innermost_nonclass_level ();
+  return b->kind < sk_function_parms || b->kind == sk_omp;
+}
+
 /* True if the current level needs to have a BLOCK made.  */
 
 bool
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 5974dce..a37afdb 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -292,6 +292,7 @@  extern bool kept_level_p (void);
 extern bool global_bindings_p (void);
 extern bool toplevel_bindings_p	(void);
 extern bool namespace_bindings_p (void);
+extern bool local_bindings_p (void);
 extern bool template_parm_scope_p (void);
 extern scope_kind innermost_scope_kind (void);
 extern cp_binding_level *begin_scope (scope_kind, tree);
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype32.C b/gcc/testsuite/g++.dg/cpp0x/decltype32.C
new file mode 100644
index 0000000..66731cc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype32.C
@@ -0,0 +1,12 @@ 
+// PR c++/50075
+// { dg-options -std=c++0x }
+
+template <typename T>
+auto make_array(const T& il) ->	// { dg-error "not declared" }
+decltype(make_array(il))
+{ }
+
+int main()
+{
+  int z = make_array(1);	// { dg-error "no match" }
+}