[C++] PR/77812 struct stat hack fix

Message ID 161a292f-926f-c7a2-1906-5babafa8d0a2@acm.org
State New
Headers show

Commit Message

Nathan Sidwell Jan. 11, 2017, 8:39 p.m.
issue 77812 turned out to be a srtuct stat hack problem, the bisected 
commit a red herring (that just made it noisy for the enum case).

We wrap using decls and template functions in a singleton overload, and 
this can confuse set_namespace_binding into thinking we're augmenting an 
existing OVERLOAD binding.  We need to check for this case and use 
supplement_binding in that case, just as if it was a non-overload.

Applied to trunk (and will backport to 5 & 6)

nathan
-- 
Nathan Sidwell

Patch hide | download patch | download mbox

2017-01-11  Nathan Sidwell  <nathan@acm.org>

	cp/
	PR c++/77812
	* name-lookup.c (set_namespace_binding_1): An overload of 1 decl
	is a new overload.

	testsuite/
	PR c++/77812
	* g++.dg/pr77812.C: New.

Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c	(revision 244334)
+++ cp/name-lookup.c	(working copy)
@@ -3496,7 +3496,12 @@  set_namespace_binding_1 (tree name, tree
   if (scope == NULL_TREE)
     scope = global_namespace;
   b = binding_for_name (NAMESPACE_LEVEL (scope), name);
-  if (!b->value || TREE_CODE (val) == OVERLOAD || val == error_mark_node)
+  if (!b->value
+      /* For templates and using we create a single element OVERLOAD.
+	 Look for the chain to know whether this is really augmenting
+	 an existing overload.  */
+      || (TREE_CODE (val) == OVERLOAD && OVL_CHAIN (val))
+      || val == error_mark_node)
     b->value = val;
   else
     supplement_binding (b, val);
Index: testsuite/g++.dg/pr77812.C
===================================================================
--- testsuite/g++.dg/pr77812.C	(revision 0)
+++ testsuite/g++.dg/pr77812.C	(working copy)
@@ -0,0 +1,18 @@ 
+// PR77812
+// struct-stat hack failure when first overload is a template
+
+enum f {};
+
+template <typename>
+void f ()
+{
+}
+enum f F;
+
+struct g {};
+
+template <typename>
+void g ()
+{
+}
+struct g G;