[v3,5/9] compile: Use -Wall, not -w

Message ID 20150411194403.29128.80053.stgit@host1.jankratochvil.net
State New, archived
Headers

Commit Message

Jan Kratochvil April 11, 2015, 7:44 p.m. UTC
  Hi,

for a reason unknown to me GDB was using -w instead of -Wall for 'compile code'.
The problem is later patch for 'compile printf' really needs some warnings to
be able to catch for example missing format string parameters:
	(gdb) compile printf "%d\n"
GCC does not seem to be able to cancel -w (there is nothing like -no-w).

Besides that I think even 'compile code' can benefit from -Wall.

That #ifndef hack in print_one_macro() is not nice but while GCC does not warn
for redefinitions like
	#define MACRO val
	#define MACRO val
together with the GCC build-in macros I haven't found any other way how to
prevent the macro-redefinition warnings (when -w is no longer in effect).

That new testsuite XFAIL is there as if one changes the struct definition to be
compliant with cv-qualifiers (to prevent the warnings):
struct struct_type {
-  struct struct_type *selffield;
+  volatile struct struct_type *selffield;
only then GCC/GDB will hit the crash, described in that GDB PR 18202.


Thanks,
Jan


gdb/ChangeLog
2015-04-05  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* compile/compile-c-support.c (print_one_macro): Use #ifndef.
	(generate_register_struct): Use __gdb_uintptr for TYPE_CODE_PTR.
	(c_compute_program): Call generate_register_struct after typedefs.
	* compile/compile-loc2c.c (push, pushf_register_address)
	(pushf_register): Cast to GCC_UINTPTR.
	(do_compile_dwarf_expr_to_c): Use unused attribute.  Add space after
	type.  Use GCC_UINTPTR instead of void *.  Remove excessive cast.
	(compile_dwarf_expr_to_c): Use GCC_UINTPTR instead of void *.
	* compile/compile.c (_initialize_compile): Enable warnings for
	COMPILE_ARGS.

gdb/testsuite/ChangeLog
2015-04-05  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.compile/compile-ops.exp: Cast param to void.
	* gdb.compile/compile.exp: Complete type for _gdb_expr.
	(compile code struct_object.selffield = &struct_object): Add xfail.
---
 0 files changed
  

Comments

Pedro Alves April 29, 2015, 3:47 p.m. UTC | #1
On 04/11/2015 08:44 PM, Jan Kratochvil wrote:
> Hi,
> 
> for a reason unknown to me GDB was using -w instead of -Wall for 'compile code'.
> The problem is later patch for 'compile printf' really needs some warnings to
> be able to catch for example missing format string parameters:
> 	(gdb) compile printf "%d\n"
> GCC does not seem to be able to cancel -w (there is nothing like -no-w).
> 
> Besides that I think even 'compile code' can benefit from -Wall.
> 
> That #ifndef hack in print_one_macro() is not nice but while GCC does not warn
> for redefinitions like
> 	#define MACRO val
> 	#define MACRO val
> together with the GCC build-in macros I haven't found any other way how to
> prevent the macro-redefinition warnings (when -w is no longer in effect).

I think GCC also knows how to suppress such warnings if the redefinitions
are in system includes.  So I guess GCC already has the smarts
to suppress those. '#pragma GCC system_header' might be close, though it may
be ignored if not done on a header.

Note we have #pragma GCC user_expression, which is a pragma handled by
the GCC plugin:

 static void
 plugin_init_extra_pragmas (void *, void *)
 {
   c_register_pragma ("GCC", "user_expression", plugin_pragma_user_expression);
 }

So if we need to, we can easily add another gdb-specific pragma that
enables whatever mode in gcc we need, and wrap the macros with that.

OTOH, if it's the inferior's version of the macro that is always wanted,
then #ifndef should be fine.  If it's gdb's version that is wanted though,
then that could be handled by an #undef before the #define.

But then again, I'm not exactly sure on what you mean by build-in
macros here.  Can you give an example?

>  
> -gdb_test_no_output "compile code struct_object.selffield = &struct_object"
> +set test "compile code struct_object.selffield = &struct_object"
> +gdb_test_multiple $test $test {
> +    -re "gdb command line:1:25: warning: assignment discards 'volatile' qualifier from pointer target type \\\[-Wdiscarded-qualifiers\\\]\r\n$gdb_prompt $" {
> +	xfail "$test (PR compile/18202)"
> +    }
> +}

Please leave a PASS path in place.  I think this would work:

gdb_test_multiple $test $test {
    -re "^$test\r\n$gdb_prompt $ $" {
	pass "$test"
    }
    -re "gdb command line:1:25: warning: assignment discards 'volatile' qualifier from pointer target type \\\[-Wdiscarded-qualifiers\\\]\r\n$gdb_prompt $" {
	xfail "$test (PR compile/18202)"
    }
}

Other than resolving/clarifying the #ifdef issue, this looks
good to me.

Thanks,
Pedro Alves
  
Jan Kratochvil May 3, 2015, 2:05 p.m. UTC | #2
On Wed, 29 Apr 2015 17:47:08 +0200, Pedro Alves wrote:
> On 04/11/2015 08:44 PM, Jan Kratochvil wrote:
> I think GCC also knows how to suppress such warnings if the redefinitions
> are in system includes.  So I guess GCC already has the smarts
> to suppress those. '#pragma GCC system_header' might be close, though it may
> be ignored if not done on a header.

Another problem is that (currently) it would not be possible to turn it off in
the same file.  Therefore the user expression without not get any warnings
which would nullify the goal of this patch.


> OTOH, if it's the inferior's version of the macro that is always wanted,
> then #ifndef should be fine.  If it's gdb's version that is wanted though,
> then that could be handled by an #undef before the #define.

Only some GCC's internal macros are affected and I guess it is better to leave
them alone, therefore #ifndef is better (contrary to forced re-#define).


> But then again, I'm not exactly sure on what you mean by build-in
> macros here.  Can you give an example?

Without that #ifndef/#endif one gets:
	compile -r -- void _gdb_expr(){int i = 5;}^M
	/tmp/gdbobj-xpU1yB/out4.c:4:0: warning: "__FILE__" redefined [-Wbuiltin-macro-redefined]^M
	/tmp/gdbobj-xpU1yB/out4.c:5:0: warning: "__LINE__" redefined^M
	/tmp/gdbobj-xpU1yB/out4.c:6:0: warning: "__STDC_IEC_559_COMPLEX__" redefined^M
	In file included from <command-line>:0:0:^M
	/usr/include/stdc-predef.h:46:0: note: this is the location of the previous definition^M
	/tmp/gdbobj-xpU1yB/out4.c:7:0: warning: "__STDC_IEC_559__" redefined^M
	In file included from <command-line>:0:0:^M
	/usr/include/stdc-predef.h:38:0: note: this is the location of the previous definition^M
	/tmp/gdbobj-xpU1yB/out4.c:8:0: warning: "__STDC_ISO_10646__" redefined^M
	In file included from <command-line>:0:0:^M
	/usr/include/stdc-predef.h:54:0: note: this is the location of the previous definition^M
	/tmp/gdbobj-xpU1yB/out4.c:9:0: warning: "__STDC_NO_THREADS__" redefined^M
	In file included from <command-line>:0:0:^M
	/usr/include/stdc-predef.h:57:0: note: this is the location of the previous definition^M
	(gdb) FAIL: gdb.compile/compile.exp: Test delimiter with -r

Without that #ifndef/#endif and with -Wno-builtin-macro-redefined one
expectedly gets mostly the same:
	compile -r -- void _gdb_expr(){int i = 5;}^M
	/tmp/gdbobj-sJlZmG/out4.c:5:0: warning: "__LINE__" redefined^M
	/tmp/gdbobj-sJlZmG/out4.c:6:0: warning: "__STDC_IEC_559_COMPLEX__" redefined^M
	In file included from <command-line>:0:0:^M
	/usr/include/stdc-predef.h:46:0: note: this is the location of the previous definition^M
	/tmp/gdbobj-sJlZmG/out4.c:7:0: warning: "__STDC_IEC_559__" redefined^M
	In file included from <command-line>:0:0:^M
	/usr/include/stdc-predef.h:38:0: note: this is the location of the previous definition^M
	/tmp/gdbobj-sJlZmG/out4.c:8:0: warning: "__STDC_ISO_10646__" redefined^M
	In file included from <command-line>:0:0:^M
	/usr/include/stdc-predef.h:54:0: note: this is the location of the previous definition^M
	/tmp/gdbobj-sJlZmG/out4.c:9:0: warning: "__STDC_NO_THREADS__" redefined^M
	In file included from <command-line>:0:0:^M
	/usr/include/stdc-predef.h:57:0: note: this is the location of the previous definition^M
	(gdb) FAIL: gdb.compile/compile.exp: Test delimiter with -r

Using #undef before the #define one gets:
	compile -r -- void _gdb_expr(){int i = 5;}^M
	/tmp/gdbobj-vCA0XG/out4.c:7:0: warning: undefining "__FILE__" [-Wbuiltin-macro-redefined]^M
	/tmp/gdbobj-vCA0XG/out4.c:9:8: warning: undefining "__LINE__"^M
	/tmp/gdbobj-vCA0XG/out4.c:11:8: warning: undefining "__STDC_IEC_559_COMPLEX__"^M
	/tmp/gdbobj-vCA0XG/out4.c:13:8: warning: undefining "__STDC_IEC_559__"^M
	/tmp/gdbobj-vCA0XG/out4.c:15:8: warning: undefining "__STDC_ISO_10646__"^M
	/tmp/gdbobj-vCA0XG/out4.c:17:8: warning: undefining "__STDC_NO_THREADS__"^M
	(gdb) FAIL: gdb.compile/compile.exp: Test delimiter with -r

In the end the #ifndef+#define is not such a problem I think.


> Please leave a PASS path in place.  I think this would work:

Yes, almost:
> 
> gdb_test_multiple $test $test {
>     -re "^$test\r\n$gdb_prompt $ $" {
      -re "^$test\r\n$gdb_prompt $" {
> 	pass "$test"
>     }


Thanks,
Jan
  
Pedro Alves May 6, 2015, 10:21 a.m. UTC | #3
On 05/03/2015 03:05 PM, Jan Kratochvil wrote:

> In the end the #ifndef+#define is not such a problem I think.

OK, let's keep that route then.

>> Please leave a PASS path in place.  I think this would work:
> 
> Yes, almost:
>>
>> gdb_test_multiple $test $test {
>>     -re "^$test\r\n$gdb_prompt $ $" {
>       -re "^$test\r\n$gdb_prompt $" {
>> 	pass "$test"
>>     }

Yeah, that double $ was a typo.

Thanks,
Pedro Alves
  

Patch

diff --git a/gdb/compile/compile-c-support.c b/gdb/compile/compile-c-support.c
index 1711cda..48a17e2 100644
--- a/gdb/compile/compile-c-support.c
+++ b/gdb/compile/compile-c-support.c
@@ -131,7 +131,9 @@  print_one_macro (const char *name, const struct macro_definition *macro,
   if (line == 0)
     return;
 
-  fprintf_filtered (file, "#define %s", name);
+  /* None of -Wno-builtin-macro-redefined, #undef first
+     or plain #define of the same value would avoid a warning.  */
+  fprintf_filtered (file, "#ifndef %s\n# define %s", name, name);
 
   if (macro->kind == macro_function_like)
     {
@@ -147,7 +149,7 @@  print_one_macro (const char *name, const struct macro_definition *macro,
       fputs_filtered (")", file);
     }
 
-  fprintf_filtered (file, " %s\n", macro->replacement);
+  fprintf_filtered (file, " %s\n#endif\n", macro->replacement);
 }
 
 /* Write macro definitions at PC to FILE.  */
@@ -252,7 +254,7 @@  generate_register_struct (struct ui_file *stream, struct gdbarch *gdbarch,
 	    switch (TYPE_CODE (regtype))
 	      {
 	      case TYPE_CODE_PTR:
-		fprintf_filtered (stream, "void *%s", regname);
+		fprintf_filtered (stream, "__gdb_uintptr %s", regname);
 		break;
 
 	      case TYPE_CODE_INT:
@@ -340,8 +342,6 @@  c_compute_program (struct compile_instance *inst,
 							  expr_block, expr_pc);
       make_cleanup (xfree, registers_used);
 
-      generate_register_struct (buf, gdbarch, registers_used);
-
       fputs_unfiltered ("typedef unsigned int"
 			" __attribute__ ((__mode__(__pointer__)))"
 			" __gdb_uintptr;\n",
@@ -363,6 +363,8 @@  c_compute_program (struct compile_instance *inst,
 			      " __gdb_int_%s;\n",
 			      mode, mode);
 	}
+
+      generate_register_struct (buf, gdbarch, registers_used);
     }
 
   add_code_header (inst->scope, buf);
diff --git a/gdb/compile/compile-loc2c.c b/gdb/compile/compile-loc2c.c
index 6a3615d..6f53814 100644
--- a/gdb/compile/compile-loc2c.c
+++ b/gdb/compile/compile-loc2c.c
@@ -436,7 +436,8 @@  compute_stack_depth (enum bfd_endian byte_order, unsigned int addr_size,
 static void
 push (int indent, struct ui_file *stream, ULONGEST l)
 {
-  fprintfi_filtered (indent, stream, "__gdb_stack[++__gdb_tos] = %s;\n",
+  fprintfi_filtered (indent, stream,
+		     "__gdb_stack[++__gdb_tos] = (" GCC_UINTPTR ") %s;\n",
 		     hex_string (l));
 }
 
@@ -520,7 +521,8 @@  pushf_register_address (int indent, struct ui_file *stream,
   struct cleanup *cleanups = make_cleanup (xfree, regname);
 
   registers_used[regnum] = 1;
-  pushf (indent, stream, "&" COMPILE_I_SIMPLE_REGISTER_ARG_NAME	 "->%s",
+  pushf (indent, stream,
+	 "(" GCC_UINTPTR ") &" COMPILE_I_SIMPLE_REGISTER_ARG_NAME "->%s",
 	 regname);
 
   do_cleanups (cleanups);
@@ -544,7 +546,8 @@  pushf_register (int indent, struct ui_file *stream,
     pushf (indent, stream, COMPILE_I_SIMPLE_REGISTER_ARG_NAME "->%s",
 	   regname);
   else
-    pushf (indent, stream, COMPILE_I_SIMPLE_REGISTER_ARG_NAME "->%s + %s",
+    pushf (indent, stream,
+	   COMPILE_I_SIMPLE_REGISTER_ARG_NAME "->%s + (" GCC_UINTPTR ") %s",
 	   regname, hex_string (offset));
 
   do_cleanups (cleanups);
@@ -605,7 +608,8 @@  do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
 
   ++scope;
 
-  fprintfi_filtered (indent, stream, "%s%s;\n", type_name, result_name);
+  fprintfi_filtered (indent, stream, "__attribute__ ((unused)) %s %s;\n",
+		     type_name, result_name);
   fprintfi_filtered (indent, stream, "{\n");
   indent += 2;
 
@@ -899,7 +903,7 @@  do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
 		       (long) (op_ptr - base));
 
 	    do_compile_dwarf_expr_to_c (indent, stream,
-					"void *", fb_name,
+					GCC_UINTPTR, fb_name,
 					sym, pc,
 					arch, registers_used, addr_size,
 					datastart, datastart + datalen,
@@ -1080,7 +1084,7 @@  do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
 			   "__cfa_%ld", (long) (op_ptr - base));
 
 		do_compile_dwarf_expr_to_c (indent, stream,
-					    "void *", cfa_name,
+					    GCC_UINTPTR, cfa_name,
 					    sym, pc, arch, registers_used,
 					    addr_size,
 					    cfa_start, cfa_end,
@@ -1117,8 +1121,8 @@  do_compile_dwarf_expr_to_c (int indent, struct ui_file *stream,
 	}
     }
 
-  fprintfi_filtered (indent, stream, "%s = (%s) __gdb_stack[__gdb_tos];\n",
-		     result_name, type_name);
+  fprintfi_filtered (indent, stream, "%s = __gdb_stack[__gdb_tos];\n",
+		     result_name);
   fprintfi_filtered (indent - 2, stream, "}\n");
 
   do_cleanups (cleanup);
@@ -1134,7 +1138,7 @@  compile_dwarf_expr_to_c (struct ui_file *stream, const char *result_name,
 			 const gdb_byte *op_ptr, const gdb_byte *op_end,
 			 struct dwarf2_per_cu_data *per_cu)
 {
-  do_compile_dwarf_expr_to_c (2, stream, "void *", result_name, sym, pc,
+  do_compile_dwarf_expr_to_c (2, stream, GCC_UINTPTR, result_name, sym, pc,
 			      arch, registers_used, addr_size, op_ptr, op_end,
 			      NULL, per_cu);
 }
diff --git a/gdb/compile/compile.c b/gdb/compile/compile.c
index 621de66..ab19a5d 100644
--- a/gdb/compile/compile.c
+++ b/gdb/compile/compile.c
@@ -680,8 +680,11 @@  String quoting is parsed like in shell, for example:\n\
      absolute target address.
      -fPIC is not used at is would require from GDB to generate .got.  */
 			 " -fPIE"
-  /* We don't want warnings.  */
-			 " -w"
+  /* We want warnings, except for some commonly happening for GDB commands.  */
+			 " -Wall "
+			 " -Wno-implicit-function-declaration"
+			 " -Wno-unused-but-set-variable"
+			 " -Wno-unused-variable"
   /* Override CU's possible -fstack-protector-strong.  */
 			 " -fno-stack-protector"
   );
diff --git a/gdb/testsuite/gdb.compile/compile-ops.exp b/gdb/testsuite/gdb.compile/compile-ops.exp
index 26882bd..0ef3c8d 100644
--- a/gdb/testsuite/gdb.compile/compile-ops.exp
+++ b/gdb/testsuite/gdb.compile/compile-ops.exp
@@ -416,7 +416,7 @@  if {[skip_compile_feature_tests]} {
 }
 
 # If we have a bug, this will hang.
-gdb_test_no_output "compile code param"
+gdb_test_no_output "compile code (void) param"
 
 # We can't access optimized-out variables, but their presence should
 # not affect compilations that don't refer to them.
diff --git a/gdb/testsuite/gdb.compile/compile.exp b/gdb/testsuite/gdb.compile/compile.exp
index dc09770..abe5e9b 100644
--- a/gdb/testsuite/gdb.compile/compile.exp
+++ b/gdb/testsuite/gdb.compile/compile.exp
@@ -71,13 +71,13 @@  gdb_test_no_output "compile -- f = 10" \
 gdb_test "compile f = 10;" ".*= 10;: No such file.*" \
     "Test abbreviations and code collision"
 
-gdb_test_no_output "compile -r -- _gdb_expr(){int i = 5;}" \
+gdb_test_no_output "compile -r -- void _gdb_expr(){int i = 5;}" \
     "Test delimiter with -r"
 
-gdb_test_no_output "compile -raw -- _gdb_expr(){int i = 5;}" \
+gdb_test_no_output "compile -raw -- void _gdb_expr(){int i = 5;}" \
     "Test delimiter with -raw"
 
-gdb_test "compile -- -r  _gdb_expr(){int i = 5;}" \
+gdb_test "compile -- -r  void _gdb_expr(){int i = 5;}" \
     ".* error: 'r' undeclared \\(first use in this function\\).*" \
     "Test delimiter with -r after it"
 
@@ -189,7 +189,12 @@  gdb_test "p localvar" " = 1"
 # Test setting fields and also many different types.
 #
 
-gdb_test_no_output "compile code struct_object.selffield = &struct_object"
+set test "compile code struct_object.selffield = &struct_object"
+gdb_test_multiple $test $test {
+    -re "gdb command line:1:25: warning: assignment discards 'volatile' qualifier from pointer target type \\\[-Wdiscarded-qualifiers\\\]\r\n$gdb_prompt $" {
+	xfail "$test (PR compile/18202)"
+    }
+}
 gdb_test "print struct_object.selffield == &struct_object" " = 1"
 
 gdb_test_no_output "compile code struct_object.charfield = 1"
@@ -261,7 +266,7 @@  gdb_test "print 'compile.c'::globalshadow" " = 77000" \
 
 # Test GOT vs. resolving jit function pointers.
 
-gdb_test_no_output "compile -raw -- int func(){return 21;} _gdb_expr(){int (*funcp)()=func; if (funcp()!=21) abort();}" \
+gdb_test_no_output "compile -raw -- int func(){return 21;} void _gdb_expr(){ void abort (void); int (*funcp)()=func; if (funcp()!=21) abort(); }" \
     "pointer to jit function"
 
 #