diff mbox

C++ PATCH for c++/17729, c++/50308, deprecated warning issues

Message ID CADzB+2nE2WLn=SP1ELhMeD0QaLh3iaskiCh-PsBH6PCO1UmCSg@mail.gmail.com
State New
Headers show

Commit Message

Jason Merrill Feb. 21, 2017, 8:48 p.m. UTC
Both of these PRs are problems with the attribute deprecated warning
in cases when there are no other declarations of the name in scope.
[basic.def.odr] says that a function is odr-used if it is the unique
result of name lookup, and also if it is selected by overload
resolution; in 17729 that results in a duplicate warning, and in 50308
in a bogus warning because a different function is chosen by
arg-dependent lookup.

The solution for these is to avoid calling mark_used on the lookup
when we know we're building a call.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit b823b69a6cec77c5e96d0383b919a8da14b13a72
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Feb 21 09:45:19 2017 -0800

            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.
diff mbox

Patch

diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 6a47476..6ba7c13 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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;
 
diff --git a/gcc/testsuite/c-c++-common/pr69558.c b/gcc/testsuite/c-c++-common/pr69558.c
index 102d72c..4c6d498 100644
--- a/gcc/testsuite/c-c++-common/pr69558.c
+++ b/gcc/testsuite/c-c++-common/pr69558.c
@@ -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
index 0000000..df5c76f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/deprecated-12.C
@@ -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" }
+}