[Bug c/94142] New: typeof enum member appears to give wrong signedness

2020-03-11 Thread matthew.fernandez at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94142

Bug ID: 94142
   Summary: typeof enum member appears to give wrong signedness
   Product: gcc
   Version: 9.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: matthew.fernandez at gmail dot com
  Target Milestone: ---

Consider the following code:

typedef enum { A, B } t;
t x;
__typeof__(A) y;

int foo() {
  if (x == y)
return 0;

  return 1;
}

With GCC 9.2.0, compiling with -Wsign-compare has the following to say:

$ gcc-9.2.0 -std=gnu11 -c -Wsign-compare goo.c
foo.c: In function 'foo':
foo.c:6:9: warning: comparison of integer expressions of different
sightedness: 't' {aka 'enum '} and 'int' [-Wsign-compare]
6 |   if (x == y)
  | ^~

This seems surprising to me. Shouldn't x and y have the same signedness as
they're both the type of the enum? It seems like somehow the type of an enum
member differs from the type of the enum itself. Either way, the warning seems
spurious here. Maybe #66773 is relevant.

Some cursory testing suggests to me this behaviour extends back to at least the
GCC 4 series. I could not find a version of Clang that has this behaviour.

[Bug c/94142] typeof enum member appears to give wrong signedness

2020-03-11 Thread matthew.fernandez at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94142

Matthew Fernandez  changed:

   What|Removed |Added

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

--- Comment #2 from Matthew Fernandez  ---
Ah I see. I had missed the subtlety in the standard there. Thanks for
explaining and for the pointer to the docs, Jonathan. I'll close as INVALID.

[Bug c++/82873] New: Generated copy constructor calls constructors for 0-sized array members

2017-11-06 Thread matthew.fernandez at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82873

Bug ID: 82873
   Summary: Generated copy constructor calls constructors for
0-sized array members
   Product: gcc
   Version: 7.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: matthew.fernandez at gmail dot com
  Target Milestone: ---

Hello there, I'm trying to do something a little unorthodox and ran into an
undefined reference during linking. It appears that a generated copy
constructor calls another copy constructor that itself is not generated. A
minimised example is:

#include 

class Foo {
  std::vector x[0];
};

int main(void) {
  Foo a;
  Foo b(a);
  return 0;
}

Compiling this yields:

$ g++ -std=c++17 -W -Wall -Wextra main.cc
/tmp/ccfexx8L.o: In function `Foo::Foo(Foo const&)':
main.cc:(.text._ZN3FooC2ERKS_[_ZN3FooC5ERKS_]+0x35): undefined reference to
`std::vector >::vector(std::vector > const&)'

It seems this is related to the 0-sized array member, which I realise is
non-standard (https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html). Making the
array member size 1 results in the relevant vector copy constructor being
generated, as does inserting the following otherwise-useless code into the
translation unit:

static inline std::vector dummy(const std::vector &p) {
  return p;
}

This behaviour surprised me because I expected GCC to either (1) emit a compile
error or (2) generate the relevant constructors. Is this known/expected
behaviour?

Possibly of relevance PR 42121 and PR 14799.

[Bug c++/82873] Generated copy constructor calls constructors for 0-sized array members

2017-11-06 Thread matthew.fernandez at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82873

--- Comment #1 from Matthew Fernandez  ---
Sorry, that was meant to be PR 14779, not 14799.

[Bug libgcc/67902] New: Undefined negation in __divdi3

2015-10-08 Thread matthew.fernandez at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67902

Bug ID: 67902
   Summary: Undefined negation in __divdi3
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libgcc
  Assignee: unassigned at gcc dot gnu.org
  Reporter: matthew.fernandez at gmail dot com
CC: joseph at codesourcery dot com
  Target Milestone: ---

As discussed on the GCC list, I believe the function __divdi3 performs a signed
negation that may be undefined behaviour.

In more detail: AIUI, signed 64-bit division can be emitted as a call to
software emulation in libgcc when the current target has no native hardware
support. For example, on 32-bit x86 this can mean signed 64-bit division
becomes a call to __divdi3. Internally, this function negates its operands if
they are negative. I believe this negation, in the case when either of the
operands is INT64_MIN is undefined behaviour. This seems to mean that a legal
operation like `INT64_MIN / INT64_MIN` inadvertently causes undefined
behaviour. Thus I believe __divdi3's implementation doesn't strictly comply
with the C standard.

There may be some disagreement about this as presumably GCC does the expected
thing when compiling this code and, as Joseph Myers has pointed out, the
shipped libgcc binaries are probably fine. However, I believe a compiler is
within its rights to transform `x = -x` into:

if (x == INT64_MIN) {
  // nasal demons
} else {
  x = -x;
}

Please let me know if I'm mistaken or if you need more information. If I'm
incorrect, apologies for taking up your time.

GCC commit: 03ca0c3cbd35930b7e08135e5f2ac069db22f7f7