Bug 64079 - %+D in diagnostics breaks pragma GCC diagnostic
Summary: %+D in diagnostics breaks pragma GCC diagnostic
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.9.2
: P3 normal
Target Milestone: 6.0
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic, easyhack
Depends on:
Blocks:
 
Reported: 2014-11-26 06:38 UTC by Danil Ilinykh
Modified: 2015-07-25 06:38 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2015-07-23 00:00:00


Attachments
preprocessed file (182 bytes, text/plain)
2014-11-26 06:38 UTC, Danil Ilinykh
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Danil Ilinykh 2014-11-26 06:38:18 UTC
Created attachment 34121 [details]
preprocessed file

Regression from 4.8.x

Warning "-Wunused-function" is generated even if 
#pragma GCC diagnostic ignored "-Wunused-function"
is defined in place where function is declared/defined.

If there is no "pragma GCC diagnostic push/pop", no warning is generated, even if "pragma GCC diagnostic ignored" is located at the end of a compilation unit.

*Command line*: g++ -Wall bug.cpp

*Compiler output*:
bug.cpp:11:13: warning: ‘void bar()’ defined but not used [-Wunused-function]
 static void bar() {}
             ^
bug.cpp:7:6: warning: ‘void {anonymous}::foo()’ defined but not used [-Wunused-function]
 void foo() {}
      ^

*Version*:
g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.9.2-0ubuntu1~14.04' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.9.2 (Ubuntu 4.9.2-0ubuntu1~14.04)
Comment 1 Manuel López-Ibáñez 2014-11-26 13:10:07 UTC
I think this is because this warning uses:

    warning ((TREE_CODE (decl) == FUNCTION_DECL)
	     ? OPT_Wunused_function
             : OPT_Wunused_variable,
	     "%q+D defined but not used", decl);

instead of:

    warning_at (DECL_SOURCE_LOCATION (decl),
                (TREE_CODE (decl) == FUNCTION_DECL)
	     ? OPT_Wunused_function
             : OPT_Wunused_variable,
	     "%qD defined but not used", decl);

and the pragma location check is done before processing the format string, so the location is not set correctly. As I said several times, "+D" is not only cryptic, it is also buggy because it is handled too late and too deep in the diagnostics machinery to modify the location of the diagnostic ('+' would be more intuitive as 'extra verbose' output).

Every diagnostic using +D is broken in this respect.

On the other hand, I do not understand how it was working in GCC 4.8.
Comment 2 Manuel López-Ibáñez 2015-07-23 13:14:59 UTC
Another example of this: https://gcc.gnu.org/ml/gcc-help/2015-07/msg00070.html
Comment 3 Manuel López-Ibáñez 2015-07-23 13:18:21 UTC
Trivial patch, but the issue remains that any use of '+' is potentially a bug.

Index: toplev.c
===================================================================
--- toplev.c    (revision 225868)
+++ toplev.c    (working copy)
@@ -522,14 +522,15 @@ check_global_declaration (tree decl)
       && (TREE_CODE (decl) != FUNCTION_DECL
          || (!DECL_STATIC_CONSTRUCTOR (decl)
              && !DECL_STATIC_DESTRUCTOR (decl)))
       /* Otherwise, ask the language.  */
       && lang_hooks.decls.warn_unused_global (decl))
-    warning ((TREE_CODE (decl) == FUNCTION_DECL)
-            ? OPT_Wunused_function
-             : OPT_Wunused_variable,
-            "%q+D defined but not used", decl);
+    warning_at (DECL_SOURCE_LOCATION (decl),
+               (TREE_CODE (decl) == FUNCTION_DECL)
+               ? OPT_Wunused_function
+               : OPT_Wunused_variable,
+               "%qD defined but not used", decl);
 }
 
 /* Compile an entire translation unit.  Write a file of assembly
    output and various debugging dumps.  */
Comment 4 Manuel López-Ibáñez 2015-07-23 13:31:09 UTC
BTW, changes like the above are trivial to implement and test, thus this is a nice easy-hack for beginners.
Comment 5 Paolo Carlini 2015-07-23 19:07:07 UTC
Thanks Manu. I'm going to take care of this specific issue. I will also ask if patches proactively replacing those +D and +#D in the C++ front-end are welcome at this time.
Comment 6 Jason Merrill 2015-07-23 20:25:08 UTC
(In reply to Paolo Carlini from comment #5)
> Thanks Manu. I'm going to take care of this specific issue. I will also ask
> if patches proactively replacing those +D and +#D in the C++ front-end are
> welcome at this time.

Such changes are pre-approved.
Comment 7 Paolo Carlini 2015-07-24 09:06:23 UTC
Thanks Jason.

Note that '+' eventually boils down to location_of, which does quite a bit more than DECL_SOURCE_LOCATION. Thus either we should be very, very careful in this work or in some cases use location_of to be safe, at least ad interim.
Comment 8 Manuel López-Ibáñez 2015-07-24 12:46:21 UTC
(In reply to Paolo Carlini from comment #7)
> Thanks Jason.
> 
> Note that '+' eventually boils down to location_of, which does quite a bit
> more than DECL_SOURCE_LOCATION. Thus either we should be very, very careful
> in this work or in some cases use location_of to be safe, at least ad
> interim.

Indeed. And there are other cases that pass an explicit location and use '+', thus simply removing '+' may regress the location info:

      error_at (type_start_token->location, "redefinition of %q#T",
		type);
      error_at (type_start_token->location, "previous definition of %q+#T",
		type);
Comment 9 Paolo Carlini 2015-07-24 13:05:44 UTC
Agreed. For now I mean to do a first pass on the warnings, no errors, seems more urgent given the issue involving the pragmas.
Comment 10 paolo@gcc.gnu.org 2015-07-24 20:20:45 UTC
Author: paolo
Date: Fri Jul 24 20:20:13 2015
New Revision: 226191

URL: https://gcc.gnu.org/viewcvs?rev=226191&root=gcc&view=rev
Log:
2015-07-24  Manuel López-Ibáñez  <manu@gcc.gnu.org>

	PR c++/64079
	* toplev.c (check_global_declaration): Use DECL_SOURCE_LOCATION
	and "%qD" in warning_at instead of "%q+D" in warning.

/testsuite
2015-07-24  Manuel López-Ibáñez  <manu@gcc.gnu.org>

	PR c++/64079
	* c-c++-common/Wunused-function-1.c: New.

Added:
    trunk/gcc/testsuite/c-c++-common/Wunused-function-1.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/toplev.c
Comment 11 Paolo Carlini 2015-07-24 20:21:16 UTC
Fixed.
Comment 12 Manuel López-Ibáñez 2015-07-24 22:57:03 UTC
(In reply to Paolo Carlini from comment #11)
> Fixed.

Should we have a meta-bug for all uses of %+ that can potentially cause problems or should we leave open this one as a catch all case? Removing even one case would be an easy entry-level patch for new contributors, this is why I marked it as a easy-hack.

I have also updated https://gcc.gnu.org/wiki/DiagnosticsGuidelines following Jason's comments.
Comment 13 Danil Ilinykh 2015-07-25 06:38:50 UTC
Thanks!