re PR c++/77549 (ICE on invalid C++ code that references undeclared variable)
authorJakub Jelinek <jakub@redhat.com>
Wed, 14 Sep 2016 21:55:10 +0000 (23:55 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 14 Sep 2016 21:55:10 +0000 (23:55 +0200)
PR c++/77549
* name-lookup.c (consider_binding_level): Look through TREE_LIST
and OVERLOAD.

* g++.dg/lookup/pr77549.C: New test.

From-SVN: r240148

gcc/cp/ChangeLog
gcc/cp/name-lookup.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/pr77549.C [new file with mode: 0644]

index 001479c8b5e45fa6f62519b4e0c39f4d25a6722c..26d730eb62689a92518b2f91fca054629b3221e5 100644 (file)
@@ -1,3 +1,9 @@
+2016-09-14  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/77549
+       * name-lookup.c (consider_binding_level): Look through TREE_LIST
+       and OVERLOAD.
+
 2016-09-14  Marek Polacek  <polacek@redhat.com>
 
        * typeck.c (cp_build_unary_op): Diagnose incrementing boolean
index 022ab6a2c09007e119fb936b3683577216631620..952d8b799ab93766ded5bc98d27866fd71aa4729 100644 (file)
@@ -4707,19 +4707,29 @@ consider_binding_level (tree name, best_match <tree, tree> &bm,
 
   for (tree t = lvl->names; t; t = TREE_CHAIN (t))
     {
+      tree d = t;
+
+      /* OVERLOADs or decls from using declaration are wrapped into
+        TREE_LIST.  */
+      if (TREE_CODE (d) == TREE_LIST)
+       {
+         d = TREE_VALUE (d);
+         d = OVL_CURRENT (d);
+       }
+
       /* Don't use bindings from implicitly declared functions,
         as they were likely misspellings themselves.  */
-      if (TREE_TYPE (t) == error_mark_node)
+      if (TREE_TYPE (d) == error_mark_node)
        continue;
 
       /* Skip anticipated decls of builtin functions.  */
-      if (TREE_CODE (t) == FUNCTION_DECL
-         && DECL_BUILT_IN (t)
-         && DECL_ANTICIPATED (t))
+      if (TREE_CODE (d) == FUNCTION_DECL
+         && DECL_BUILT_IN (d)
+         && DECL_ANTICIPATED (d))
        continue;
 
-      if (DECL_NAME (t))
-       bm.consider (DECL_NAME (t));
+      if (DECL_NAME (d))
+       bm.consider (DECL_NAME (d));
     }
 }
 
index dc55a3d8cd2121304590070655072133841c89f9..023fcd484fd96034392b38b4b6491111c0b339a1 100644 (file)
@@ -1,3 +1,8 @@
+2016-09-14  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/77549
+       * g++.dg/lookup/pr77549.C: New test.
+
 2016-09-14  Marek Polacek  <polacek@redhat.com>
 
        * c-c++-common/gomp/atomic-12.c: Use -Wno-deprecated.
diff --git a/gcc/testsuite/g++.dg/lookup/pr77549.C b/gcc/testsuite/g++.dg/lookup/pr77549.C
new file mode 100644 (file)
index 0000000..6fe1a0e
--- /dev/null
@@ -0,0 +1,76 @@
+// PR c++/77549
+// { dg-do compile }
+
+struct A
+{ 
+  static int x;
+};
+
+void
+f1 ()
+{ 
+  using ::A;
+  x;                   // { dg-error "'x' was not declared in this scope" }
+}
+
+namespace N
+{
+  int bar;
+}
+
+void
+f2 ()
+{
+  using N::bar;
+  baz++;               // { dg-error "'baz' was not declared in this scope" }
+}                      // { dg-message "note: suggested alternative: 'bar'" "" { target *-*-* } 25 }
+
+int
+bar ()
+{
+  return 0;
+}
+
+namespace M
+{
+  int
+  bar ()
+  {
+    return 0;
+  }
+}
+
+void
+f3 ()
+{
+  using M::bar;
+  baz ();              // { dg-error "'baz' was not declared in this scope" }
+}                      // { dg-message "note: suggested alternative: 'bar'" "" { target *-*-* } 47 }
+
+namespace O
+{
+  int
+  foo ()
+  {
+    return 0;
+  }
+}
+
+namespace P
+{
+  int
+  bar ()
+  {
+    return 0;
+  }
+}
+
+void
+f4 ()
+{
+  using O::foo;
+  using P::bar;
+  fooo ();             // { dg-error "'fooo' was not declared in this scope" }
+                       // { dg-message "note: suggested alternative: 'foo'" "" { target *-*-* } 73 }
+  baz ();              // { dg-error "'baz' was not declared in this scope" }
+}                      // { dg-message "note: suggested alternative: 'bar'" "" { target *-*-* } 75 }