PR c++/50308 - wrong deprecated warning with ADL
authorJason Merrill <jason@redhat.com>
Tue, 21 Feb 2017 20:51:03 +0000 (15:51 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 21 Feb 2017 20:51:03 +0000 (15:51 -0500)
PR c++/17729 - duplicate deprecated warning
* semantics.c (finish_id_expression): Only call mark_used on a
function if we aren't building a call.

From-SVN: r245643

gcc/cp/ChangeLog
gcc/cp/semantics.c
gcc/testsuite/c-c++-common/pr69558.c
gcc/testsuite/g++.dg/warn/deprecated-12.C [new file with mode: 0644]

index 13d7d33..42c6a52 100644 (file)
@@ -1,5 +1,10 @@
 2017-02-21  Jason Merrill  <jason@redhat.com>
 
+       PR c++/50308 - wrong deprecated warning with ADL
+       PR c++/17729 - duplicate deprecated warning
+       * semantics.c (finish_id_expression): Only call mark_used on a
+       function if we aren't building a call.
+
        PR c++/41727 - ICE with partial spec of partial instantiation
        * pt.c (process_partial_specialization): For now, don't check more
        specialized if there is more than one level of args.
index 6a47476..6ba7c13 100644 (file)
@@ -3743,7 +3743,15 @@ finish_id_expression (tree id_expression,
          if (TREE_CODE (first_fn) == TEMPLATE_DECL)
            first_fn = DECL_TEMPLATE_RESULT (first_fn);
 
-         if (!really_overloaded_fn (decl)
+         /* [basic.def.odr]: "A function whose name appears as a
+            potentially-evaluated expression is odr-used if it is the unique
+            lookup result".
+
+            But only mark it if it's a complete postfix-expression; in a call,
+            ADL might select a different function, and we'll call mark_used in
+            build_over_call.  */
+         if (done
+             && !really_overloaded_fn (decl)
              && !mark_used (first_fn))
            return error_mark_node;
 
index 102d72c..4c6d498 100644 (file)
@@ -16,4 +16,4 @@
 
 __attribute__((deprecated)) void foo (void); /* { dg-bogus "declared here" "" { xfail { c++ } } } */
 
-C (foo) /* { dg-bogus "is deprecated"  "" { xfail { c++ } } } */
+C (foo) /* { dg-bogus "is deprecated" } */
diff --git a/gcc/testsuite/g++.dg/warn/deprecated-12.C b/gcc/testsuite/g++.dg/warn/deprecated-12.C
new file mode 100644 (file)
index 0000000..df5c76f
--- /dev/null
@@ -0,0 +1,20 @@
+// PR c++/50308
+
+void A( int ) __attribute__((deprecated));
+
+namespace B {
+
+  struct C {};
+
+  void A(C) {}
+
+}
+
+int main ()
+{
+  B::C x;
+
+  // ADL correctly identifies the non-deprecated B::A, but a warning about the
+  // global A is generated anyway
+  A( x );                      // { dg-bogus "deprecated" }
+}