[Bug c/89448] Failure to generate diagnostic for "complex int" (OK for "_Complex int")

2020-01-21 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89448

--- Comment #6 from Keith Thompson  ---
Since Bug 91980 has been closed as a duplicate of this one, I'll
mention explicitly that another symptom of the bug is that this:

#include 
complex x;
// _Complex y;

produces no diagnostic.

[Bug c/54486] New: Spurious printf format warning mentions nonexistent type 'sizetype'

2012-09-04 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54486

 Bug #: 54486
   Summary: Spurious printf format warning mentions nonexistent
type 'sizetype'
Classification: Unclassified
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: keith.s.thomp...@gmail.com


printf's "%zu" format expects an argument of type size_t.  In the sample
program, the corresponding argument is of type size_t in all the printf calls
(the first because strspn() is defined to return a size_t result, and the
second because of the explicit cast, and similarly for the others).

For a call to strlen() or to a user-defined function func(), gcc rightly does
not complain.

For a call to strspn(), even with an explicit cast, gcc incorrectly complains
that the arguments is of type ‘sizetype’ -- which, as far as I can tell,
doesn't exist.  (If I try to add a variable definition of type ‘sizetype’, I
get "error: unknown type name ‘sizetype’", and I can find no reference to
‘sizetype’ in any of my system's headers.)

I see nothing unusual in the declaration of strspn() in /usr/include/string.h.

$ uname -a 
Linux kvetch 3.2.0-29-generic-pae #46-Ubuntu SMP Fri Jul 27 17:25:43 UTC 2012
i686 i686 i386 GNU/Linux
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=12.10
DISTRIB_CODENAME=quantal
DISTRIB_DESCRIPTION="Ubuntu quantal (development branch)"
$ gcc --version
gcc (Ubuntu/Linaro 4.7.0-7ubuntu3) 4.7.0
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ cat c.c
#include 
#include 

extern size_t func(void);

int main(void) {
printf("%zu\n", strspn("abc", "abcdefg")); /* line 7 */
printf("%zu\n", (size_t)strspn("abc", "abcdefg")); /* line 8 */
printf("%zu\n", strlen("foo"));
printf("%zu\n", (size_t)strlen("foo"));
printf("%zu\n", func());
printf("%zu\n", (size_t)func());
return 0;   
}   
$ gcc -c -std=c99 -pedantic c.c
c.c: In function ‘main’:
c.c:7:5: warning: format ‘%zu’ expects argument of type ‘size_t’, but argument
2 has type ‘sizetype’ [-Wformat]
c.c:8:5: warning: format ‘%zu’ expects argument of type ‘size_t’, but argument
2 has type ‘sizetype’ [-Wformat]
$


[Bug c/50662] New: Incorrect diagnostic returning non-const array pointer

2011-10-07 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50662

 Bug #: 50662
   Summary: Incorrect diagnostic returning non-const array pointer
Classification: Unclassified
   Product: gcc
   Version: 4.5.2
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: keith.s.thomp...@gmail.com


Compiling the following program:
==
typedef int this_type;
typedef int that_type[8];

static this_type this;
static that_type that;

static const this_type *this_func(void) {
return &this;
}

static const that_type *that_func(void) {
return &that; /* line 12 */
}
==

produces the following error:
==
$ gcc -c -std=c99 -pedantic-errors const_pointer.c
const_pointer.c: In function ‘that_func’:
const_pointer.c:12:5: error: return from incompatible pointer type
==

I believe that the return statement is valid.  The return statement returns a
"that_type*" result in a function returning "const that_type*".  There is no
potential violation of const-correctness.

Note that "this_func" does not trigger a diagnostic.  I don't believe that the
fact that "this_type" is an integer type and "that_type" is an array type
should matter.  In particular, there is no array-to-pointer decay.

This showed up in a question on stackoverflow.com:

http://stackoverflow.com/questions/7691295/return-from-incompatible-pointer-type-const-vs-non-const-c-gcc


[Bug c/53391] New: Slightly misleading warning on printf format mismatch

2012-05-17 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53391

 Bug #: 53391
   Summary: Slightly misleading warning on printf format mismatch
Classification: Unclassified
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: minor
  Priority: P3
 Component: c
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: keith.s.thomp...@gmail.com


Given the following program (c.c):

#include 
int main(void) {
typedef long my_long;
my_long x = 42;
printf("x = %d\n", (long)x);
return 0;
}

"gcc -c c.c" produces the following warning:

c.c: In function ‘main’:
c.c:5:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2
has type ‘my_long’ [-Wformat]

The argument is actually of type long, not my_long; the warning should say
"..., but argument 2 has type ‘long’".

Now because of the way typedefs work, long and my_long are really different
names for the same type. gcc is obviously trying to be clever about which name
makes for a clearer warning message. In this case, since x is explicitly
converted to long, referring to "long" would be less confusing. *Some* warning
is certainly appropriate, since "%d" requires an int argument.

(Speculation: gcc sees that the cast is a no-op, so it ignores it, which is
fine except that it results in this misleading warning message.)

Ubuntu x86 12.04
gcc (Ubuntu/Linaro 4.7.0-7ubuntu3) 4.7.0


[Bug c/53391] Slightly misleading warning on printf format mismatch

2012-05-18 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53391

--- Comment #2 from Keith Thompson  
2012-05-18 18:26:31 UTC ---
The cleverness I was referring to was having diagnostics refer to an
appropriate typedef rather than to the original type (e.g., "size_t" rather
than "unsigned int").  I find this clever in a *good* way.

The conversion is a no-op if my_long happens to be the same type as long, as it
is in this example -- but it's very useful from the programmer's point of view
if my_long (or something with a more meaningful name) *could* be either long or
int.

I suppose solving this would require saving some information about the cast so
that the name of the type of the expression ("my_long" rather than "long") can
be referred to in diagnostic messages.

I should note that this is not production code.  The original program was
intended to use "%ld" and convert the argument to long; I ran into the
misleading warning due to a logic error.


[Bug c/54188] New: Inconsistent __alignof__(long long)

2012-08-06 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54188

 Bug #: 54188
   Summary: Inconsistent __alignof__(long long)
Classification: Unclassified
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: minor
  Priority: P3
 Component: c
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: keith.s.thomp...@gmail.com


The __alignof__ operator applied to a struct type with a single long
long member yields 4.  This is inconsistent; a struct's alignment
should be at least as large as the alignment of any of its members.

I'm using gcc 4.7.0 on Ubuntu 12.04 x86.

gcc -v says:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.7/lto-wrapper
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro
4.7.0-7ubuntu3' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs
--enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-4.7 --enable-shared --enable-linker-build-id
--with-system-zlib --libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7
--libdir=/usr/lib --enable-nls --disable-bootstrap --with-sysroot=/
--enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes
--enable-gnu-unique-object --enable-plugin --enable-objc-gc
--enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic
--enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu
--target=i686-linux-gnu
Thread model: posix
gcc version 4.7.0 (Ubuntu/Linaro 4.7.0-7ubuntu3) 

Demo program (alignof_bug.c):

#include 
#include 

/*
 * See ,
 * posted by PiotrNycz
 */

/*
 * The ALIGNOF macro yields the alignment in bytes of a given type,
 * determined by how the compiler aligns a member of the type in
 * a struct following a single char member.
 */
#define ALIGNOF(type) ((int)(offsetof(struct {char c; type t;}, t)))

struct wrapper {
long long ll;
};

int main(void) {
printf("__alignof__(long long)  = %d\n",
   (int)__alignof__(long long));
printf("__alignof__(struct wrapper) = %d\n",
   (int)__alignof__(struct wrapper));
printf("ALIGNOF(long long)  = %d\n",
   (int)ALIGNOF(long long));
printf("ALIGNOF(struct wrapper) = %d\n",
   (int)ALIGNOF(struct wrapper));

if (__alignof__(long long) > __alignof__(struct wrapper)) {
puts("Inconsistent __alignof__, long long vs. struct");
}
if (__alignof__(long long) != ALIGNOF(long long)) {
puts("Inconsistent alignment for long long");
}

return 0;
}


Output:

__alignof__(long long)  = 8
__alignof__(struct wrapper) = 4
ALIGNOF(long long)  = 4
ALIGNOF(struct wrapper) = 4
Inconsistent __alignof__, long long vs. struct
Inconsistent alignment for long long


A response to
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10360
suggests that __alignof__ needn't necessarily yield the same result
as the offset of a member within a struct.  I'm not sure I agree
with that, but the main problem I'm reporting here refers to the
alignment of the struct type itself, compared to the alignment of
one of its members.


[Bug c/54188] Inconsistent __alignof__(long long)

2012-08-06 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54188

--- Comment #1 from Keith Thompson  
2012-08-06 09:33:43 UTC ---
Forgot to mention: I compiled and executed the demo program as follows:

gcc alignof_bug.c -o alignof_bug && ./alignof_bug


[Bug c/54188] Inconsistent __alignof__(long long)

2012-08-06 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54188

--- Comment #3 from Keith Thompson  
2012-08-06 19:28:37 UTC ---
The results of the _Alignof operator (new in the 2011 ISO C standard)
are the same as for the __alignof__ operator (not surprisingly).

N1370 (C11 draft) 6.5.3.4 paragraph 3 says:

The _Alignof operator yields the alignment requirement of its
operand type.

Richard Guenther: You say it's "Because the ABI says so".  Do you have
a reference to the ABI, particularly to a statement that a structure
should have a smaller alignment than its member?

You also say __alignof__ "does not return the minimum but the
recommended alignment".  That seems inconsistent with the use of the
word "required" in C11.

I just grabbed a copy of http://www.uclibc.org/docs/psABI-i386.pdf;
is that the ABI you're referring to?  Figure 3-1 covers alignment
for scalar types.  It says 8-byte floating-point has an alignment
of 4 bytes, but it doesn't mention 8-byte integers.  Furthermore,
the following page says:

Aggregates (structures and arrays) and unions assume the alignment
of their most strictly aligned component.

That seems inconsistent with the behavior of the following program:

#include 
int main(void) {
printf("_Alignof(long long) = %d\n",
   (int)_Alignof(long long));
printf("_Alignof(struct {long long x;}) = %d\n",
   (int)_Alignof(struct {long long x;}));
return 0;
}

whose output on my system, with
gcc -std=c11 -pedantic c.c -o c && ./c
is:

_Alignof(long long) = 8
_Alignof(struct {long long x;}) = 4


[Bug c++/33101] Bad C++ error on invalid code: has incomplete type

2012-03-16 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33101

Keith Thompson  changed:

   What|Removed |Added

 CC||Keith.S.Thompson at gmail
   ||dot com

--- Comment #10 from Keith Thompson  
2012-03-16 19:26:45 UTC ---
This came up in a question on stackoverflow.com:

http://stackoverflow.com/q/9742135/827263

I believe the code is valid. Here's a simpler test case:

typedef void VOID;
int main(VOID) { }

which g++ 4.5.2 rejects with the following:

void_test.cpp:2:10: error: ‘’ has incomplete type
void_test.cpp:2:14: error: invalid use of ‘VOID’

Quoting N3290, a draft of the 2011 ISO C++ standard, section 8.3.5 [dcl.fct]:

The parameter-declaration-clause determines the arguments that can
be specified, and their processing, when the function is called.
[ ... ] If the parameter-declaration-clause is empty, the function
takes no arguments. The parameter list (void) is equivalent to
the empty parameter list. Except for this special case, void
shall not be a parameter type (though types derived from void,
such as void*, can).

Earlier versions of the standard have similar or identical wording.

The last sentence implies that "void" here is being used as a type
name, not as some special-case syntactic use of the keyword.  I believe
the phrase "special case" is meant to exclude declarations like

void foo(void, int);

or 

void bar(void param);

not to prohibit the use of a typedef.  Since a typedef creates an
*alias* for an existing type, the name "VOID" should be usable as a
replacement for "void" whenever it's used as a type name.

Note that the syntax for a parameter-declaration does not refer
specifically to the "void" keyword; rather, "void" is valid in that
context because it's a type name.

Practically speaking, the purpose of allowing "void" as a parameter
declaration is for compatibility with C.  Quoting the latest draft
of the C standard, N1570 6.7.6.3p10:

The special case of an unnamed parameter of type void as the only
item in the list specifies that the function has no parameters.

It refers to the *type* void, not the keyword, implying that a
typedef is acceptable in this context -- and gcc 4.5.2 accepts the
above program without complaint when compiling it as C.

I agree that the C++ standard's wording is ambiguous, and *could*
be read as requiring the keyword "void", but I believe the intent
is to permit a typedef.  (And if you want to argue that the use of
a typedef is silly, I agree completely.)

I believe that the resolution of DR 577:
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#577
confirms this.  The resolution, as of August, 2011, suggests changing
the wording to refer to the *type* void rather than the keyword.  
(That change doesn't appear in the N3270 draft; I don't know whether
it appears in the final ISO C++ 2011 standard.)

At the very least, since there is (unfortunately) real-world code that 
depends on this, I suggest changing it from a fatal error to a warning,
though I think removing the diagnostic altogether would be better.


[Bug c++/33101] Bad C++ error on invalid code: has incomplete type

2012-03-16 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33101

--- Comment #11 from Keith Thompson  
2012-03-16 19:30:17 UTC ---
And since the C++ code is valid, the title of this bug should be changed.


[Bug c++/33101] [DR 577] allow typedefs for void in empty parameter list

2012-03-16 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33101

--- Comment #14 from Keith Thompson  
2012-03-16 21:41:18 UTC ---
On re-reading DR 577, I agree that it implies the current standard
says that only "(void)" is allowed, and in particular that a typedef
is not.  I might have interpreted it differently myself, but I defer to
the committee.  (I thought perhaps that the change had been made between
N3290 and the released standard, but apparently that's not the case.)

The fact that C90 required the keyword further weakens my previous
argument.

So the diagnostic is necessary, but I'd still suggest that a warning
would be more appropriate, and would still meet the current standard's
requirements.

(I should mention that I have no need for this myself; I don't even take
advantage of the permission to use "(void)" rather than "()".)


[Bug c++/51115] New: "-Wstrict-prototypes" is rejected for C++ (ok) but accepted for Ada (meaningless)

2011-11-12 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51115

 Bug #: 51115
   Summary: "-Wstrict-prototypes" is rejected for C++ (ok) but
accepted for Ada (meaningless)
Classification: Unclassified
   Product: gcc
   Version: 4.5.2
Status: UNCONFIRMED
  Severity: trivial
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: keith.s.thomp...@gmail.com


Created attachment 25811
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=25811
Demo script

When the "-Wstrict-prototypes" option is used when compiling C++, the following
warning appears:

cc1plus: warning: command line option "-Wstrict-prototypes" is valid for
Ada/C/ObjC but not for C++

The warning option doesn't make sense for C++, since the language doesn't
permit old-style non-prototype function declarations, but it makes even less
sense for Ada.  Further experiment shows that the option is quietly accepted
when compiling Ada.

Suggested solution:

1. Make the Ada front end complain about "-Wstrict-prototypes" (unless there's
a general policy of having it quietly accept options that don't make sense).

2. Drop "Ada/" from the cc1plus warning message.

The attached sh script demonstrates the problem.  The output on my system is:


% gcc --version
gcc (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

% gnatmake --version
GNATMAKE 4.4.5
Copyright (C) 1995-2008, Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.

% uname -a
Linux kvetch 2.6.38-12-generic #51-Ubuntu SMP Wed Sep 28 14:25:20 UTC 2011 i686
i686 i386 GNU/Linux

=== C ===
% gcc -c -Wstrict-prototypes foo.c

=== C++ ===
% g++ -c -Wstrict-prototypes foo.cpp
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for
Ada/C/ObjC but not for C++
% gcc -c -Wstrict-prototypes foo.cpp
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for
Ada/C/ObjC but not for C++

=== Objective-C
% gcc -c -Wstrict-prototypes foo.m

=== Ada ===
% gnatmake foo.adb -cargs -Wstrict-prototypes
gcc-4.4 -c -Wstrict-prototypes foo.adb
gnatbind -x foo.ali
gnatlink foo.ali


[Bug c/51628] New: __attribute__((packed)) is unsafe in some cases

2011-12-19 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51628

 Bug #: 51628
   Summary: __attribute__((packed)) is unsafe in some cases
Classification: Unclassified
   Product: gcc
   Version: 4.5.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: keith.s.thomp...@gmail.com


Created attachment 26147
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=26147
packed.c test case with output in a comment

I've seen this problem with gcc 4.5.1 on SPARC Solaris 9.  I presume it will
affect other versions of gcc on other platforms with strict alignment
requirements (unlike x86, which supports misaligned accesses in hardware as I
understand it).  I think it also applies to "#pragma pack".

The gcc extension __attribute__(packed), which applied to a struct, has the
following semantics (quoting the gcc documentation for 4.5.2):

 The `packed' attribute specifies that a variable or structure field
 should have the smallest possible alignment--one byte for a
 variable, and one bit for a field, unless you specify a larger
 value with the `aligned' attribute.

When a program accesses a misaligned member of a packed struct, the compiler
generates whatever code is necessary to read or write the correct value.

If the address of a misaligned member is stored in a pointer object,
dereferencing that pointer doesn't give the compiler an opportunity to generate
that extra code.

The attached program demonstrates the problem, and includes (as a comment) the
output I get on Ubuntu x86 (ok) and Solaris 9 SPARC (bus error).

See also
http://stackoverflow.com/questions/8568432/is-gccs-attribute-packed-pragma-pack-unsafe/

I don't believe it would be practical to fix this (though there might be some
clever solution I haven't thought of).  But at least I suggest mentioning this
issue in the documentation.


[Bug c/51628] __attribute__((packed)) is unsafe in some cases

2011-12-19 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51628

--- Comment #1 from Keith Thompson  
2011-12-19 23:05:50 UTC ---
A commenter on stackoverflow points out that a possible fix would be to permit
the address of a member of a packed structure to be assigned only to a pointer
object that is itself declared "packed".


[Bug c/51628] __attribute__((packed)) is unsafe in some cases

2011-12-19 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51628

--- Comment #3 from Keith Thompson  
2011-12-20 00:36:52 UTC ---
I see no "-Walign" option, either in the versions of gcc I'm using or in the
online documentation.  Were you thinking of a different option?

What I'm suggesting, primarily, is that the issue should be mentioned in the
documentation of the "packed" attribute (and probably of "pragma #pack" as
well).


[Bug c++/91314] New: Confusing warning refers to nonexistent comma operator

2019-07-31 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91314

Bug ID: 91314
   Summary: Confusing warning refers to nonexistent comma operator
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com
  Target Milestone: ---

Test case:

int main() {
int a;
&(a=0);
}

Demonstration:

$ g++ -c -Wunused-value confusing_warning.cpp 
confusing_warning.cpp: In function ‘int main()’:
confusing_warning.cpp:3:7: warning: right operand of comma operator has no
effect [-Wunused-value]
3 | &(a=0);
  |   ^

The problem: The warning refers to a comma operator that does not
exist in the source.

Speculation (please ignore this if it's not useful):
The compiler internally generates some internal data structure that's
similar to a comma operator (something like `(a=0), &a`) and the
warning message is based on that.

I've reproduced this problem with all versions of g++ I have access
to, from 4.1.2 to 10.0.0 20190718 (experimental).

This problem was originally reported by Stefan Ram 
on comp.lang.c++, 2019-07-24, thread "why can't I apply a bitwise modifier
directly in a function call?".

[Bug c++/91314] Confusing warning refers to nonexistent comma operator

2019-08-01 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91314

--- Comment #1 from Keith Thompson  ---
Irrelevant correction: The post was in comp.lang.c, not comp.lang.c++.

[Bug c++/87519] -Wsign-conversion -Wconversion explicit cast fails to silence warning

2019-08-07 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87519

Keith Thompson  changed:

   What|Removed |Added

 CC||Keith.S.Thompson at gmail dot 
com

--- Comment #8 from Keith Thompson  ---
Another test case:

#include 
int main() {
int i = 42;
size_t s0 = sizeof (int) + (size_t)i;
size_t s1 = sizeof (int) + static_cast(i);
}

https://stackoverflow.com/q/57403497/827263
https://stackoverflow.com/a/57404123/827263

[Bug c/91980] New: No diagnostic for type "complex"

2019-10-02 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91980

Bug ID: 91980
   Summary: No diagnostic for type "complex"
   Product: gcc
   Version: 8.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com
  Target Milestone: ---

"gcc -std=c11 -pedantic-errors" does not issue a required
diagnostic for a declaration using type "complex". The
C standard requires "float _Complex", "double _Complex", or
"long double _Complex" (or equivalent; the keywords can be
in any order and "_Complex" can be replaced by "complex"
if  is included).
See C11/N1570 6.7.1 "Type specifiers"

Test case "complex-bug.c":

#include 
complex x;
// _Complex y;


The command
gcc -std=c11 -pedantic-errors -c complex-bug.c
produces no diagnostics for this source file.

Further experiments, not shown here, indicate that
x is of type double _Complex.

If the declaration of "y" is uncommented, a diagnostic
is issued:

complex-bug.c:3:1: error: ISO C does not support plain ‘complex’ meaning
‘double complex’ [-Wpedantic]
 _Complex y;
 ^~~~


("complex" and "_Complex" should be treated identically.)

I've reproduced this problem with gcc 8.3.0 on Ubuntu 19.04
and with 10.0.0 20190916 (experimental) (built from source)
on Ubuntu 18.04.3.

[Bug c/91980] No diagnostic for type "complex"

2019-10-03 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91980

--- Comment #3 from Keith Thompson  ---
Not surprisingly, when I modify my "complex-bug.c" changing
#include 
to
#include "complex.h"
and add a "complex.h file containing only
#define complex _Complex
the problem goes away (i.e., the correct diagnostic is printed).

[Bug c/83584] New: "ISO C forbids conversion of object pointer to function pointer type" -- no, not really

2017-12-24 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83584

Bug ID: 83584
   Summary: "ISO C forbids conversion of object pointer to
function pointer type" -- no, not really
   Product: gcc
   Version: 7.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com
  Target Milestone: ---

$ gcc --version
gcc (GCC) 7.1.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ cat c.c
int main(void) {
typedef void (func)(void);
void *ptr = 0;
func *fptr = (func*)ptr;
}
$ gcc -std=c11 -pedantic-errors -c c.c
c.c: In function ‘main’:
c.c:4:18: error: ISO C forbids conversion of object pointer to function pointer
type [-Wpedantic]
 func *fptr = (func*)ptr;
  ^
$ 

In fact the conversion does not violate any syntax rule or constraint,
though its behavior is undefined.

N1570 6.5.4 p2-4 specifies the constraints on the cast operator. It
permits conversions between scalar types (which include pointer types). p4
specifically forbids conversions between pointer types and floating-point
types. There's nothing about pointer-to-function types.

6.3.2.3 defines the semantics of pointer conversions. It says nothing
about conversions between void* and pointer-to-function types -- which
means the behavior is undefined by omission.

The diagnostic should be a non-fatal warning when "-pedantic-errors"
is used, and it should be rephrased.

[Bug c/83584] "ISO C forbids conversion of object pointer to function pointer type" -- no, not really

2017-12-24 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83584

--- Comment #1 from Keith Thompson  ---
Tested on x86_64 Ubuntu 17.04, gcc 7.1.0 built from source

[Bug c/83584] "ISO C forbids conversion of object pointer to function pointer type" -- no, not really

2017-12-24 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83584

--- Comment #4 from Keith Thompson  ---
I'm aware that the standard has not changed in this area from C90 to C99
to C11.  The conversion is undefined behavior, not a constraint violation,
in all three editions.

If the conversion is forbidden, what syntax rule or constraint does
it violate?

[Bug c/83584] "ISO C forbids conversion of object pointer to function pointer type" -- no, not really

2017-12-25 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83584

--- Comment #6 from Keith Thompson  ---
Andreas: As I understand it, POSIX requires conversions between
object pointers and function pointers to work only for the specific
values returned by dlsym().

In any case, that's not directly relevant to this bug.

[Bug c/83584] "ISO C forbids conversion of object pointer to function pointer type" -- no, not really

2017-12-26 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83584

--- Comment #7 from Keith Thompson  ---
I don't agree that this bug report is invalid.  I see that the
Bugzilla interface lets me change the status.  Would it be appropriate
to do so?

[Bug c/83584] "ISO C forbids conversion of object pointer to function pointer type" -- no, not really

2017-12-26 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83584

Keith Thompson  changed:

   What|Removed |Added

 Status|RESOLVED|UNCONFIRMED
 Resolution|INVALID |---

--- Comment #9 from Keith Thompson  ---
In my opinion, this is a genuine bug. The conversion warrants a warning,
but not a fatal error. (For it to be an error, it should violate a specific
constraint or syntax rule.)

[Bug c/83584] "ISO C forbids conversion of object pointer to function pointer type" -- no, not really

2017-12-26 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83584

--- Comment #12 from Keith Thompson  ---
Andrew:

In my opinion, such conversions have undefined behavior (simply because
the standard does not define their behavior), but they are not forbidden.

The "-pedantic" and "-pedantic-errors" options, as I understand their
description, cause gcc to produce all diagnostic required by the C
standard. The only required diagnostics are for (a) #error directives,
(b) violations of syntax rules, and (c) violations of constraints.

Is my understanding correct?

If so, what syntax rule or constraint is violated by the program in
the description?

For example, (void*)1.0 violates the constraint in N1570 6.5.4 p4.

(I'll note in passing, without claiming that it's directly relevant,
that "clang -c -std=c11 -pedantic-errors" does not produce a diagnostic.)

This is not a duplicate of #11234, it's the opposite. #11234 complains
that a diagnostic is not produced; this bug report complains that it does.

I don't want to get into an editing war, so I'll leave the status as it
is for now.

[Bug c/83584] "ISO C forbids conversion of object pointer to function pointer type" -- no, not really

2019-06-05 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83584

--- Comment #18 from Keith Thompson  ---
Something I probably should have noticed earlier:

Why was this bug closed as a duplicate of bug 11234?

Bug 11234 complains that conversions between function pointer and void*
are accepted. This bug is exactly the opposite, complaining that they're
rejected.

If the resolution of #11234 were valid, then this bug would be invalid,
not a duplicate. (I've already stated my opinion.)

[Bug preprocessor/69665] New: Internal error on #pragma push_macro("__FILE__")

2016-02-03 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69665

Bug ID: 69665
   Summary: Internal error on #pragma push_macro("__FILE__")
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: preprocessor
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com
  Target Milestone: ---

The line of code that causes the problem is from this answer on Stack Overflow,
posted by Alain Totouom: http://stackoverflow.com/a/3078/827263

The main problem, of course, is that cpp dies with an internal error.

A minor secondary problem is that after reporting the internal error, cpp
prints a tab character to stdout, not followed by a newline.  I've manually
added a newline to the following transcript so all the "$" prompts are
left-justified.

$ uname -a
Linux bomb20 3.16.0-38-generic #52~14.04.1-Ubuntu SMP Fri May 8 09:43:57 UTC
2015 x86_64 x86_64 x86_64 GNU/Linux
$ cpp --version
cpp (GCC) 5.3.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ gcc --version
gcc (GCC) 5.3.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ cat gcc-push_macro-bug.c
#pragma push_macro("__FILE__")
$ cpp gcc-push_macro-bug.c
gcc-push_macro-bug.c:1:31: internal compiler error: invalid hash type 1 in
cpp_macro_definition
0x644ff8 c_cpp_error(cpp_reader*, int, int, unsigned int, unsigned int, char
const*, __va_list_tag (*) [1])
/home/kst/src/gcc/gcc-5.3.0/gcc/c-family/c-common.c:10029
0xf6b03a cpp_diagnostic
/home/kst/src/gcc/gcc-5.3.0/libcpp/errors.c:60
0xf6b166 cpp_error(cpp_reader*, int, char const*, ...)
/home/kst/src/gcc/gcc-5.3.0/libcpp/errors.c:75
0xf7bc14 cpp_macro_definition(cpp_reader*, cpp_hashnode*)
/home/kst/src/gcc/gcc-5.3.0/libcpp/macro.c:3330
0xf68c62 do_pragma_push_macro
/home/kst/src/gcc/gcc-5.3.0/libcpp/directives.c:1517
0xf679e5 do_pragma
/home/kst/src/gcc/gcc-5.3.0/libcpp/directives.c:1432
0xf69451 _cpp_handle_directive
/home/kst/src/gcc/gcc-5.3.0/libcpp/directives.c:509
0xf76314 _cpp_lex_token
/home/kst/src/gcc/gcc-5.3.0/libcpp/lex.c:2188
0xf7ad67 cpp_get_token_1
/home/kst/src/gcc/gcc-5.3.0/libcpp/macro.c:2442
0x65895f scan_translation_unit
/home/kst/src/gcc/gcc-5.3.0/gcc/c-family/c-ppoutput.c:192
0x65895f preprocess_file(cpp_reader*)
/home/kst/src/gcc/gcc-5.3.0/gcc/c-family/c-ppoutput.c:113
0x6572d0 c_common_init()
/home/kst/src/gcc/gcc-5.3.0/gcc/c-family/c-opts.c:1033
0x5cb7d3 lang_dependent_init
/home/kst/src/gcc/gcc-5.3.0/gcc/toplev.c:1836
0x5cb7d3 do_compile
/home/kst/src/gcc/gcc-5.3.0/gcc/toplev.c:2053
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
# 1 "gcc-push_macro-bug.c"
# 1 ""
# 1 ""
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "" 2
# 1 "gcc-push_macro-bug.c"

$ gcc -c gcc-push_macro-bug.c
gcc-push_macro-bug.c:1:31: internal compiler error: invalid hash type 1 in
cpp_macro_definition
0x644ff8 c_cpp_error(cpp_reader*, int, int, unsigned int, unsigned int, char
const*, __va_list_tag (*) [1])
/home/kst/src/gcc/gcc-5.3.0/gcc/c-family/c-common.c:10029
0xf6b03a cpp_diagnostic
/home/kst/src/gcc/gcc-5.3.0/libcpp/errors.c:60
0xf6b166 cpp_error(cpp_reader*, int, char const*, ...)
/home/kst/src/gcc/gcc-5.3.0/libcpp/errors.c:75
0xf7bc14 cpp_macro_definition(cpp_reader*, cpp_hashnode*)
/home/kst/src/gcc/gcc-5.3.0/libcpp/macro.c:3330
0xf68c62 do_pragma_push_macro
/home/kst/src/gcc/gcc-5.3.0/libcpp/directives.c:1517
0xf679e5 do_pragma
/home/kst/src/gcc/gcc-5.3.0/libcpp/directives.c:1432
0xf69451 _cpp_handle_directive
/home/kst/src/gcc/gcc-5.3.0/libcpp/directives.c:509
0xf76314 _cpp_lex_token
/home/kst/src/gcc/gcc-5.3.0/libcpp/lex.c:2188
0xf7ad67 cpp_get_token_1
/home/kst/src/gcc/gcc-5.3.0/libcpp/macro.c:2442
0x65269c c_lex_with_flags(tree_node**, unsigned int*, unsigned char*, int)
/home/kst/src/gcc/gcc-5.3.0/gcc/c-family/c-lex.c:408
0x5fd4ff c_lex_one_token
/home/kst/src/gcc/gcc-5.3.0/gcc/c/c-parser.c:258
0x61a9dd c_parser_peek_token
/home/kst/src/gcc/gcc-5.3.0/gcc/c/c-parser.c:440
0x61a9dd c_parse_file()
/home/kst/src/gcc/gcc-5.3.0/gcc/c/c-parser.c:15443
0x657422 c_common_parse_file()
/home/kst/src/gcc/gcc-5.3.0/gcc/c-family/c-opts.c:1057
Please submit a full bug report,
with preprocessed source if appropria

[Bug c/69704] New: goto *42 is not diagnosed

2016-02-05 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69704

Bug ID: 69704
   Summary: goto *42 is not diagnosed
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com
  Target Milestone: ---

This program:

int main(void) {
goto *(void*)42;
}

shows a legal use of gcc's computed goto extension.

This program:

int main(void) {
goto *42;
}

results in the same generated machine code, but is not consistent with the
documented extension, which permits the expression following "goto *" to be of
type void*. (An int value can be converted to void*, but only via an explicit
cast, or in the special case of a null pointer constant.)

The expression *42 by itself is correctly diagnosed as an error.

$ uname -a
Linux bomb20 3.16.0-38-generic #52~14.04.1-Ubuntu SMP Fri May 8 09:43:57 UTC
2015 x86_64 GNU/Linux
$ gcc --version
gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4

This was inspired by this question on Stack Overflow:

http://stackoverflow.com/q/35236834/827263

posted by user Sarvadi.

[Bug preprocessor/66318] Error messages contain raw file name; malicious #line directives can do bad things

2016-03-08 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66318

--- Comment #6 from Keith Thompson  ---
Thanks to this:

http://undeadly.org/cgi?action=article&sid=20160308204011

I've now constructed a case where compiling a malicious source file can cause
xterm to freeze.

The source file uses a UTF-8 character in a file name. The problem occurs
when xterm is run without UTF-8 support. The first byte of the UTF-8 character
happens to be the "application program command" command, which causes
subsequent input to be ignored until the xterm receives the "string terminator"
byte '\234'.

To reproduce the problem:

1. Run "xterm -lc +u8"

2. In that xterm, run "/bin/sh". (The bash shell sends some control codes
   when it prints a prompt; /bin/sh typically doesn't. You might need to use
   some other shell.)

3. In that shell: "unset LC_ALL LC_CTYPE LANG".

4. printf '#line __LINE__ "\303\237"\n#error "Kaboom"\n' > kaboom.c

5. gcc -c kaboom.c

In a UTF-8 environment, this simply prints an error message that includes
a Unicode LATIN SMALL LETTER SHARP S as the file name:

$ gcc -c kaboom.c
ß:1:2: error: #error "Kaboom"

In an ASCII environment, as above, the xterm prints a LATIN CAPITAL
LETTER A WITH TILDE and freezes. (You can recover by doing a soft reset
via the middle-click mouse menu.)

[Bug c++/80648] New: Valid C++11 null pointer constant (1-1) is rejected

2017-05-05 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80648

Bug ID: 80648
   Summary: Valid C++11 null pointer constant (1-1) is rejected
   Product: gcc
   Version: 7.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com
  Target Milestone: ---

I'm using g++ 7.1.0, built from source, on Ubuntu 16.10 x86_64.

$ g++ --version
g++ (GCC) 7.1.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ uname -a
Linux bomb20 4.8.0-46-generic #49-Ubuntu SMP Fri Mar 31 13:57:14 UTC 2017
x86_64 x86_64 x86_64 GNU/Linux
$

Test case:

int main() {
void *p = 1-1;
}

When compiled with "g++ -std=c++03 -pedantic c.cpp", the compiler correctly
doesn't complain; likewise with -std=c++98.

With "g++ -std=c++11 -pedantic", it produces an error message:

c.cpp: In function ‘int main()’:
c.cpp:2:16: error: invalid conversion from ‘int’ to ‘void*’ [-fpermissive]
 void *p = 1-1;
   ~^~

And the same message with "g++ -std=c++14 -pedantic".

C++14 restricted the definition of a null pointer constant.  In the
N4296 draft, 4.10p1 [conv.ptr] says:

"A null pointer constant is an integer literal (2.13.2) with value
zero or a prvalue of type std::nullptr_t."

1-1 is not an integer literal, so the error message is correct for C++14.

But C++11 had not yet made that change.  The C++11 standard,
ISO/IEC 14882:2011(E), in the corresponding section, says:

"A null pointer constant is an integral constant expression (5.19)
prvalue of integer type that evaluates to zero or a prvalue of type
std::nullptr_t."

g++ correctly accepts 1-1 as a null pointer constant in C++98
and C++03 modes, and correctly rejects it in C++14 mode, but it
should accept it in C++11 mode.

(I do not of course suggest that using 1-1 as a null pointer constant
is a good idea.)

[Bug c++/80648] [DR903] Valid C++11 null pointer constant (1-1) is rejected

2017-05-06 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80648

Keith Thompson  changed:

   What|Removed |Added

 Status|RESOLVED|UNCONFIRMED
 Resolution|INVALID |---

--- Comment #2 from Keith Thompson  ---
http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#903

I don't believe this DR applies to C++11.

The header does say "Status: CD3", but the next line is:

> [Moved to DR status at the April, 2013 meeting.]

with an this  at the bottom:

Additional note (January, 2013):

> Concerns were raised at the Portland (October, 2012) meeting that
> the value false has been used in existing code as a null pointer
> constant, and such code would be broken by this change. This issue
> has been returned to "review" status to allow discussion of whether
> to accommodate such code or not.

And at the very top of the cwg_defects.html page:

> Issues with DR, accepted, DRWP, and WP status are NOT part of the 
> International Standard for C++.

[Bug c++/80648] [DR903] Valid C++11 null pointer constant (1-1) is rejected

2017-05-06 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80648

--- Comment #4 from Keith Thompson  ---
Then what does

> Issues with DR, accepted, DRWP, and WP status are NOT part of the 
> International Standard for C++.

mean?  The web page itself says that issues with DR status are not
part of C++11.

[Bug c++/80648] [DR903] Valid C++11 null pointer constant (1-1) is rejected

2017-05-07 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80648

--- Comment #6 from Keith Thompson  ---
Shall I submit a separate ticket against the documentation?

"info gcc" for gcc-7.1.0 has the following description for -std=c=+98 and
std=++03:

 'c++98'
 'c++03'
  The 1998 ISO C++ standard plus the 2003 technical corrigendum
  and some additional defect reports.  Same as '-ansi' for C++
  code.

and this for -std=c++11 and -std=c++0x:

 'c++11'
 'c++0x'
  The 2011 ISO C++ standard plus amendments.  The name 'c++0x'
  is deprecated.

Both should mention DRs.

(I question the policy of implementing DRs that have not been approved
by the committee. As I understand it, the existence of a DR merely means
that *someone* thinks there's a defect in the standard. Many DRs are
eventually rejected.)

[Bug c++/80648] [DR903] Valid C++11 null pointer constant (1-1) is rejected

2017-05-07 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80648

--- Comment #8 from Keith Thompson  ---
That's a surprising interpretation of the word "amendment".

Searching isocpp.org and other sites, I haven't found any official reference
to an "amendment" to the C++ standard.  The nearest thing I've found, which
is referenced in the gcc documentation, is the 1995 amendment to the 1990
ISO C standard, "ANSI/ISO/IEC 9899-1990/AM 1-1995".  That's definitely not
a DR.  (The C and C++ standard committees use similar procedures.)

Does g++ implement *all* DRs reported against C++11?

[Bug c/82755] New: Misleading error message "incompatible type for argument"

2017-10-27 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82755

Bug ID: 82755
   Summary: Misleading error message "incompatible type for
argument"
   Product: gcc
   Version: 7.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com
  Target Milestone: ---

I'm using gcc 7.2.0-8ubuntu3 on Ubuntu 17.10, x86_64.

$ cat c.c
void f(double a) { }

int main(void) {
int i;
f(&i);
}
$ gcc -c -std=c11 -pedantic c.c
c.c: In function ‘main’:
c.c:5:7: error: incompatible type for argument 1 of ‘f’
 f(&i);
   ^
c.c:1:6: note: expected ‘double’ but argument is of type ‘int *’
 void f(double a) { }
  ^

The problem is the phrase "incompatible type" in the error message. It's true
that the types int* and double are incompatible, but that's not why the call
is invalid. Types int and double are also incompatible (as the C standard
defines the term), but the call
f(42);
would be valid.

I suggest changing "incompatible type" to "incorrect type".

[Bug c/61240] New: Incorrect warning "integer overflow in expression" on pointer-pointer subtraction

2014-05-19 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61240

Bug ID: 61240
   Summary: Incorrect warning "integer overflow in expression" on
pointer-pointer subtraction
   Product: gcc
   Version: 4.8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com

Credit goes to "Lumbering Lummox", the author of this Stack Overflow post:
http://stackoverflow.com/q/23747641/827263

I see this problem with gcc versions 4.8.0 and 4.9.0, both compiled from
source, on Linux Mint 14 on x86_64.

Source program:

int main(void) {
int i;
int *p = &i;
int *q = &i + 1;
p - (p - 1);
q - (q - 1);
}

Compiler output:

% /usr/local/apps/gcc-4.8.0/bin/gcc gcc-bug-integer-overflow.c
gcc-bug-integer-overflow.c: In function ‘main’:
gcc-bug-integer-overflow.c:5:7: warning: integer overflow in expression
[-Woverflow]
 p - (p - 1);
   ^
gcc-bug-integer-overflow.c:6:7: warning: integer overflow in expression
[-Woverflow]
 q - (q - 1);
   ^

A warning would be appropriate for "p - (p - 1)", since (p - 1) has undefined
behavior -- but since it's pointer arithmetic, not integer arithmetic, the
"integer overflow" warning is at least incorrectly worded. Furthermore, the
error message points to the first "-", which is not the problem.

As for "q - (q - 1)", no warning should be issued at all, since both "(q - 1)"
and "q - (q - 1)" are valid expressions with well defined behavior (yielding &i
and (ptrdiff_t)1, respectively).

This might be related to bug #48267.

[Bug preprocessor/66317] New: Preprocessor chokes on __FILE__ containing a newline

2015-05-27 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66317

Bug ID: 66317
   Summary: Preprocessor chokes on __FILE__ containing a newline
   Product: gcc
   Version: 5.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: preprocessor
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com
  Target Milestone: ---

This is an obscure problem, unlikely to occur in the real world.
I do not suggest handling it "correctly", whatever that might mean,
just detecting it and terminating with a reasonable error message.

The problem can also occur if the actual file name contains a newline.

System: Linux Mint 17.
gcc version 5.1.0, built from source with:
gcc-5.1.0/configure --prefix=/usr/local/apps/gcc-5.1.0 --disable-multilib

Test case (a 2 line source file named "filename_bug.c"):
#line 1 "new\nline.c"
const char filename[] = __FILE__;

Output of "cpp filename_bug.c" (there is no newline on the last line of
output):
# 1 "filename_bug.c"
# 1 ""
# 1 ""
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "" 2
# 1 "filename_bug.c"
# 1 "new
line.c"
new
line.c:1:1: warning: missing terminating " character
new
line.c:1:25: internal compiler error: invalid built-in macro "__FILE__"
0x6449a8 c_cpp_error(cpp_reader*, int, int, unsigned int, unsigned int, char
const*, __va_list_tag (*) [1])
../gcc-5.1.0/gcc/c-family/c-common.c:10029
0xf6664a cpp_diagnostic
../gcc-5.1.0/libcpp/errors.c:60
0xf66776 cpp_error(cpp_reader*, int, char const*, ...)
../gcc-5.1.0/libcpp/errors.c:75
0xf74158 builtin_macro
../gcc-5.1.0/libcpp/macro.c:471
0xf748ed enter_macro_context
../gcc-5.1.0/libcpp/macro.c:1247
0xf7643d cpp_get_token_1
../gcc-5.1.0/libcpp/macro.c:2526
0x65830f scan_translation_unit
../gcc-5.1.0/gcc/c-family/c-ppoutput.c:192
0x65830f preprocess_file(cpp_reader*)
../gcc-5.1.0/gcc/c-family/c-ppoutput.c:113
0x656c80 c_common_init()
../gcc-5.1.0/gcc/c-family/c-opts.c:1033
0x5cb33e lang_dependent_init
../gcc-5.1.0/gcc/toplev.c:1845
0x5cb33e do_compile
../gcc-5.1.0/gcc/toplev.c:2062
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
const char filename[] =


[Bug preprocessor/66318] New: Error messages contain raw file name; malicious #line directives can do bad things

2015-05-27 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66318

Bug ID: 66318
   Summary: Error messages contain raw file name; malicious #line
directives can do bad things
   Product: gcc
   Version: 5.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: preprocessor
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com
  Target Milestone: ---

Error messages include the (presumed) name of the source file in which
the error was detected. The #line directive can set the presumed file name
to nearly any arbitrary string, possibly including control characters.

A directive like:

#line __LINE__ "beep\a.c"

can cause every printed error message to beep.  More malicious #line
directives can cause even more obnoxious behavior.

The sample file shown below, when fed through the preprocessor (either
directly or via the "gcc" command), will change the screen foreground
to green and the background to red if the command is run under xterm.

Depending on which terminal emulator is being used and how it's
configured, it might even be possible to trigger arbitrary code execution
just by compiling a source file.

System: Linux Mint 17.
gcc version 5.1.0, built from source with:
gcc-5.1.0/configure --prefix=/usr/local/apps/gcc-5.1.0 --disable-multilib

Test case (a 2 line source file named "red_green.c"):
#line __LINE__ "'\x1b]10;green\a\x1b]11;red\a'"
#error "Argh! My eyes!"

Output of "cpp red_green.c 2>&1 | cat -A":
'^[]10;green^G^[]11;red^G':1:2: error: #error "Argh! My eyes!"$
# 1 "red_green.c"$
# 1 ""$
# 1 ""$
# 1 "/usr/include/stdc-predef.h" 1 3 4$
# 1 "" 2$
# 1 "red_green.c"$
# 1 "'^[]10;green^G^[]11;red^G'"$

See the "xtermcontrol" command for other possibilities. Even if
arbitrary command execution isn't possible, maximizing the current
window and rapidly alternating between red and green would be at least
seriously annoying, and at worst potentially dangerous to epileptics
(the latter is speculation on my part).

Suggested fix: Sanitize the displayed file name for error messages so
only printable characters are displayed (presumably affected by the
current locale).


[Bug preprocessor/66318] Error messages contain raw file name; malicious #line directives can do bad things

2015-05-27 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66318

--- Comment #2 from Keith Thompson  ---
Martin:

Good point.  I don't suggest altering the string to which the __FILE__
macro expands, merely sanitizing file names to be displayed in error
messages.

I see my original description wasn't 100% clear.

If you execute

cpp red_green.c

or

gcc -E red_green.c

the preprocessed output goes to stdout. If it includes ugly garbage,
well, that's what you asked for. The error message goes to stderr;
I'm suggesting sanitizing that.

If you execute

gcc -c red_green.c

the preprocessed output is passed to the next phase of the compiler and
is not seen by the user.  I suggest that any diagnostic messages should
be sanitized. There's no requirement for a compiler's diagnostic output
to include any particular content.

I suppose some tools could parse that diagnostic output, and misbehave if
it includes something other than the literal file name.  But I suggest
that if either an actual file name or the value of __FILE__ contains
control characters, the risk of writing those control characters to the
user's terminal exceeds the cost of breaking such tools.

Perhaps an option could be added to print raw file names unconditionally
in diagnostic messages.  It should be turned off by default; otherwise
there's not much point in making a change from the current behavior.
The idea is to protect users who compile possibly malicious source files.


[Bug preprocessor/66318] Error messages contain raw file name; malicious #line directives can do bad things

2015-05-29 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66318

--- Comment #5 from Keith Thompson  ---
Mikhail: Newlines in file names (either the actual file name or via a
#line directive) cause problems with __FILE__, though that particular
problem occurs only if there's an explicit reference to __FILE__.

See Bugzilla ticket #66317.


[Bug c++/59945] New: "uint" typedef is visible with "g++ -std=c++11 -pedantic"

2014-01-25 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59945

Bug ID: 59945
   Summary: "uint" typedef is visible with "g++ -std=c++11
-pedantic"
   Product: gcc
   Version: 4.7.2
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com

If a C++ program includes a standard header (I use  in my example), a
typedef

typedef unsigned int uint;

becomes visible. The identifier does not appear in the 2011 ISO C++ standard.

The problem occurs with "g++ -std=c++11 -pedantic". It does not occur with "g++
-std=c++03 -pedantic".

To demonstrate:

$ cat uint_bug.cpp
#include 
int uint;
int main() { }
$ g++ --version 
g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ g++ -std=c++03 -pedantic -c uint_bug.cpp
$ g++ -std=c++11 -pedantic -c uint_bug.cpp
uint_bug.cpp:2:5: error: ‘int uint’ redeclared as different kind of symbol
In file included from /usr/include/stdlib.h:320:0,
 from /usr/include/c++/4.7/cstdlib:66,
 from /usr/include/c++/4.7/ext/string_conversions.h:37,
 from /usr/include/c++/4.7/bits/basic_string.h:2814,
 from /usr/include/c++/4.7/string:54,
 from uint_bug.cpp:1:
/usr/include/x86_64-linux-gnu/sys/types.h:153:22: error: previous
declaration of ‘typedef unsigned int uint’
$

Running "g++ -std=c++11 -E uint_bug.cpp" shows that the declaration "typedef
int uint;", along with similar declarations for "ushort" and "ulong", appears
in /usr/include/x86_64-linux-gnu/sys/types.h. Apparently the macro __USE_MISC
is defined. (The same macro appears to be defined with "-std=c++03", but the
problem doesn't occur with that option; I haven't figured out why.)

I'm not sure whether the bug is in the compiler or in the libc headers.

(The same problem occurs with clang++ version 3.4.)

[Bug c++/59945] "uint" typedef is visible with "g++ -std=c++11 -pedantic"

2014-01-25 Thread Keith.S.Thompson at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59945

--- Comment #1 from Keith Thompson  ---
This came up in this question:
http://stackoverflow.com/q/21356275/827263
on Stack Overflow; the original version of the question used "uint" without
declaring it and compiled without error (at least without that error being
flagged).


[Bug c/63611] New: Invalid optimization for "==" on pointers

2014-10-21 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63611

Bug ID: 63611
   Summary: Invalid optimization for "==" on pointers
   Product: gcc
   Version: 4.8.2
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com

"gcc --version" says
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2

"uname -a" says
Linux bomb20 3.13.0-24-generic #47-Ubuntu SMP Fri May 2 23:30:00 UTC 2014
x86_64 x86_64 x86_64 GNU/Linux
(The system is Linux Mint 17, based on Ubuntu 14.04.1 LTS.)

I've created a Gist at
https://gist.github.com/Keith-S-Thompson/60dc069f4823fb1c3209
but of course I'll include the information here.

The C standard's definition of "==" for pointers (N1570 6.5.9 paragraph 6)
says:

Two pointers compare equal if and only if both are null pointers, both
are pointers to the same object (including a pointer to an object and a
subobject at its beginning) or function, both are pointers to one past
the last element of the same array object, or one is a pointer to one
past the end of one array object and the other is a pointer to the start
of a different array object that happens to immediately follow the first
array object in the address space.

which implies that the test program below should print (among other output)
one of the following:
- "y immediately follows x" followed by "ok";
- "x immediately follows y" followed by "ok"; or
- "x and y are not adjacent"

Instead, when compiled with gcc, it prints "inconsistent behavior: ...".

It appears that gcc is assuming that a pointer just past the end of one
declared object cannot be equal to a pointer to the beginning of another
object, when the two objects are not subobjects of the same containing
object. Examining an assembly listing indicates that the code to print
"ok" is not even generated, implying that this is an optimization bug
(that occurs even at "-O0".

I don't expect that this is a common use case, but the compiled program
does behave in a manner inconsistent with the standard's requirements.

I see the same behavior with a copy of gcc 4.9.1 built from source on the
same system.  (I also see it with clang 3.5-1ubuntu1, but with the order
of x and y reversed; that's not directly relevant to this bug report,
but it's mildly interesting.)

The command line used to compile and execute the program is:

$ gcc -std=c11 -pedantic -Wall -Wextra pointer_equality_bug.c -o
pointer_equality_bug && ./pointer_equality_bug

The output on my system is:

x  = 0x7fff2a94a1d0
x0 = 0x7fff2a94a1d0
x1 = 0x7fff2a94a250
y  = 0x7fff2a94a250
y0 = 0x7fff2a94a250
y1 = 0x7fff2a94a2d0
y immediately follows x
inconsistent behavior:
0x7fff2a94a250 !=
0x7fff2a94a250

And the program itself (73 lines, making up the remainder of this description)
is:

#include 
#include 
int main(void) {
typedef struct {
int arr[32];
} element;
element x[1];
element y[1];
element *const x0 = x;
element *const x1 = x0 + 1;
element *const y0 = y;
element *const y1 = y0 + 1;

/*
 * x and y will typically be adjacent in memory.
 * x0 points to x; x1 points just past it.
 * y0 points to y; y1 points just past it.
 * We should have x1 == y0 if and only if y immediately follows x.
 * We should have y1 == x0 if and only if x immediately follows y.
 */

printf("x  = %p\nx0 = %p\nx1 = %p\ny  = %p\ny0 = %p\ny1 = %p\n",
   (void*)x, (void*)x0, (void*)x1,
   (void*)y, (void*)y0, (void*)y1);

if (x1 == y0) {
puts("y immediately follows x");
if (x + 1 == y) {
puts("ok");
}
else if (x + 1 != y) {
printf("inconsistent behavior:\n"
   "%p !=\n"
   "%p\n",
   (void*)(x + 1),
   (void*)y);
exit(EXIT_FAILURE);
}
else {
printf("inconsistent behavior:\n"
   "%p !=\n"
   "%p\n",
   (void*)(x + 1),
   (void*)y);
exit(EXIT_FAILURE);
}
}
else if (y1 == x0) {
puts("x immediately follows y");
if (y + 1 == x) {
puts("ok");
}
else if (y + 1 != x) {
printf("inconsistent behavior:\n"
   "%p !=\n"
   "%p\n",
   (void*)(y + 1),
   (void*)x);
exit(EXIT_FAILURE);
}
else {
printf("inconsistent behavior:\n"
   "%p !=\n"
   "%p\n",
   (void*)(y + 1),
   (void*)x);
exit(EXIT_FAILURE);
}
}
else {
puts("x and y are not adjacent");
}
}


[Bug c/63611] Invalid optimization for "==" on pointers

2014-10-21 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63611

--- Comment #1 from Keith Thompson  ---
A bug report for a similar issue with clang is here:
http://llvm.org/bugs/show_bug.cgi?id=21327


[Bug tree-optimization/61502] == comparison on "one-past" pointer gives wrong result

2014-10-21 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61502

--- Comment #6 from Keith Thompson  ---
In the test case for Bug 63611 (marked as a duplicate of this one)
we have:

element x[1];
element y[1];
element *const x0 = x;
element *const x1 = x0 + 1;
element *const y0 = y;

When the test case is executed, the condition (x1 == y0) is true
when it's evaluated, but the condition (x + 1 == y) (which I argue is
equivalent) is false when it's evaluated 2 lines later.

I don't believe that DR#260 applies, since there are no indeterminate
values being used here.  Which means, I think, that N1570 6.2.4p2:

An object exists, has a constant address, and retains its
last-stored value throughout its lifetime.

does apply.

Whether x follows y or y follows x in memory, or neither, is 
unimportant.  The problem is that the "==" comparison is behaving
inconsistently for the same two pointer values.

I'm unconvinced by the argument (if I understand it correctly) that 
the objects x and y might be adjacent when the first comparison is
evaluated, but not when the second is evaluated.  I believe that would
violate the requirement that objects have constant addresses and retain
their last-stored values.  Furthermore, even if relocating objects so
they're no long adjacent is permitted by the language, I don't believe
gcc (or the code that it generates) is actually doing so in this case.


[Bug tree-optimization/61502] == comparison on "one-past" pointer gives wrong result

2014-10-21 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61502

--- Comment #8 from Keith Thompson  ---
I'm not (deliberately) considering anything other than the requirements
of the C standard.

The standard talks about an array object immediately following another
array object in the address space. Since that phrase is used in
normative wording in the standard, I presume it's meaningful.  Since
the term is not otherwise defined, I presume that the intended meaning
is one that follows reasonably clearly from the wording.

The test program for Bug 63611, when I execute it, prints the string
"y immediately follows x", followed by the string "inconsistent behavior:".

Are you saying it's possible that y immediately follows x in the
address space when that line of output is printed, and that y *doesn't*
immediately follow x in the address space when "inconsistent behavior:"
is printed?

If so, can you describe what the word "follows" means in this context?
If it has a meaning that permits such behavior, can you cite a source
that indicates that that's how the authors of the standard meant it?


[Bug tree-optimization/61502] == comparison on "one-past" pointer gives wrong result

2014-10-21 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61502

--- Comment #10 from Keith Thompson  ---
I strongly disagree with your interpretation.

Do you believe that the authors of the standard meant it the way you do?

I suggest that the footnote:

> Two objects may be adjacent in memory because they are adjacent elements
> of a larger array or adjacent members of a structure with no padding
> between them, or because the implementation chose to place them so,
> even though they are unrelated.

implies that the phrase "adjacent in memory" (which appears to
be synonymous with "immediately following in the address space") is
intended to have a *consistent* meaning, even for unrelated objects.
Two given objects may or may not be adjacent, and if they are adjacent
they may appear in either order, entirely at the whim of the compiler.
But I don't see a reasonable interpretation of the standard's wording
that doesn't require "==" to behave consistently. Indeed, I believe
that consistency (which gcc lacks) is the whole point of that wording.

Any two pointer values are either equal or unequal. In the test program,
the pointer values do not change, but they compare both equal and unequal
at different points in the code. In my opinion, that's a clear violation
of the required semantics.

And I don't believe you've fullyl answered my question about what is meant
by "follows", at least not fully. I agree with you about the meaning
for objects that are subobjects of some larger object, but for other cases
you've essentially said that it's meaningless. I actually would have no
problem with that, and I wouldn't complain if the standard left it
unspecified -- but it doesn't.


[Bug tree-optimization/61502] == comparison on "one-past" pointer gives wrong result

2014-10-26 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61502

--- Comment #14 from Keith Thompson  ---
The C standard requires that, if y "happens to immediately follow"
x in the address space, then a pointer just past the end of x shall
compare equal to a pointer to the beginning of y (C99 and C11 6.5.9p6).

How could I distinguish the current behavior of gcc from the behavior
of a hypothetical C compiler that violates that requirement? In
other words, in what sense does gcc actually obey that requirement?

Or is it your position that the requirement is so vague that it
cannot meaningfully be followed? If so, have you followed up with
the standard committee to clarify or remove it?


[Bug c/23087] Misleading warning, "... differ in signedness"

2016-01-05 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=23087

Keith Thompson  changed:

   What|Removed |Added

Version|4.0.0   |5.3.0

--- Comment #13 from Keith Thompson  ---
This problem still exists in gcc 5.3.0.

Here's a perhaps clearer example that doesn't depend on string literals,
and that demonstrates the problem both when plain char is signed
and when it's unsigned.

$ cat tmp.c
#include 
void foo(void) {
char *pc = 0;
#if CHAR_MIN < 0
/* plain char is signed but incompatible with signed char */
signed char *psc = pc;
#else
/* plain char is unsigned but incompatible with unsigned char */
unsigned char *puc = pc;
#endif
}
$ gcc --version
gcc (GCC) 5.3.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ gcc -std=c11 -pedantic-errors -c tmp.c
tmp.c: In function 'foo':
tmp.c:6:24: error: pointer targets in initialization differ in signedness
[-Wpointer-sign]
 signed char *psc = pc;
^
$ gcc -std=c11 -pedantic-errors -c -funsigned-char tmp.c
tmp.c: In function 'foo':
tmp.c:9:26: error: pointer targets in initialization differ in signedness
[-Wpointer-sign]
 unsigned char *puc = pc;
  ^
$

[Bug c/23087] Misleading warning, "... differ in signedness"

2016-01-11 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=23087

--- Comment #17 from Keith Thompson  ---
I just took a quick look at the discussion on the gcc-patches mailing
list.

It's true that the standard doesn't classify plain "char" either as a
signed integer type or as an unsigned integer type.

But I think that 99% of users think of plain "char" as either signed
or unsigned, not some third kind of signedness. If plain "char" has the
same range as "signed char", saying that they "differ in signedness" is
just confusing.  (Even to me, and I read ISO language standards for fun.)

And really, the signedness is not the issue.  The issue is that they're
incompatible types.

I'll also note the documentation of the "-fsigned-char" option:

Let the type 'char' be signed, like 'signed char'.

It's difficult to tell uses that plain char is not signed when gcc's
own documentation says it is.

I understand that you might not want to warn about assigning a "signed
char*" value to a "char* object in the same circumstances where you'd warn
about assigning an "int*" to a "long*".  (Both are constraint violations,
but that's another kettle of fish.)

Perhaps char* vs. signed char* or char* vs. unsigned char* needs to be
treated as a special case. But I still say that the existing warning is
misleading and at least needs to be rephrased.

[Bug c/66618] New: Failure to diagnose non-constant initializer for static object with -O1

2015-06-21 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66618

Bug ID: 66618
   Summary: Failure to diagnose non-constant initializer for
static object with -O1
   Product: gcc
   Version: 4.8.4
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com
  Target Milestone: ---

$ uname -a
Linux m5 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64
x86_64 x86_64 GNU/Linux
$ gcc --version | head -n 1
gcc (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4
$ cat bug.c
int main(void) {
const int not_a_constant = 0;
static int n = not_a_constant; /* constraint violation */
return n;  /* avoid unused variable warning */
}
$ gcc -O0 -c -std=c11 -pedantic-errors -Wall -Wextra bug.c
bug.c: In function ‘main’:
bug.c:3:5: error: initializer element is not constant
 static int n = not_a_constant; /* constraint violation */
 ^
$ gcc -O1 -c -std=c11 -pedantic-errors -Wall -Wextra bug.c
$ 

In the test program "bug.c", the object "not_a_constant" is defined as "const",
but its name is not a constant expression. The initializer for a static
expression must be a constant expression; using a non-constant expression is a
constraint violation, requiring a diagnostic (N1570 6.7.9p4).

With "-O0", gcc correctly diagnoses this. I see the same problem with "-O1",
"-O2", and "-O3", and with "-std=c90", "-std=c99", and "-std=c11".

This is based on a question posted to Stack Overflow:
http://stackoverflow.com/q/30962512/827263
by user "meet". Grzegorz Szpetkowski gets the credit for realizing that the
"-O" option triggers the bug.

[Bug c/66618] Failure to diagnose non-constant initializer for static object with -O1

2015-06-30 Thread Keith.S.Thompson at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66618

--- Comment #3 from Keith Thompson  ---
It would be easier to argue that gcc accepts "other forms of constant 
expressions" if (a) those other forms were documented and (b) they were
accepted at all optimization levels.

Admittedly the standard doesn't seem to require such documentation (which I
find a little surprising), and you could argue that "gcc -O0" and "gcc -O1" are
two different implementations.


[Bug c/108531] New: Imaginary types are not supported, violating ISO C Annex G

2023-01-24 Thread Keith.S.Thompson at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108531

Bug ID: 108531
   Summary: Imaginary types are not supported, violating ISO C
Annex G
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com
  Target Milestone: ---

#include 
#include 
int main(void) {
#ifdef __STDC_IEC_559_COMPLEX__
printf("__STDC_IEC_559_COMPLEX__ is defined as %d\n",
__STDC_IEC_559_COMPLEX__);
#else
printf("__STDC_IEC_559_COMPLEX__ is NOT defined\n");
#endif

#ifdef _Imaginary_I
printf("Imaginary types are supported\n");
#else
printf("Imaginary types are NOT supported\n");
#endif
}

The output of this program, when compiled with
"gcc -Wall -Wextra -std=c11 -pedantic-errors"
is:

__STDC_IEC_559_COMPLEX__ is defined as 1
Imaginary types are NOT supported

ISO C Annex G was informative in C99, but was made normative in C11. 
Imaginary types are optional in C11, but are mandatory for any
implementation that predefines __STDC_IEC_559_COMPLEX__.
(Complex types were made optional in C11, but that's not relevant here.)

To conform to C11 (and later), gcc should either implement imaginary types
as defined in Annex G or remove the definition of __STDC_IEC_559_COMPLEX__.

[Bug c/108531] Imaginary types are not supported, violating ISO C Annex G

2023-01-24 Thread Keith.S.Thompson at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108531

--- Comment #1 from Keith Thompson  ---
After I submitted this, I found that this is probably a duplicate of:

https://sourceware.org/bugzilla/show_bug.cgi?id=15720

(I disagree with the resolution of that bug report.)

[Bug c/108531] Imaginary types are not supported, violating ISO C Annex G

2023-01-24 Thread Keith.S.Thompson at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108531

--- Comment #3 from Keith Thompson  ---
In the latest C2X draft,
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3054.pdf
Annex G still requires imaginary number support for any implementation
that defines __STDC_IEC_60559_COMPLEX__ or __STDC_IEC_559_COMPLEX__.

I don't see anything relevant in TS 18661-1
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2314.pdf

[Bug c/108531] Imaginary types are not supported, violating ISO C Annex G

2023-01-25 Thread Keith.S.Thompson at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108531

--- Comment #5 from Keith Thompson  ---
FYI, I've sent an email to the C standard editors (the addresses at
the top of the N3054 draft) suggesting that imaginary number support
should be optional even if __STDC_IEC_559_COMPLEX__ and
__STDC_IEC_60559_COMPLEX__ are defined.

It's probably too late to make such a change in C23.

(__STDC_IEC_60559_COMPLEX__ is replacing __STDC_IEC_559_COMPLEX__,
which is obsolescent.)

[Bug c/108986] New: Incorrect warning for [static] array parameter

2023-03-01 Thread Keith.S.Thompson at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108986

Bug ID: 108986
   Summary: Incorrect warning for [static] array parameter
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com
  Target Milestone: ---

When a parameter is declared with the (new in C99) [static] syntax, and
the argument is a null pointer, the warning incorrectly refers to the
expected size in bytes of the parameter rather than to its length.

That by itself might be annoying but not incorrect, but the warning
includes C syntax that is inconsistent with the actual declaration.

(When the argument is an array object that's too short, the warning
is different. It also refers to a size in bytes, and IMHO referring
to the length would be clearer. Details to follow in a comment.)

$ cat c.c
#include 

void f(int a[static 7]) { }

int main(void) {
f(NULL);
}
$ gcc --version | head -n 1
gcc (GCC) 12.2.0
$ gcc -Wall -c c.c 
c.c: In function ‘main’:
c.c:6:5: warning: argument 1 to ‘int[static 28]’ is null where non-null
expected [-Wnonnull]
6 | f(NULL);
  | ^~~
c.c:3:6: note: in a call to function ‘f’
3 | void f(int a[static 7]) { }
  |  ^
c.c:6:5: warning: argument 1 to ‘int[static 28]’ is null where non-null
expected [-Wnonnull]
6 | f(NULL);
  | ^~~
c.c:3:6: note: in a call to function ‘f’
3 | void f(int a[static 7]) { }
  |  ^
$

[Bug c/108986] Incorrect warning for [static] array parameter

2023-03-01 Thread Keith.S.Thompson at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108986

--- Comment #1 from Keith Thompson  ---
A similar case. The warning refers to the size in bytes, but unlike
the first case it's not incorrect, though referring to the length
would IMHO be clearer.

Note also that the warning appears twice. It only appears once in gcc 11.2.0.

Let me know if I should submit a new bug report for this.

$ cat c.c
#include 

void f(int a[static 7]) { }

int main(void) {
f(NULL);
}
$ /o/apps/gcc-12.2.0/bin/gcc --version | head -n 1
gcc (GCC) 12.2.0
$ /o/apps/gcc-12.2.0/bin/gcc -Wall -c c.c
c.c: In function ‘main’:
c.c:6:5: warning: argument 1 to ‘int[static 28]’ is null where non-null
expected [-Wnonnull]
6 | f(NULL);
  | ^~~
c.c:3:6: note: in a call to function ‘f’
3 | void f(int a[static 7]) { }
  |  ^
c.c:6:5: warning: argument 1 to ‘int[static 28]’ is null where non-null
expected [-Wnonnull]
6 | f(NULL);
  | ^~~
c.c:3:6: note: in a call to function ‘f’
3 | void f(int a[static 7]) { }
  |  ^
$

[Bug c/105156] New: No diagnostic for `enum { toobig = UINT_MAX }`

2022-04-04 Thread Keith.S.Thompson at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105156

Bug ID: 105156
   Summary: No diagnostic for `enum { toobig = UINT_MAX }`
   Product: gcc
   Version: 11.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com
  Target Milestone: ---

Source file:
```
#include 
enum { toobig = UINT_MAX };
```

gcc version 11.2.0 on Ubuntu 20.04.4, x86_64

INT_MAX is 2147483647
UINT_MAX is 4294967295

The C11 and C17 standards both have the following constraint in 6.7.2.2:

> The expression that defines the value of an enumeration constant shall
> be an integer constant expression that has a value representable as an int.

"gcc -std=c17 -pedantic-errors -c c.c" does not produce a diagnostic for the
above source file.

If I replace UINT_MAX by 4294967295 I get a correct diagnostic:
c.c:3:18: error: ISO C restricts enumerator values to range of ‘int’
[-Wpedantic]
3 | enum { toobig2 = 4294967295 };
  | 

"gcc -E" indicates that the macro UINT_MAX expands to (0x7fff * 2U + 1U)

[Bug c/105156] No diagnostic for `enum { toobig = UINT_MAX }`

2022-04-04 Thread Keith.S.Thompson at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105156

--- Comment #2 from Keith Thompson  ---
Andrew, did you use "-std=c17 -pedantic-errors"? Both gcc and clang
correctly diagnose "enum { toobig = 0x7fff * 2U + 1U };".

I'm seeing weird behavior that I don't understand. Replacing the UINT_MAX
macro by its expansion seems to change the behavior. Perhaps I'm missing
something obvious?

$ gcc --version
gcc (GCC) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ cat -n c.c
 1  #include 
 2  enum { toobig= (0x7fff * 2U + 1U) };
 3  enum { toobigtoo = UINT_MAX };
$ gcc -std=c17 -pedantic-errors -c c.c
c.c:2:20: error: ISO C restricts enumerator values to range of ‘int’
[-Wpedantic]
2 | enum { toobig= (0x7fff * 2U + 1U) };
  |^
$ gcc -E c.c | tail -n 6
enum { toobig = (0x7fff * 2U + 1U) };
enum { toobigtoo =
# 3 "c.c" 3 4
  (0x7fff * 2U + 1U)
# 3 "c.c"
   };
$

[Bug c/105156] No diagnostic for `enum { toobig = UINT_MAX }`

2022-04-04 Thread Keith.S.Thompson at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105156

--- Comment #4 from Keith Thompson  ---
OK, that explains the bug.

It sounds like the code that suppresses warnings in system headers needs
to be a bit more clever. Using UINT_MAX here isn't an error in the header.

[Bug c/107091] New: Misleading error message "incompatible types when returning ..."

2022-09-29 Thread Keith.S.Thompson at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107091

Bug ID: 107091
   Summary: Misleading error message "incompatible types when
returning ..."
   Product: gcc
   Version: 12.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Keith.S.Thompson at gmail dot com
  Target Milestone: ---

When I compile this source file:

double bad(void) {
return (void*)0;
}

double good(void) {
return 42;
}

I get this output from gcc 12.2.0 (and from earlier versions):

c.c: In function ‘bad’:
c.c:2:12: error: incompatible types when returning type ‘void *’ but ‘double’
was expected
2 | return (void*)0;
  |^

It's true that it's a constraint violation, and it's true that void* and double
are incompatible, but type compatibility is not required here. The problem is
that there is no implicit conversion from void* to double.

In the "good" function, int and double are also incompatible types, but there
is an implicit conversion so the statement is valid.

Note that g++ produces this correct message for the equivalent C++ code:

c.cpp: In function ‘double bad()’:
c.cpp:2:19: error: cannot convert ‘void*’ to ‘double’ in return
2 | return (void*)0;
  |  

This was brought to my attention by this post on Stack Overflow:
https://stackoverflow.com/q/73899947/827263

Reference for compatible types: C11 (or N1570) 6.2.7.