[Bug c/47901] New: -Wall should not imply -Wformat-zero-length by default

2011-02-26 Thread anders at kaseorg dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47901

   Summary: -Wall should not imply -Wformat-zero-length by default
   Product: gcc
   Version: 4.5.2
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: and...@kaseorg.com


There is nothing wrong with printf("") or custom_printf_like_function(foo, "").
 There are plenty of reasons to write such code: for example, when using a
macro that sometimes expands to the empty string, or if
custom_printf_like_function does something else with foo in addition to using
the format string, or if the string is used for something other than printing
and you really just want the empty string there.

gcc/c-format.c contains a comment that says “If the format is an empty string,
this should be counted similarly to the case of extra format arguments.”  But
those are not actually similar.  Extra format arguments clearly indicate that
the code was not written as intended, because the extra arguments could be
removed with no effects; but a zero-length string is there for a reason and
can’t just be removed.

When GCC complains about legitimate empty format strings as soon as -Wall is
turned on, it only leads to frustration with -Wall.  This leads some users to
give up on -Wall altogether, and thus to miss many of the real problems -Wall
would find; and leads others to come up with brain-damaged workarounds like
adding a useless space:
http://git.kernel.org/linus/6f131ce1dfa9b283ddc212df42b015d152c670a5

Can we change -Wformat-zero-length to default to off unless explicitly
requested?

See also:
http://gcc.gnu.org/ml/gcc-patches/2002-05/msg01469.html
http://ewx.livejournal.com/517490.html
http://www.mail-archive.com/qemu-devel@nongnu.org/msg43910.html


[Bug c/39985] Type qualifiers not actually ignored on function return type

2009-11-26 Thread anders at kaseorg dot com


--- Comment #3 from anders at kaseorg dot com  2009-11-27 07:33 ---
> my inclination is that we should eliminate the inconsistent attempts to give
> rvalues qualified types in some cases, and say that if the operand of typeof
> is not an lvalue it never has a qualified type.

Should typeof ever return a qualified type?  It is easy to add qualifiers to a
type if they are desired (const typeof(foo)), but seems difficult to remove
them.

For example, seemingly reasonable macros like
  #define MAX(__x, __y) ({   \
  typeof(__x) __ret = __x;   \
  if (__y > __ret) __ret = __y;  \
  __ret; \
  })
currently fail when given a qualified argument:
  const int c = 42;
  MAX(c, 17);  /* error: assignment of read-only variable ‘__ret’ */

This bug report was motivated by my attempts to fix a macro like this, by
replacing typeof(__x) with something that strips qualifiers.  These all fail to
strip qualifiers:
  typeof( ({ __x; }) )
  typeof( ((typeof(__x)(*)(void)) 0)() )
  typeof( (typeof(__x)) (__x) )
This seems to work, but only for numeric and pointer types:
  typeof( (typeof(__x)) 0 )
This succeeds at stripping qualifiers for numeric types, but for some reason it
promotes char and short to int, and it fails to strip qualifiers for
non-numeric types:
  typeof( 1 ? (__x) : (__x) )

Much confusion would be avoided if typeof(__x) just stripped qualifiers to
begin with.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39985



[Bug c/41045] Extended asm with C operands doesn�t work at top level

2009-10-09 Thread anders at kaseorg dot com


--- Comment #7 from anders at kaseorg dot com  2009-10-09 17:45 ---
> Really if the kernel should have compile time asserts that the offsets don't
> match up with the inline-asm.

Yes, it’s entirely possible that the kernel’s kludge could be made more robust
by adding complexity.  This doesn’t change the point that a solution based on
extended toplevel asm would be easier and simpler.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41045



[Bug c/41045] Extended asm with C operands doesn�t work at top level

2009-10-09 Thread anders at kaseorg dot com


--- Comment #5 from anders at kaseorg dot com  2009-10-09 16:12 ---
As Nelson pointed out, the subsequent commit to that macro
<http://git.kernel.org/linus/0b1c723d0bd199300a1a2de57a46000d17577498> cannot
be done with C.  In any event, while it may also be useful to add extensions
like nobits to C, adding enough extensions to subsume all conceivable uses of
inline assembly clearly isn’t a sustainable solution.

A more fundamental source of ugliness in the Linux kernel is that many
functions which are written entirely in assembly (and must be, because they
have special calling conventions dictated by the hardware, or are involved in
setting up the appropriate environment for executing C code, or must be
hand-optimized for performance, etc.) need to access members of a C struct. 
Since there is no way to get the offset of a C struct member from assembly, the
kernel’s current solution is to compile (but not assemble) a special file named
asm-offsets.c:

#define DEFINE(sym, val) \
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
int main(void)
{
#define ENTRY(entry) DEFINE(tsk_ ## entry, offsetof(struct task_struct, entry))
ENTRY(state);
ENTRY(flags); 
ENTRY(pid);
…   
}

resulting in asm-offsets.s:

main:
pushq   %rbp#
movq%rsp, %rbp  #,
#APP
->tsk_state $0 offsetof(struct task_struct, state)  #
->tsk_flags $20 offsetof(struct task_struct, flags) #
->tsk_pid $680 offsetof(struct task_struct, pid)#
…

which is post-processed with sed into a header asm-offsets.h that consists of a
long list of definitions for assembly code:

#define tsk_state 0 /* offsetof(struct task_struct, state)  # */
#define tsk_flags 20 /* offsetof(struct task_struct, flags) # */
#define tsk_pid 680 /* offsetof(struct task_struct, pid)# */
…

If toplevel extended asm was available, this entire mechanism could have been
unnecessary, because one could write this directly:

asm("kernel_thread:\n"
…
"movl %c[tsk_pid](%%rax),%%eax\n"
: : [tsk_pid] "n" (offsetof(struct task_struct, pid)));


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41045



[Bug c/41045] New: Extended asm with C operands doesn�t work at top level

2009-08-12 Thread anders at kaseorg dot com
I’d like to be able to write toplevel inline assembly with C operands that are
compile-time constants, e.g.

static const char foo[] = "Hello, world!";
enum { bar = 17 };
asm(".pushsection baz; .long %c0, %c1, %c2; .popsection"
: : "i" (foo), "i" (sizeof(foo)), "i" (bar));

However, this currently fails with “error: expected ‘)’ before ‘:’ token” at
the top level, even though it works fine inside a function.


-- 
   Summary: Extended asm with C operands doesn’t work at top level
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: enhancement
  Priority: P3
 Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: anders at kaseorg dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41045



[Bug c/39985] New: Type qualifiers not actually ignored on function return type

2009-04-30 Thread anders at kaseorg dot com
The warning printed with -Wignored-qualifiers (“warning: type qualifiers
ignored on function return type”) seems to be lying.  The const on a function’s
return type is not actually ignored, as can be demonstrated using typeof().  I
think that the warning should be right and the typeof() behavior is wrong, but
I’m not actually sure.

int f(void);
const int g(void);  /* warning: type qualifiers ignored on function return type
*/
typeof(f()) a;
a = 5;
typeof(g()) b;
b = 5;  /* error: assignment of read-only variable ‘b’ */

Another thing that seems similarly strange is that a statement expression can
return a const type, even though it is not an lvalue:

const int x = 5;
typeof( ({ x; }) ) y;
y = 5;  /* error: assignment of read-only variable ‘y’ */


-- 
   Summary: Type qualifiers not actually ignored on function return
type
   Product: gcc
   Version: 4.4.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: anders at kaseorg dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39985



[Bug c/37303] New: const compound initializers in structs are written to .data instead of .rodata

2008-08-31 Thread anders at kaseorg dot com
GCC generates identical code for the following two structures:

  const struct { const int *p; } foo = { (const int []) {1, 2, 3} };

  const struct { int *p; } foo = { (int []) {1, 2, 3} };

In both cases, the struct is written to the .rodata section, but the array {1,
2, 3} is written to the .data section:

.section.rodata
.align 8
.type   foo, @object
.size   foo, 8
foo:
.quad   __compound_literal.0
.data
.align 4
.type   __compound_literal.0, @object
.size   __compound_literal.0, 12
__compound_literal.0:
.long   1
.long   2
.long   3

For the first struct, where the array is const, it should also be written to
the .rodata section.

I’m using gcc 4.3.2-0ubuntu2 on Intrepid amd64.


-- 
   Summary: const compound initializers in structs are written to
.data instead of .rodata
   Product: gcc
   Version: 4.3.2
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: anders at kaseorg dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37303



[Bug c/36432] New: �incompatible pointer type� with pointer to array as a struct member

2008-06-03 Thread anders at kaseorg dot com
According to gcc warnings, a pointer to int[] can be assigned the address of an
int[3], but not if the variable is a struct member:

int main() {
int array[3];
int (*ptr)[];
struct { int (*ptr)[]; } st;

ptr = &array; // fine
st.ptr = &array;  // warning: assignment from incompatible pointer type
}


-- 
   Summary: “incompatible pointer type” with pointer to array as a
struct member
   Product: gcc
   Version: 4.3.0
Status: UNCONFIRMED
  Severity: minor
  Priority: P3
 Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: anders at kaseorg dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36432