[Bug target/105932] New: Small structures returned incorrectly in i386 Microsoft ABI

2022-06-11 Thread josephcsible at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105932

Bug ID: 105932
   Summary: Small structures returned incorrectly in i386
Microsoft ABI
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Keywords: ABI, wrong-code
  Severity: normal
  Priority: P3
 Component: target
  Assignee: unassigned at gcc dot gnu.org
  Reporter: josephcsible at gmail dot com
  Target Milestone: ---

Consider this C code:

struct foo {
int x, y;
};

extern int x, y;

struct foo f(void) {
struct foo rv;
rv.x = x;
rv.y = y;
return rv;
}

When compiled with "-O2 -m32 -mabi=ms", it compiles to this:

f:
movdx, %xmm0
movl4(%esp), %eax
movdy, %xmm1
punpckldq   %xmm1, %xmm0
movq%xmm0, (%eax)
ret

Which expects to be passed a hidden parameter to hold the address of the return
value. But in the i386 Microsoft ABI, that's not how returns work for POD types
that are 64 bits or smaller. Here's what it should compile to instead:

f:
movdx, %eax
movdy, %edx
ret

[Bug c/105875] New: Toggling an atomic_bool is inefficient

2022-06-07 Thread josephcsible at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105875

Bug ID: 105875
   Summary: Toggling an atomic_bool is inefficient
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Keywords: missed-optimization
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: josephcsible at gmail dot com
  Target Milestone: ---
Target: x86_64-pc-linux-gnu

Consider this C code:

#include 

atomic_bool b;
atomic_char c;
_Bool b2;

void f1(void) {
b ^= 1;
}

void f2(void) {
c ^= 1;
}

void f3(void) {
b2 ^= 1;
}

At -O3, those functions compile into this:

f1:
movzbl  b(%rip), %eax
.L5:
movb%al, -1(%rsp)
xorl$1, %eax
movl%eax, %edx
movzbl  -1(%rsp), %eax
lock cmpxchgb   %dl, b(%rip)
jne .L5
ret
f2:
lock xorb   $1, c(%rip)
ret
f3:
xorb$1, b2(%rip)
ret

The code generated for f1 is inefficient. It should have just done a "lock xorb
  $1, b(%rip)".

[Bug c++/103091] New: Can't jump into scope of a variable with a nontrivial destructor in C++20

2021-11-04 Thread josephcsible at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103091

Bug ID: 103091
   Summary: Can't jump into scope of a variable with a nontrivial
destructor in C++20
   Product: gcc
   Version: 11.2.1
Status: UNCONFIRMED
  Keywords: rejects-valid
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: josephcsible at gmail dot com
  Target Milestone: ---

The C++17 standard says "A program that jumps from a point where a variable
with automatic storage duration is not in scope to a point where it is in scope
is ill-formed unless the variable has scalar type, class type with a trivial
default constructor and a trivial destructor, a cv-qualified version of one of
these types, or an array of one of the preceding types and is declared without
an initializer (11.6)."

The C++20 standard says "A program that jumps from a point where a variable
with automatic storage duration is not in scope to a point where it is in scope
is ill-formed unless the variable has vacuous initialization (6.7.3)." and "A
variable is said to have vacuous initialization if it is default-initialized
and, if it is of class type or a (possibly multi-dimensional) array thereof,
that class type has a trivial default constructor."

Note that the C++17 standard mentions a trivial destructor here, but the C++20
standard does not. Now consider this code:

struct MyStruct {
~MyStruct() {}
};
void foo() {
goto x;
MyStruct s;
x:
return;
}

It's ill-formed in C++17, but fine in C++20. However, we currently reject this
program even with -std=c++20.

[Bug debug/102442] Incorrect debug info for C89-style function parameter

2021-09-24 Thread josephcsible at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102442

Joseph C. Sible  changed:

   What|Removed |Added

 CC||josephcsible at gmail dot com

--- Comment #1 from Joseph C. Sible  ---
I wonder if this is related to fx actually being a float(double) and not a
float(float) as it appears to be.

[Bug c++/101465] New: Poorly worded error from a call to a pointer-to-member function not wrapped in parentheses

2021-07-15 Thread josephcsible at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101465

Bug ID: 101465
   Summary: Poorly worded error from a call to a pointer-to-member
function not wrapped in parentheses
   Product: gcc
   Version: 11.1.0
Status: UNCONFIRMED
  Keywords: diagnostic
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: josephcsible at gmail dot com
  Target Milestone: ---

Consider this C++ code:

struct foo *x;

void (foo::*myfuncptr)();

void f() {
x->*myfuncptr();
}

This fails to compile, as it should. The problem is that the error I get says I
"must use '.*' or '->*' to call pointer-to-member function", even though I'm
already using '->*'. The actual change I need to make is to add parentheses,
like this: "(x->*myfuncptr)();" We should make the error say this instead.

[Bug c/101432] New: NULL dereferences aren't assumed to be unreachable even with -fdelete-null-pointer-checks -fno-isolate-erroneous-paths-dereference

2021-07-12 Thread josephcsible at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101432

Bug ID: 101432
   Summary: NULL dereferences aren't assumed to be unreachable
even with -fdelete-null-pointer-checks
-fno-isolate-erroneous-paths-dereference
   Product: gcc
   Version: 11.1.0
Status: UNCONFIRMED
  Keywords: missed-optimization
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: josephcsible at gmail dot com
  Target Milestone: ---
Target: x86_64-linux-gnu

Consider this C code:

#include 
int f(_Bool x) {
if(x) {
int *null = NULL;
return *null;
} else {
return 42;
}
}

I want this assembly:

f:
movl$42, %eax
ret

But even with -O3 -fdelete-null-pointer-checks
-fno-isolate-erroneous-paths-dereference, I get this assembly:

f:
movl$42, %eax
testb   %dil, %dil
je  .L1
movl0, %eax
.L1:
ret

[Bug c/101358] New: Warn when saving a pointer to an object with temporary lifetime

2021-07-06 Thread josephcsible at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101358

Bug ID: 101358
   Summary: Warn when saving a pointer to an object with temporary
lifetime
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Keywords: diagnostic
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: josephcsible at gmail dot com
  Target Milestone: ---

Consider this C code:

typedef struct {
int x[1];
} foo;

foo f(void);

int g(void) {
int *p = f().x;
return *p;
}

The g() function is always UB, since the return value of f() has temporary
lifetime, so doing "return *p;" is dereferencing a pointer to an object whose
lifetime has ended. (This is the case both before and after C11's change to
temporary lifetime.) Since it's obvious at compile time that p can never be
used safely, we should have a warning for it, similar to how we have
-Wreturn-local-addr to catch mistakes like this function:

int *h(void) {
int x;
return &x;
}

[Bug middle-end/100861] False positive -Wmismatched-new-delete with destroying operator delete

2021-06-01 Thread josephcsible at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100861

--- Comment #2 from Joseph C. Sible  ---
Wait, if it's just checking whether the calls to operator new and operator
delete match up, then why does adding "virtual ~Widget() {}" make the warning
go away?

[Bug c++/100861] New: False positive -Wmismatched-new-delete with destroying operator delete

2021-06-01 Thread josephcsible at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100861

Bug ID: 100861
   Summary: False positive -Wmismatched-new-delete with destroying
operator delete
   Product: gcc
   Version: 12.0
Status: UNCONFIRMED
  Keywords: diagnostic
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: josephcsible at gmail dot com
  Target Milestone: ---

Currently, code like "Base *b = new Derived; delete b;" gives a
-Wmismatched-new-delete warning, unless Base has a virtual destructor. One of
the use cases for C++20's destroying operator delete is to make this safe
without needing a virtual destructor, so this warning should be suppressed if
Base has a destroying operator delete. Here's a modified version of the code at
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0722r1.html that will
unnecessarily cause this warning (compile with -std=c++20 -Wall):

#include 

enum class WidgetKind {
  Grommet,
  Wingnut
};

struct Widget {
  const WidgetKind Kind : 4;
  unsigned OtherThings : 28;

  Widget(WidgetKind k) : Kind(k) {}
  void operator delete(Widget *, std::destroying_delete_t);
};

struct Grommet : Widget {
  Grommet() : Widget(WidgetKind::Grommet) {}
};

struct Wingnut : Widget {
  Wingnut() : Widget(WidgetKind::Wingnut) {}
};

void Widget::operator delete(Widget *widget, std::destroying_delete_t) {
  switch (widget->Kind) {
  case WidgetKind::Grommet:
static_cast(widget)->~Grommet();
::operator delete(widget, sizeof(Grommet));
return;
  case WidgetKind::Wingnut:
static_cast(widget)->~Wingnut();
::operator delete(widget, sizeof(Wingnut));
return;
  }
}

int main() {
  Widget *widget = new Grommet;
  delete widget;
}

[Bug c++/91859] Using destroying delete should not clobber stores to the object

2021-05-19 Thread josephcsible at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91859

--- Comment #5 from Joseph C. Sible  ---
The real problem mentioned in comment 2 still happens as of GCC 11.1. I've
narrowed it down somewhat to the optimization flags "-Og -ftree-dse
-ftree-pta". Removing any one of those will make it behave again.

[Bug c++/97820] New: VLAs in function declarations fail to compile

2020-11-13 Thread josephcsible at gmail dot com via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97820

Bug ID: 97820
   Summary: VLAs in function declarations fail to compile
   Product: gcc
   Version: 10.2.0
Status: UNCONFIRMED
  Keywords: rejects-valid
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: josephcsible at gmail dot com
  Target Milestone: ---

Consider these 4 attempts at declaring a function:

void f1(int rows, int cols, int arr[rows][cols]);
void f2(int rows, int cols, int (*arr)[cols]);
void f3(int, int, int [*][*]);
void f4(int, int, int (*)[*]);

When I compile them with g++, they all have errors:

:1:41: error: use of parameter outside function body before ']' token
1 | void f1(int rows, int cols, int arr[rows][cols]);
  | ^
:1:47: error: use of parameter outside function body before ']' token
1 | void f1(int rows, int cols, int arr[rows][cols]);
  |   ^
:2:44: error: use of parameter outside function body before ']' token
2 | void f2(int rows, int cols, int (*arr)[cols]);
  |^
:3:25: error: expected primary-expression before ']' token
3 | void f3(int, int, int [*][*]);
  | ^
:3:28: error: expected primary-expression before ']' token
3 | void f3(int, int, int [*][*]);
  |^
:4:28: error: expected primary-expression before ']' token
4 | void f4(int, int, int (*)[*]);
  |^

Since we support VLAs in C++ as an extension, I expected that all of these
would work.

https://godbolt.org/z/Wca9ra