[Bug c++/80039] `constexpr` member function calls in a `constexpr` constructor are ignored if the object is defined locally

2021-03-29 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80039

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #1 from David Stone  ---
Here's another reproduction

```
struct s {
int m_value = 0;

constexpr int value() const {
return m_value;
}

constexpr s()
{
value();
m_value = 1;
}
};

constexpr auto x = s();
static_assert(x.value() == 1);
```

Still a problem on trunk.

This example shows it's not just that side effects are ignored, but also that
the return value is cached. My guess is that there is some code path that
memoizes calls to constexpr functions, replacing them with their return value,
and that code is getting invoked when it shouldn't be.

[Bug c++/99018] Comparing address of array element not considered a constant expression in certain contexts

2021-03-10 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99018

--- Comment #2 from David Stone  ---
Simpler test case

```
struct s {
constexpr ~s() {
}
};

constexpr bool f(s const (&)[1]) {
return true;
}

static_assert(f({s()}));
```

Message

```
:10:16: error: non-constant condition for static assertion
   10 | static_assert(f({s()}));
  |   ~^~~
:10:22: error: '(((const s*)(&)) != 0)' is not a constant
expression
   10 | static_assert(f({s()}));
  |  ^
Compiler returned: 1
```

See it live: https://godbolt.org/z/YGYjfh

You can get the same error by making the function parameter
`std::initializer_list` as well. Especially interesting in this reduction is
that the code complains about a comparison, but there is no comparison anywhere
in the code.

[Bug c++/99018] Comparing address of array element not considered a constant expression in certain contexts

2021-02-09 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99018

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #1 from David Stone  ---
Here's a simpler test case

```
struct s {
constexpr ~s() {
if (this) {
}
}
};

constexpr bool f(s (&&)[1]) {
return true;
}

static_assert(f(
{s()}
));
```

Message:

```
:12:16: error: non-constant condition for static assertion
   12 | static_assert(f(
  |   ~^
   13 | {s()}
  | ~   
   14 | ));
  | ~   
:14:1: error: '(((s*)(&)) != 0)' is not a constant
expression
   14 | ));
  | ^
Compiler returned: 1
```

[Bug c++/99031] New: Comparing pointers to heap-allocated memory is not a constant expression

2021-02-09 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99031

Bug ID: 99031
   Summary: Comparing pointers to heap-allocated memory is not a
constant expression
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following valid translation unit

```
constexpr bool f() {
auto a = new int;
auto b = new int;
if (a == b) {
}
delete b;
delete a;
return true;
}

static_assert(f());
```

is rejected with

```
:11:16: error: non-constant condition for static assertion
   11 | static_assert(f());
  |   ~^~
:11:16:   in 'constexpr' expansion of 'f()'
:4:15: error: '(((int*)(& heap )) == ((int*)(& heap )))' is not a
constant expression
4 | if (a == b) {
  | ~~^~~~
Compiler returned: 1
```

See it live: https://godbolt.org/z/of45no

[Bug c++/96333] [10/11 Regression] Regression on concepts constraint checking

2021-02-08 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96333

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #5 from David Stone  ---
*** Bug 98987 has been marked as a duplicate of this bug. ***

[Bug c++/98987] Concept subsumption doesn't work with by-value vs. by-reference parameters

2021-02-08 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98987

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net
 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |DUPLICATE

--- Comment #2 from David Stone  ---
I agree, this is a duplicate of that other issue.

*** This bug has been marked as a duplicate of bug 96333 ***

[Bug c++/99018] New: Comparing address of array element not considered a constant expression in certain contexts

2021-02-08 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99018

Bug ID: 99018
   Summary: Comparing address of array element not considered a
constant expression in certain contexts
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following valid translation unit

```
struct s {
constexpr s() = default;

constexpr s(s const & other) {
if (this == ) {
}
}
};

constexpr auto f() {
s init[2];
for (auto & element : init) {
s foo = element;
}
return true;
}

static_assert(f());
```

is rejected by gcc with

```
:18:16: error: non-constant condition for static assertion
   18 | static_assert(f());
  |   ~^~
:18:16:   in 'constexpr' expansion of 'f()'
:13:11:   in 'constexpr' expansion of 's((*(const s*)(& element)))'
:5:26: error: '(((const s*)(& foo)) == (((const s*)(& init)) + 1))' is
not a constant expression
5 | if (this == ) {
  | ~^
Compiler returned: 1
```

See it live: https://godbolt.org/z/xG5dv5

[Bug c++/99016] New: Internal compiler error from decltype of binary operator when one operand is a prvalue function call

2021-02-08 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99016

Bug ID: 99016
   Summary: Internal compiler error from decltype of binary
operator when one operand is a prvalue function call
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following valid translation unit

```
struct integer {};

integer f();

int operator+(integer, integer);

using max_type = decltype(f() + f());
```

Causes gcc to crash with

```
:7:35: internal compiler error: in build_over_call, at cp/call.c:9244
7 | using max_type = decltype(f() + f());
  |   ^
0x1ce6f09 internal_error(char const*, ...)
???:0
0x6b6f43 fancy_abort(char const*, int, char const*)
???:0
0x6df89c build_new_method_call(tree_node*, tree_node*, vec**, tree_node*, int, tree_node**, int)
???:0
0x6e1000 build_special_member_call(tree_node*, tree_node*, vec**, tree_node*, int, int)
???:0
0x6e2760 build_new_op(op_location_t const&, tree_code, int, tree_node*,
tree_node*, tree_node*, tree_node**, int)
???:0
0x9c121d build_x_binary_op(op_location_t const&, tree_code, tree_node*,
tree_code, tree_node*, tree_code, tree_node**, int)
???:0
0x8de23d c_parse_file()
???:0
0xa5b7c2 c_common_parse_file()
???:0
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
Compiler returned: 1
```

This worked in gcc 10.2. See it live: https://godbolt.org/z/oxj437

[Bug c++/98995] New: Copy elision not applied to members declared with [[no_unique_address]]

2021-02-07 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98995

Bug ID: 98995
   Summary: Copy elision not applied to members declared with
[[no_unique_address]]
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following valid translation unit is rejected by gcc 11:

```
struct non_movable {
non_movable() = default;
non_movable(non_movable &&) = delete;
};

struct wrapper {
constexpr explicit wrapper(auto function):
m(function())
{
}

[[no_unique_address]] non_movable m;
};

constexpr auto w = wrapper{[]{ return non_movable(); }};
```

with the error message

```
: In instantiation of 'constexpr wrapper::wrapper(auto:1) [with auto:1
= ]':
:15:55:   required from here
:8:17: error: use of deleted function
'non_movable::non_movable(non_movable&&)'
8 | m(function())
  | ^
:3:9: note: declared here
3 | non_movable(non_movable &&) = delete;
  | ^~~
Compiler returned: 1
```

See it live: https://godbolt.org/z/o1TbY9

This was accepted in gcc 10.2.

[Bug c++/98994] New: Empty type with [[no_unique_address]] in union with constructor is not a constant expression

2021-02-07 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98994

Bug ID: 98994
   Summary: Empty type with [[no_unique_address]] in union with
constructor is not a constant expression
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following valid translation unit:

```
struct empty {};

union U {
constexpr U():
a()
{
}

[[no_unique_address]] empty a;
};

constexpr U u;
```

is incorrectly rejected by gcc 11 with the error:

```
:12:13: error: 'U()' is not a constant expression
   12 | constexpr U u;
  | ^
:12:13: error: 'U()' is not a constant expression because it refers to
an incompletely initialized variable
Compiler returned: 1
```

See it live: https://godbolt.org/z/PWcco3

This code was accepted in gcc 10.2.

[Bug c++/98990] Internal compiler error when two overloaded functions return `auto &&` and one accepts an `auto` parameter

2021-02-07 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98990

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #1 from David Stone  ---
To trigger this bug, the return type can be declared `auto &&`, `auto const &`,
or `auto &`. If it is `auto` or `decltype(auto)`, the bug is not triggered.
Whichever form is used, the same form must be used for both declarations.

[Bug c++/98990] New: Internal compiler error when two overloaded functions return `auto &&` and one accepts an `auto` parameter

2021-02-07 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98990

Bug ID: 98990
   Summary: Internal compiler error when two overloaded functions
return `auto &&` and one accepts an `auto` parameter
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following valid translation unit

```
constexpr int x = 0;

constexpr auto && f() {
return x;
}
constexpr auto && f(auto) {
return x;
}
```

causes gcc to crash with

```
:6:25: internal compiler error: same canonical type node for different
types 'auto&&' and 'auto&&'
6 | constexpr auto && f(auto) {
  | ^
0x1ce6f09 internal_error(char const*, ...)
???:0
0x9c60ce comptypes(tree_node*, tree_node*, int)
???:0
0x78ef77 decls_match(tree_node*, tree_node*, bool)
???:0
0x7c003c cplus_decl_attributes(tree_node**, tree_node*, int)
???:0
0x79f277 grokdeclarator(cp_declarator const*, cp_decl_specifier_seq*,
decl_context, int, tree_node**)
???:0
0x7a3916 start_function(cp_decl_specifier_seq*, cp_declarator const*,
tree_node*)
???:0
0x8de23d c_parse_file()
???:0
0xa5b7c2 c_common_parse_file()
???:0
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
Compiler returned: 1
```

See it live: https://godbolt.org/z/bnszYo

This code was accepted in gcc 10.2, but it is rejected by the upcoming 11.0.

[Bug c++/98988] New: delete is not a constant expression with -fsanitize=undefined

2021-02-07 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98988

Bug ID: 98988
   Summary: delete is not a constant expression with
-fsanitize=undefined
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following valid translation unit:

```
constexpr bool f() {
auto ptr = new int();
delete ptr;
return true;
}

static_assert(f());
```

is incorrectly rejected when compiled with `-fsanitize=undefined`, complaining
about

```
:7:16: error: non-constant condition for static assertion
7 | static_assert(f());
  |   ~^~
:7:16:   in 'constexpr' expansion of 'f()'
:3:9: error: '(((int*)(& heap )) != 0)' is not a constant expression
3 | delete ptr;
  | ^~
Compiler returned: 1
```

See it live: https://godbolt.org/z/Yf67G7

[Bug c++/79751] Concept placeholder on another concept does not work

2021-02-07 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79751

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #2 from David Stone  ---
Resolved in gcc 10.1. It now correctly rejects this code.

[Bug c++/98987] New: Concept subsumption doesn't work with by-value vs. by-reference parameters

2021-02-07 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98987

Bug ID: 98987
   Summary: Concept subsumption doesn't work with by-value vs.
by-reference parameters
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following translation unit

```
template
concept A = true;

template
concept B = A and true;

constexpr bool f(A auto) {
return false;
}

constexpr bool f(B auto const &) {
return true;
}

static_assert(f(0));
```

should compile successfully. Instead, gcc reports

```
:15:18: error: call of overloaded 'f(int)' is ambiguous
   15 | static_assert(f(0));
  |  ^
:7:16: note: candidate: 'constexpr bool f(auto:1) [with auto:1 = int]'
7 | constexpr bool f(A auto) {
  |^
:11:16: note: candidate: 'constexpr bool f(const auto:2&) [with auto:2
= int]'
   11 | constexpr bool f(B auto const &) {
  |^
Compiler returned: 1
```

Changing the first `f` overload to accept `A auto const &` or changing the
second to accept `B auto` resolves the ambiguity error.

See it live: https://godbolt.org/z/9aYo64

[Bug tree-optimization/80738] dead first stmt in a=0;a=b;b=0 whatever the aliasing

2020-12-14 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80738

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #6 from David Stone  ---
All of the standard library types in C++ have a hand-written version of
std::swap to work around the problem. Fundamental types do not need anything
set to 0 in the middle so they don't show the problem. The simplest case to
show this would probably be a struct containing a unique_ptr (although it
applies to any resource-owning type that doesn't have a swap written
specifically for it):

```
#include 
#include 

struct wrapper {
std::unique_ptr ptr;
};

void slow(wrapper & lhs, wrapper & rhs) {
std::swap(lhs, rhs);
}

void fast(wrapper & lhs, wrapper & rhs) {
std::swap(lhs.ptr, rhs.ptr);
}
```

At `-O3`, this generates the assembly

```
slow(wrapper&, wrapper&):
mov rax, QWORD PTR [rdi]
mov QWORD PTR [rdi], 0
mov rdx, QWORD PTR [rsi]
mov QWORD PTR [rsi], 0
mov QWORD PTR [rdi], rdx
mov rdi, QWORD PTR [rsi]
mov QWORD PTR [rsi], rax
testrdi, rdi
je  .L1
mov esi, 4
jmp operator delete(void*, unsigned long)
.L1:
ret
fast(wrapper&, wrapper&):
mov rax, QWORD PTR [rdi]
mov rdx, QWORD PTR [rsi]
mov QWORD PTR [rdi], rdx
mov QWORD PTR [rsi], rax
ret
```

Where `fast` is better only because the C++ standard library maintainers
hand-wrote a faster version.

[Bug c++/97388] constexpr evaluator incorrectly claims double delete with function parameter

2020-10-12 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97388

--- Comment #2 from David Stone  ---
That is what seems to be happening here. It looks like by-value function
parameters have all modifications rolled back before the object is destroyed.
The following code is also erroneously rejected:

```
struct S {
int m;

constexpr S():
m(1)
{
}
constexpr ~S() noexcept(false) {
if (m == 1) {
throw;
}
}
};

constexpr bool test(S v) {
v.m = 2;
return true;
}

static_assert(test(S()));
```

See it live: https://godbolt.org/z/qMjEfo

[Bug c++/97388] constexpr evaluator incorrectly claims double delete with function parameter

2020-10-12 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97388

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #1 from David Stone  ---
This seems like it could be the same issue. The following code should be
rejected, but it's accepted.

```
#include 

struct S {
int * m_ptr;

constexpr S():
m_ptr(new int)
{
}
S(const S&) = delete;
S& operator=(const S&) = delete;
constexpr ~S() {
delete m_ptr;
}
};

constexpr bool test(S v) {
v.m_ptr = nullptr;
return true;
}

static_assert(test(S()));
```

Here, we have a memory leak that fails to be reported. It seems like changes to
by-value function parameters are not maintained for the destructor?

[Bug c++/97388] New: constexpr evaluator incorrectly claims double delete with function parameter

2020-10-12 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97388

Bug ID: 97388
   Summary: constexpr evaluator incorrectly claims double delete
with function parameter
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following translation unit

```
struct S {
int * m_ptr;

constexpr S():
m_ptr(new int())
{
}
constexpr S(S && other) noexcept:
m_ptr(other.m_ptr)
{
other.m_ptr = nullptr;
}
constexpr ~S() noexcept {
delete m_ptr;
}
};

constexpr bool test(S v) {
auto x = static_cast(v);
return true;
}

static_assert(test(S()));
```

is rejected with 

```
:23:19: error: non-constant condition for static assertion

   23 | static_assert(test(S()));

  |   ^

Compiler returned: 1
```

This problem does not occur if `v` is turned into a local variable instead of a
function parameter.

The error message is also not helpful in this case. It gives a much more
helpful (but still erroneous) error message if `std::allocator` is used instead
of `new` and `delete`:

```
:28:19: error: non-constant condition for static assertion

   28 | static_assert(test(S()));

  |   ^

In file included from
/opt/compiler-explorer/gcc-trunk-20201012/include/c++/11.0.0/memory:64,

 from :1:

:28:25:   in 'constexpr' expansion of '(&)->S::~S()'

:17:36:   in 'constexpr' expansion of
'std::allocator().std::allocator::deallocate(((S*)this)->S::m_ptr,
1)'

/opt/compiler-explorer/gcc-trunk-20201012/include/c++/11.0.0/bits/allocator.h:183:30:
error: deallocation of already deallocated storage

  183 | ::operator delete(__p);

  | ~^

Compiler returned: 1
```

See it live: https://godbolt.org/z/hcv88h

[Bug c++/97052] Internal compiler error with substitution failure in template parameter list of concept declaration

2020-10-01 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97052

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #2 from David Stone  ---
Turns out the substitution failure is a red herring. Here is a simpler
reproduction:

```
template
concept foo = true;

void f(foo auto) {
}
```

[Bug c++/97195] construct_at on a union member is not a constant expression

2020-09-27 Thread david at doublewise dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97195

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #1 from David Stone  ---
This is actually a broader bug in construct_at, unrelated to unions:


```
#include 

constexpr bool test() {
int a = 5;
std::construct_at(
,
-1
);
return true;
}
constexpr bool b = test();
```

is also rejected. See it live: https://godbolt.org/z/KWK8n1

The real problem here appears to be that std::construct_at is not a constant
expression for values with non-constant addresses. The following code, for
example, is accepted:

```
#include 

struct S {
constexpr S() {
std::construct_at(
,
-1
);
}

int m;
};

constexpr S s;
```

See it live: https://godbolt.org/z/Wdx9Kx

[Bug c++/97052] New: Internal compiler error with substitution failure in template parameter list of concept declaration

2020-09-14 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97052

Bug ID: 97052
   Summary: Internal compiler error with substitution failure in
template parameter list of concept declaration
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following code

```
template
concept foo = true;

constexpr bool f(foo auto) {
return false;
}

constexpr bool f(int) {
return true;
}

static_assert(f(0));
```

fails to compile with

```
:4:18: internal compiler error: in dependent_type_p, at cp/pt.c:26440

4 | constexpr bool f(foo auto) {

  |  ^~~

Please submit a full bug report,

with preprocessed source if appropriate.

See <https://gcc.gnu.org/bugs/> for instructions.

Compiler returned: 1
```



See it live: https://godbolt.org/z/EjEePo

[Bug c++/97051] New: Evaluating is_constant_evaluated in requires clause fails

2020-09-14 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97051

Bug ID: 97051
   Summary: Evaluating is_constant_evaluated in requires clause
fails
   Product: gcc
   Version: 11.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following program



#include 

template
requires((std::is_constant_evaluated(), true))
constexpr int a = 0;

constexpr int b = a;



when compiled with `g++ -std=c++20` fails with



:9:19: error: use of invalid variable template 'a'

9 | constexpr int b = a;

  |   ^~

:9:19: note: constraints not satisfied

Compiler returned: 1




See it live: https://godbolt.org/z/fc5cWE

[Bug c/52981] Separate -Wpadded into two options

2019-12-22 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52981

--- Comment #9 from David Stone  ---
It might further be worth giving the "you can rearrange to save sapce" option
two warning levels. The highest level would warn for all cases where
rearranging can reduce size, and the lowest level would warn for all cases
where rearranging only the private data members can reduce size. This is a
potentially important point because rearranging public / protected data members
can affect the API of your type by changing how it interacts with structured
bindings, and, if it is also an aggregate, aggregate construction.

The important new consideration that has the potential for a third warning
option is the handling of empty types. It could be useful to have a warning
that alerts the user that marking a data member with [[no_unique_address]]
would reduce the size of their structure. A potential name for this is
-Wempty-data-member-wastes-space or -Wmissing-no-unique-address.

Cross posted to the equivalent clang bug report:
https://bugs.llvm.org/show_bug.cgi?id=22442#c5

[Bug c++/67348] [concepts] Constraints, special member functions, and default/delete

2019-07-30 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67348

--- Comment #2 from David Stone  ---
This started causing an ICE in 8.1. Prior versions accepted whichever candidate
was defined first as being the one true definition.

[Bug c++/67348] [concepts] Constraints, special member functions, and default/delete

2019-07-30 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67348

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #1 from David Stone  ---
P0848 (Conditionally trivial special member functions) makes the change
suggested by this bug report. However, similar code now causes an internal
compiler error when testing conditionally trivial special member functions with
-fconcepts:


#include 

template
struct s {
~s() {}
~s() requires(std::is_same_v) = default;
};

static_assert(std::is_trivially_destructible_v>);



Outputs:

: In instantiation of 'struct s':

/opt/compiler-explorer/gcc-trunk-20190730/include/c++/10.0.0/type_traits:1410:12:
  required from 'struct std::is_trivially_destructible >'

/opt/compiler-explorer/gcc-trunk-20190730/include/c++/10.0.0/type_traits:3154:25:
  required from 'constexpr const bool std::is_trivially_destructible_v
>'

:9:20:   required from here

:4:8: internal compiler error: tree check: expected function_type or
method_type, have lang_type in deduce_noexcept_on_destructor, at
cp/class.c:4804

4 | struct s {

  |^

Please submit a full bug report,

with preprocessed source if appropriate.

See <https://gcc.gnu.org/bugs/> for instructions.

Compiler returned: 1





See it live: https://godbolt.org/z/viCkS0

[Bug libstdc++/91259] Parenthesize requires clauses that contain expressions that are not just a value of type bool

2019-07-29 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91259

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #6 from David Stone  ---
Sorry, I thought I had seen the usage somewhere else but it turns out I was
mistaken and it was enable_if. Thanks for fixing.

[Bug libstdc++/91259] New: Parenthesize requires clauses that contain expressions that are not just a value of type bool

2019-07-25 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91259

Bug ID: 91259
   Summary: Parenthesize requires clauses that contain expressions
that are not just a value of type bool
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

requires clauses in C++20 must have the expression be parenthesized unless it
is a logical combination of concepts or the name of a single variable of type
bool. libstdc++ contains many expressions that are not parenthesized that do
not meet these requirements (this was not true of the Concepts TS, but as
changed as part of standardization). For instance, in , we have
`requires ! _Std_pair<_Tp>`. This causes an error when trying to compile using
clang + libstdc++, as clang-concepts does not accept this older form. See
https://github.com/saarraz/clang-concepts/issues/73 for the bug report against
clang.

[Bug c++/91082] New: Reference to function binds to pointer to function when given a template specialization

2019-07-03 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91082

Bug ID: 91082
   Summary: Reference to function binds to pointer to function
when given a template specialization
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

In the following code, gcc accepts the code in `c`, but rejects the code in
`d`. I believe both should be rejected, because it is attempting to bind a
pointer to a reference.


template
void a();

void b();

void c() {
static_cast();
}

void d() {
static_cast();
}




See it live: https://godbolt.org/z/zguy6D

[Bug c++/85125] constant expression with const_cast UB does not emit error

2019-06-21 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85125

--- Comment #4 from David Stone  ---
*** Bug 86623 has been marked as a duplicate of this bug. ***

[Bug c++/55004] [meta-bug] constexpr issues

2019-06-21 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55004
Bug 55004 depends on bug 86623, which changed state.

Bug 86623 Summary: constexpr evaluation fails to give an error for modifying a 
const object
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86623

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |DUPLICATE

[Bug c++/86623] constexpr evaluation fails to give an error for modifying a const object

2019-06-21 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86623

David Stone  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||david at doublewise dot net
 Resolution|--- |DUPLICATE

--- Comment #2 from David Stone  ---
Closing as duplicate

*** This bug has been marked as a duplicate of bug 85125 ***

[Bug c++/85125] constant expression with const_cast UB does not emit error

2019-06-21 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85125

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #3 from David Stone  ---
Here is a reproduction that does not require const_cast:


struct S {
int a = 1;
int * ptr = 
};

constexpr bool f() {
auto const s = S{};
*s.ptr = 2;
return s.a == 2;
}

static_assert(f());


See it live: https://godbolt.org/z/30O7_j

[Bug tree-optimization/80738] dead first stmt in a=0;a=b;b=0 whatever the aliasing

2019-06-17 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80738

--- Comment #2 from David Stone  ---
*** Bug 90888 has been marked as a duplicate of this bug. ***

[Bug middle-end/90888] std::swap bad code gen -- alias analysis insufficient to remove dead store

2019-06-17 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90888

David Stone  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |DUPLICATE

--- Comment #3 from David Stone  ---
I agree this is a duplicate of the other bug. Closing this one.

*** This bug has been marked as a duplicate of bug 80738 ***

[Bug middle-end/90888] std::swap bad code gen -- alias analysis insufficient to remove dead store

2019-06-14 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90888

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #1 from David Stone  ---
Forgot to mention, this occurs at -O1, -O2, -Os, -O3

[Bug middle-end/90888] New: std::swap bad code gen -- alias analysis insufficient to remove dead store

2019-06-14 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90888

Bug ID: 90888
   Summary: std::swap bad code gen -- alias analysis insufficient
to remove dead store
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: middle-end
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following code optimizes well for `custom_swap` and `restrict_std_swap`,
but has an additional `mov` instruction for `std_swap`:


void custom_swap(int * lhs, int * rhs) {
int temp = *lhs;
*lhs = *rhs;
*rhs = temp;
}

void restrict_std_swap(int * __restrict lhs, int * __restrict rhs) {
int temp = *lhs;
*lhs = 0;
*lhs = *rhs;
*rhs = temp;
}

void std_swap(int * lhs, int * rhs) {
int temp = *lhs;
*lhs = 0;
*lhs = *rhs;
*rhs = temp;
}



Compiles into this for x86-64:

custom_swap(int*, int*):
mov eax, DWORD PTR [rdi]
mov edx, DWORD PTR [rsi]
mov DWORD PTR [rdi], edx
mov DWORD PTR [rsi], eax
ret
restrict_std_swap(int*, int*):
mov eax, DWORD PTR [rdi]
mov edx, DWORD PTR [rsi]
mov DWORD PTR [rsi], eax
mov DWORD PTR [rdi], edx
ret
std_swap(int*, int*):
mov eax, DWORD PTR [rdi]
mov DWORD PTR [rdi], 0
mov edx, DWORD PTR [rsi]
mov DWORD PTR [rdi], edx
mov DWORD PTR [rsi], eax
ret


And this for ARM64:

custom_swap(int*, int*):
ldr w3, [x1]
ldr w2, [x0]
str w3, [x0]
str w2, [x1]
ret
restrict_std_swap(int*, int*):
ldr w2, [x0]
ldr w3, [x1]
str w3, [x0]
str w2, [x1]
ret
std_swap(int*, int*):
ldr w2, [x0]
str wzr, [x0]
ldr w3, [x1]
str w3, [x0]
str w2, [x1]
ret


As we see from the example that annotates the parameters with __restrict, the
problem appears to be that the risk of *lhs aliasing *rhs disables the
optimizer's ability to remove the dead store in the second line of std_swap. It
is able to see that if they don't alias, the store in line 2 is dead. It is not
able to see that if they do alias, the store in line 3 is dead and the store in
line 2 is dead.

See it live: https://godbolt.org/z/D3Ey9i . 




The real life problem here is that types that manage a resource but do not
implement a custom std::swap, as well as all types that recursively contain a
type that manages a resource, suffer from reduced performance for using
std::swap. The larger, slightly more meaningful test case showing how I arrived
at this reduction and its relationship to std::swap:

struct unique_ptr {
unique_ptr():
ptr(nullptr)
{
}
unique_ptr(unique_ptr && other) noexcept:
ptr(other.ptr)
{
other.ptr = nullptr;
}
unique_ptr & operator=(unique_ptr && other) noexcept {
delete ptr;
ptr = nullptr;
ptr = other.ptr;
other.ptr = nullptr;
return *this;
}
~unique_ptr() noexcept {
delete ptr;
}

int * ptr;
};


void custom_swap(unique_ptr & lhs, unique_ptr & rhs) noexcept {
int * temp = lhs.ptr;
lhs.ptr = rhs.ptr;
rhs.ptr = temp;
}

void inlined_std_swap(unique_ptr & lhs, unique_ptr & rhs) noexcept {
int * temp_ptr = lhs.ptr;
lhs.ptr = nullptr;

delete lhs.ptr;
lhs.ptr = nullptr;
lhs.ptr = rhs.ptr;
rhs.ptr = nullptr;

delete rhs.ptr;
rhs.ptr = nullptr;

rhs.ptr = temp_ptr;
temp_ptr = nullptr;

delete temp_ptr;
}

void std_swap(unique_ptr & lhs, unique_ptr & rhs) noexcept {
auto temp = static_cast(lhs);
lhs = static_cast(rhs);
rhs = static_cast(temp);
}

See it live: https://godbolt.org/z/yBFa4H

[Bug c++/90846] New: Concepts sometimes ignored for friend function templates of class templates

2019-06-11 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90846

Bug ID: 90846
   Summary: Concepts sometimes ignored for friend function
templates of class templates
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following code reports ambiguous overload when compiling with `g++
-std=c++2a -fconcepts`:



template
struct S {
template
friend constexpr auto f(S, S) {
return true;
}

template requires false
friend constexpr auto f(S, T) {
return false;
}

template requires false
friend constexpr auto f(T, S) {
return false;
}
};

static_assert(f(S{}, S{}));



It complains that all three functions are viable overloads. Deleting the second
overload makes gcc complain the that two remaining functions are ambiguous, but
deleting the third overload makes gcc happy and accept the code.

See it live: https://godbolt.org/z/wG3Isj

[Bug c++/79917] Internal compiler error with variadic template and concepts, internal compiler error: in tsubst_constraint, at cp/constraint.cc:1956

2019-06-04 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79917

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #1 from David Stone  ---
Reconfirmed for 9.1. Updated reproduction:

template
concept bool C = true;

struct S {
template
static void f() {
}
};

void foo() {
S::f();
}





: In substitution of 'template  requires  C... static
void S::f() [with c = {}]':

:11:10:   required from here

:6:14: internal compiler error: in tsubst_constraint, at
cp/constraint.cc:1948

6 |  static void f() {

  |  ^






See it live: https://godbolt.org/z/cSCotJ

[Bug c++/68812] [concepts] bogus mismatched argument pack lengths

2019-06-04 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68812

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #1 from David Stone  ---
Reconfirmed on 9.1. This bug manifests even if you change the member function
from a constructor to anything else. The bug does not show up if you pass a
single template argument to the type, but does show up if you pass 0 arguments
or more than 1 argument.

Slightly simplified reproducing:

template
struct S {
template requires(... and (s == f))
static void F() {
}
};

void foo(S<>) {}




See it live: https://godbolt.org/z/SlmBEp

[Bug c++/90449] New: No way to turn off warning about inaccessible base

2019-05-13 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90449

Bug ID: 90449
   Summary: No way to turn off warning about inaccessible base
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

It is possible to pass `-w` to gcc to turn off all warnings, but as far as I
can tell, there is no way to turn off just the warning "direct base ...
inaccessible in ... due to ambiguity". It would be very helpful to me to
disable just this one warning, because I really do not want to turn off the
other on-by-default warnings.

I have a valid use case for needing an ambiguous base class:

https://godbolt.org/z/GG7aR9

In summary, it allows me to implement a tuple that is always empty when given
no non-empty types. The general idea is that `std::get` would delegate to a
member function that accepts an `integral_constant` argument, but each
`tuple_value` class has an overload that accepts only the integral constants
that matches its `index`. This implementation leads to ambiguous base classes
if the user creates a `tuple>`. The base class is inaccessible, but
that doesn't mean that all of its member functions are inaccessible because I
hid the overload that would have conflicted.

The alternative would be to use the more traditional method of implementing
`get` by casting `tuple` to `tuple_value,
Types...>` and thus having `tuple_value` have all of the types in the tuple as
a trailing variadic parameter to ensure uniqueness in tuples of tuples. This
allows emptiness in all possible cases at the cost of greatly increased symbol
sizes (n^2 template instantiation).

clang also warns on this by default, but has the flag `-Wno-inaccessible-base`
to turn it off.

[Bug c++/90432] New: Internal compiler error with no_unique_address empty type with constructor call followed by value initialized to non-zero

2019-05-10 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90432

Bug ID: 90432
   Summary: Internal compiler error with no_unique_address empty
type with constructor call followed by value
initialized to non-zero
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following code causes an internal compiler error:


struct empty {};

struct has_empty {
[[no_unique_address]] empty brace_or_equal_initialized{};
};

struct has_value {
int non_zero = 1;
};


struct pair : has_empty, has_value {};

pair a;
//pair b = pair();





:14:7: internal compiler error: in output_constructor_regular_field, at
varasm.c:5207

   14 | pair a;

  |   ^




See it live: https://godbolt.org/z/tvdsmg


The error occurs if you comment out a and uncomment b, as well.
`brace_or_equal_initialized` can also be initialized by a regular constructor
call, the important part is just that the constructor is explicitly called.

[Bug c++/86623] New: constexpr evaluation fails to give an error for modifying a const object

2018-07-21 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86623

Bug ID: 86623
   Summary: constexpr evaluation fails to give an error for
modifying a const object
   Product: gcc
   Version: 8.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following code is compiled by gcc with -std=c++17



constexpr bool f() {
int const a = 0;
const_cast(a) = 2;
return a == 0;
}

static_assert(f());


This should not be allowed because we modify a const value in a constant
expression.

Here is another example test case that does not use const_cast (and gives a
different answer in the return statement, but I don't think that's especially
relevant because it's undefined behavior anyway):


struct S {
int a = 1;
int * ptr = 
};

constexpr bool f() {
auto const s = S{};
*s.ptr = 2;
return s.a == 2;
}

static_assert(f());

[Bug libstdc++/86524] [8/9 Regression] std::less with pointer arguments not usable in static_assert in constexpr function

2018-07-16 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86524

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #1 from David Stone  ---
I am not sure that the problem is actually in libstdc++. I would expect that
any implementation of std::less that is valid in f1 would also be valid in f2.
Declaring the function itself constexpr should have no bearing on the
static_assert.

[Bug c++/86524] New: std::less with pointer arguments not usable in static_assert in constexpr function

2018-07-14 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86524

Bug ID: 86524
   Summary: std::less with pointer arguments not usable in
static_assert in constexpr function
   Product: gcc
   Version: 8.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

This code worked in gcc 7.3, but no longer works as of 8.1 or trunk.


#include 

void f1() {
constexpr int x = 0;
static_assert(!( < ));
static_assert(!std::less<>{}(, ));
}

constexpr void f2() {
constexpr int x = 0;
static_assert(!( < ));
static_assert(!std::less<>{}(, ));
}


In this example, the function f1 compiles fine, but f2 gives:

> g++ -std=c++17

: In function 'constexpr void f2()':

:12:19: error: non-constant condition for static assertion

 static_assert(!std::less<>{}(, ));

   ^~

Compiler returned: 1


The same problem occurs if using `std::less` instead of
`std::less<>`.

[Bug c++/85944] Address of member variable of temporary not considered constexpr at global scope

2018-05-28 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85944

--- Comment #2 from David Stone  ---
I have simplified the bug. It does not require a member variable to trigger the
bug, just taking the address of a a temporary bound to a reference function
parameter at global scope:



constexpr bool f(int const & x) {
return 
}

constexpr auto x = f(0);





Note that this code does not trigger the bug:



int const & x = 0;
constexpr bool b = 

[Bug c++/85944] New: Address of member variable of temporary not considered constexpr at global scope

2018-05-27 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85944

Bug ID: 85944
   Summary: Address of member variable of temporary not considered
constexpr at global scope
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

When compiling the following code in C++11, C++14, C++17, or C++2a with 8.1 or
trunk (not tested with earlier versions):


struct S {
int x = 0;
};

constexpr bool f(S const & s) {
return 
}

constexpr auto x = f(S{});




gcc gives this error message:


:6:12: error: '((&.S::x) != 0)' is not a constant expression

  return 

^

Compiler returned: 1





Putting the declaration of `x` inside a function rather than at global scope
fixes the error, as does creating a constexpr variable to store the result of
`S{}` and then passing that to `f`.

[Bug c++/83692] Rejects valid constexpr with unrelated code fixing problem

2018-01-04 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83692

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #1 from David Stone  ---
Forgot to mention, this is in C++17 and C++2a modes only. C++14 does not appear
to cause this problem.

[Bug c++/83692] New: Rejects valid constexpr with unrelated code fixing problem

2018-01-04 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83692

Bug ID: 83692
   Summary: Rejects valid constexpr with unrelated code fixing
problem
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

The following program fails to compile

struct integer {
constexpr int value() const {
return m_value;
}
int m_value;
};

struct outer {
integer m_x{0};
constexpr outer() {
if (m_x.value() != 0) throw 0;
m_x.m_value = integer{1}.value();
if (m_x.value() != 1) throw 0;
}
};

constexpr outer o{};


Giving the error message:

17 : :17:19:   in 'constexpr' expansion of 'outer()'
13 : :13:37: error: expression '' is not a constant
expression
 if (m_x.value() != 1) throw 0;
 ^
Compiler returned: 1



Seemingly insignificant changes in the code lead to the error disappearing: for
instance, removing the first if statement (which is not rejected as invalid)
causes the second if statement to be accepted.

[Bug c++/82894] New: Inherited member functions do not create ambiguity

2017-11-07 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82894

Bug ID: 82894
   Summary: Inherited member functions do not create ambiguity
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

#include 

template
struct wrapper : private T {
struct type {};
type f(type = {});
using T::f;
};


struct S {
void f() {
}
};

static_assert(std::is_same<
decltype(std::declval<wrapper &>().f()),
wrapper::type
>{});



This program should fail to compile because the call to `f` should be
ambiguous. Instead, it compiles just fine, indicating that the outer `f` is
hiding `S::f`. This bug prevents the ability to detect certain classes of
member functions.

[Bug c++/82756] New: Poor error message from control flow at global scope

2017-10-27 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82756

Bug ID: 82756
   Summary: Poor error message from control flow at global scope
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

If you compile the following code:


while(true) {}


You get the not especially helpful error message:

:1:1: error: expected unqualified-id before 'while'
 while(true) {}
 ^


This came up for me in the context of calling a macro that wrapped a few
statements in a `do { ... } while(false);` construct, and I spend a fair amount
of time looking for a missing semicolon somewhere before I finally found the
problem. I would have preferred to get a message along the lines of "while
loops not allowed outside of functions" or something else that directly says
the problem from the user's perspective.

[Bug c++/66256] noexcept evaluation done before end of class

2017-08-24 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66256

--- Comment #9 from David Stone  ---
Sorry, I misread the chain of comments, Jonathan Wakely's comment on gcc
correctly rejecting invalid code refers specifically to the decltype example.
Please ignore my previous comment, except that it captures the wording from the
standard that says that the test case for this bug should work.

[Bug c++/66256] noexcept evaluation done before end of class

2017-08-24 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66256

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #8 from David Stone  ---
I do not believe that gcc is correct to reject this code. Consider

http://eel.is/c++draft/basic.scope.class#1

"The potential scope of a name declared in a class consists not only of the
declarative region following the name's point of declaration, but also of all
function bodies, default arguments, noexcept-specifiers, and
brace-or-equal-initializers of non-static data members in that class (including
such things in nested classes)."

That seems to state that this variable is in scope and thus this code should be
allowed.

As a second test case, this should also be accepted (same code, but with e put
in an unevaluated context instead of being static):


struct test
{
test() noexcept(noexcept(e)) {}
const bool e = false;
};

int main() {}




And also



struct test
{
test() noexcept(noexcept(e())) {}
const bool e() { return false; }
};

int main() {}

[Bug c++/52869] [DR 1207] "this" not being allowed in noexcept clauses

2017-08-24 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52869

David Stone  changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #2 from David Stone  ---
Simpler test case:

struct S {
void f() noexcept(noexcept(this)) {}
};

int main() {}



Updated standard reference stating that this should be valid:
http://eel.is/c++draft/expr.prim.this#2

[Bug libstdc++/54924] Warn for std::string constructor with wrong size

2016-07-29 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54924

--- Comment #3 from David Stone  ---
Also filed against libc++ here: https://llvm.org/bugs/show_bug.cgi?id=28777

[Bug libstdc++/69717] New: std::pair is incompatible with std::is_constructible

2016-02-07 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69717

Bug ID: 69717
   Summary: std::pair is incompatible with std::is_constructible
   Product: gcc
   Version: 5.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

#include 
#include 

struct S {
S(int) {}
};

int main() {
using pair_t = std::pair<S, S>;
static_assert(std::is_default_constructible::value, "");
pair_t p;
}





The static_assert does not fire, even though it should. If I comment out line
11, everything compiles. With line 11 in, I get a compile error that
essentially tells me that pair_t is not default constructible. This is with
-std=c++1z, which has pair's constructors only participating in overload
resolution if they are valid.

Compiling with clang and libstdc++ gives different behavior. The static_assert
fails to compile, but not with a regular static_assert message. It gives a hard
error, similar to what gcc gives when you actually try to compile line 11.
However, it is a hard error not in the immediate context, so attempting to use
it for SFINAE with enable_if causes a compile time error. In other words, I get
a compiler error with clang if I just mention
std::is_default_constructible, which seems like 'correct' behavior
based on the implementation of std::pair (but not correct in c++1z mode).

So this actually seems like a bug in both gcc and libstdc++. libstdc++ has a
std::pair implementation that causes a hard error even in c++1z mode if you
check if it is default constructible and it is not, and gcc has a bug that
causes it to ignore that error and just return true for
std::is_default_constructible.

This looks related to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68430

[Bug c++/66042] Implicitly converts lvalue to rvalue when returning reference parameter in function template

2015-05-07 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66042

David Stone david at doublewise dot net changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #1 from David Stone david at doublewise dot net ---
I have also filed this bug against clang under
https://llvm.org/bugs/show_bug.cgi?id=23440


[Bug c++/66042] New: Implicitly converts lvalue to rvalue when returning reference parameter in function template

2015-05-07 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66042

Bug ID: 66042
   Summary: Implicitly converts lvalue to rvalue when returning
reference parameter in function template
   Product: gcc
   Version: 5.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

#include type_traits

templatetypename T
auto compiles(T  t) - T  {
static_assert(std::is_sameT, int::value, Incorrect type deduced for
T.);
return t;
}
static_assert(std::is_sameint , decltype(compiles(0))::value, shouldn't
compile);

auto fails(int  t) - int  {
return t;
}
static_assert(std::is_sameint , decltype(fails(0))::value, doesn't
compile);


Neither function should compile. In the function template case, T is deduced as
int, so the parameter type is int . Local variables and function parameters
taken by value can be implicitly moved into the return value, but not function
parameters taken by rvalue reference (t is an lvalue, even though decltype(t)
== int ).

The non-template function correctly honors this behavior.

If the return type of compiles is changed to decltype(auto) or auto , then
the function correctly returns int  and the static_assert fires.


[Bug c++/66061] New: Internal Compiler Error when specializing a variable template when the specialization is variadic

2015-05-07 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66061

Bug ID: 66061
   Summary: Internal Compiler Error when specializing a variable
template when the specialization is variadic
   Product: gcc
   Version: 5.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

main.cpp:

templateint...
int x = 1;

templateint n, int... m
int xn, m... = 1;





david@i5-fedora ~/test g++ source/main.cpp -c -std=c++14
source/main.cpp:5:5: internal compiler error: in
process_partial_specialization, at cp/pt.c:4248
 int xn, m... = 1;
 ^
0x63102e process_partial_specialization
../../gcc/gcc/cp/pt.c:4248
0x631517 push_template_decl_real(tree_node*, bool)
../../gcc/gcc/cp/pt.c:4892
0x60820f start_decl(cp_declarator const*, cp_decl_specifier_seq*, int,
tree_node*, tree_node*, tree_node**)
../../gcc/gcc/cp/decl.c:4832
0x67e266 cp_parser_init_declarator
../../gcc/gcc/cp/parser.c:17170
0x67ee14 cp_parser_single_declaration
../../gcc/gcc/cp/parser.c:23811
0x67f0b8 cp_parser_template_declaration_after_export
../../gcc/gcc/cp/parser.c:23602
0x661f79 cp_parser_declaration
../../gcc/gcc/cp/parser.c:11342
0x688a3a cp_parser_declaration_seq_opt
../../gcc/gcc/cp/parser.c:11264
0x688d4f cp_parser_translation_unit
../../gcc/gcc/cp/parser.c:4100
0x688d4f c_parse_file()
../../gcc/gcc/cp/parser.c:33192
0x73b692 c_common_parse_file()
../../gcc/gcc/c-family/c-opts.c:1057
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.


[Bug c++/66042] Implicitly converts lvalue to rvalue when returning reference parameter in function template

2015-05-07 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66042

David Stone david at doublewise dot net changed:

   What|Removed |Added

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

--- Comment #2 from David Stone david at doublewise dot net ---
It looks like gcc behaves correctly, which can be seen by adding the line

auto x = compiles(0);

I wasn't actually instantiating the template, just looking at its return type.

This can be closed; sorry for the noise.


[Bug c++/65896] New: Erroneous uninitialized variable access error in constexpr function with temporary variables

2015-04-26 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65896

Bug ID: 65896
   Summary: Erroneous uninitialized variable access error in
constexpr function with temporary variables
   Product: gcc
   Version: 5.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net
  Target Milestone: ---

file.cpp
==
struct base{};

struct derived : base {
constexpr derived():
base{},
m_value(0) {
}
constexpr derived(derived  other):
base{},
m_value(other) {
}
constexpr explicit operator int() const {
return m_value;
}
int m_value;
};

constexpr int by_ref(derived  value) {
return (derived(value), 0);
}

constexpr int value = by_ref(derived{});
==

c++ -std=c++11 -o /dev/null file.cpp -c


gcc 4.8.3 and 4.9.3 and clang 3.5.0 successfully compile this program. gcc
5.1.1 fails with:

file.cpp:22:29:   in constexpr expansion of ‘by_ref(derived())’
file.cpp:22:39:   in constexpr expansion of ‘derived((*  value))’
file.cpp:10:16:   in constexpr expansion of ‘( other)-derived::operator
int()’
file.cpp:22:39: error: accessing uninitialized member ‘derived::m_value’
 constexpr int value = by_ref(derived{});
   ^


Changing to C++1y / C++14 does not change this.

[Bug c++/65896] Erroneous uninitialized variable access error in constexpr function with temporary variables

2015-04-26 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65896

David Stone david at doublewise dot net changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #1 from David Stone david at doublewise dot net ---
I have simplified the test case further:


struct base {};

struct derived :  base {
constexpr derived():
base{},
m_value(0) {
}
int m_value;
};

constexpr int by_ref(derived  value) {
return value.m_value;
}

constexpr int value = by_ref(derived{});


[Bug other/53313] Add warning levels

2015-04-25 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53313

--- Comment #13 from David Stone david at doublewise dot net ---
I understand the difference between the two. I just prefer an opt-out system of
warnings instead of opt-in. If absolutely no one could possibly want a warning,
it shouldn't exist. If some users would want the warning, I may be one of those
users at some point and I'd like to see it.


[Bug other/53313] Add warning levels

2015-04-24 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53313

--- Comment #11 from David Stone david at doublewise dot net ---
If the warnings are so ridiculous that no one could possibly want them on, then
maybe we should remove them. Otherwise, I would want -Weverything and I can use
-Wno-warnings-I-do-not-want


[Bug other/53313] Add warning levels

2015-04-23 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53313

--- Comment #8 from David Stone david at doublewise dot net ---
I have changed my opinion on this and agree that warning levels are probably
not the way to go. The two things from this that I do still want are

-Weverything-and-I-really-mean-it-this-time

All warnings either warn for exactly one type of thing or they turn on other
warnings that themselves can be individually turned on or off.


[Bug c/52981] Separate -Wpadded into two options

2015-04-23 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52981

--- Comment #5 from David Stone david at doublewise dot net ---
After thinking about this some more, we are not answering the question that
splitting it into two warnings is really trying to get at.

The first, and most important is not Is there padding in the middle of the
structure, but Can I rearrange my data members to save space?.
-Wwasted-space might be a good name for this warning. I believe in all systems
that gcc targets*, the optimal size can be achieved by arranging elements
largest to smallest, so we could just compare the size of a theoretical struct
with that arrangment and the size of the user's struct.

The second thing the user might wonder is Do I have padding that I cannot
resolve by rearranging. This warning can alert the user that a small change in
the size of their data types (or possibly moving data into different
structures) could have a greater-than-expected size savings. This is more like
the current -Wpadded.

* A strange system with 4-byte, 3-byte, and 1-byte aligned types could have a
more efficient representation by following every 3 with a 1. I am unsure if
this is actually valid according to the C or C++ standard. As long as all of
the systems just have power-of-two alignment, the largest to smallest works.


[Bug c++/63871] New: -Weffc++ does not understand type deduction for return types

2014-11-14 Thread david at doublewise dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63871

Bug ID: 63871
   Summary: -Weffc++ does not understand type deduction for return
types
   Product: gcc
   Version: 4.9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: david at doublewise dot net

Source file:


class C {};
auto  operator++(C  c) {
return c;
}

int main() {
}



gcc-4.9 source/main.cpp -Weffc++ -std=c++1y
source/main.cpp:112:25: warning: prefix ‘auto operator++(C)’ should return
‘C’ [-Weffc++]
 auto  operator++(C  c) {



I get the same error with the return type specified as `auto ` or
`decltype(auto)`.

[Bug c++/56861] New: std::vector::reserve optimization bug

2013-04-06 Thread david at doublewise dot net


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



 Bug #: 56861

   Summary: std::vector::reserve optimization bug

Classification: Unclassified

   Product: gcc

   Version: 4.7.2

Status: UNCONFIRMED

  Severity: normal

  Priority: P3

 Component: c++

AssignedTo: unassig...@gcc.gnu.org

ReportedBy: da...@doublewise.net





std::vector::reserve has a few peculiarities currently, as far as the optimizer

is concerned. In some cases, calling reserve with the final size of the vector

doesn't improve performance at all, but calling reserve with room for one extra

element does. In other cases, calling reserve with exactly the correct amount

improves performance, but calling with one extra gives the same performance as

no reserve at all. I don't know under what circumstances this happens, but it

appears to be somewhat system dependent, and changes with otherwise

insignificant changes to the code.



This arose from a StackOverflow discussion at

http://stackoverflow.com/questions/15707688/why-is-calling-vector-reserverequired-1-faster-than-vector-reserverequired



That thread contains the code in the first post, which shows the reserve + 1

situation being fastest. The answer by smossen gives some simple changes that

lead to the optimizer always working correctly or working correctly in

different situations. Unfortunately, I do not know exactly what causes this,

but it happens with and without LTO enabled, depending on the code. smossen

believes it has to do with the architecture-specific cost model being

misapplied in certain circumstances.







Using built-in specs.

COLLECT_GCC=g++

COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.7.2/lto-wrapper

Target: x86_64-redhat-linux

Configured with: ../configure --prefix=/usr --mandir=/usr/share/man

--infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla

--enable-bootstrap --enable-shared --enable-threads=posix

--enable-checking=release --disable-build-with-cxx

--disable-build-poststage1-with-cxx --with-system-zlib --enable-__cxa_atexit

--disable-libunwind-exceptions --enable-gnu-unique-object

--enable-linker-build-id --with-linker-hash-style=gnu

--enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin

--enable-initfini-array --enable-java-awt=gtk --disable-dssi

--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre

--enable-libgcj-multifile --enable-java-maintainer-mode

--with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib

--with-ppl --with-cloog --with-tune=generic --with-arch_32=i686

--build=x86_64-redhat-linux

Thread model: posix

gcc version 4.7.2 20121109 (Red Hat 4.7.2-8) (GCC)


[Bug libstdc++/56785] New: std::tuple of two elements does not apply empty base class optimization when one of its elements is a std::tuple with two elements

2013-03-29 Thread david at doublewise dot net

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

 Bug #: 56785
   Summary: std::tuple of two elements does not apply empty base
class optimization when one of its elements is a
std::tuple with two elements
Classification: Unclassified
   Product: gcc
   Version: 4.7.2
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: da...@doublewise.net


#include tuple

class Empty {
};

int main() {
static_assert(sizeof(std::tupleEmpty, std::tupleint, int) ==
sizeof(std::tupleint, int), Too big);
}

[david@localhost test]$ g++ source/test.cpp -std=c++11 -Wall -Wextra -pedantic
source/test.cpp: In function ‘int main()’:
source/test.cpp:23:2: error: static assertion failed: Too big


The static_assert does not fail if I change it to be a std::tupleint, int,
int on both sides, however, or any number of int other than exactly 2. I also
get this bug regardless of the type in the std::tuple (for instance, my own
class type).

Therefore, I have created a workaround, demonstrated such:

#include tuple

class Empty {
};
class Empty2 {
};

int main() {
static_assert(sizeof(std::tupleEmpty, std::tupleint, short, Empty2) ==
sizeof(std::tupleint, short, Empty2), Too big);
static_assert(sizeof(std::tupleEmpty, std::tupleint, int, Empty2) ==
sizeof(int) * 2, Too big);
}






[david@localhost test]$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.7.2/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla
--enable-bootstrap --enable-shared --enable-threads=posix
--enable-checking=release --disable-build-with-cxx
--disable-build-poststage1-with-cxx --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-gnu-unique-object
--enable-linker-build-id --with-linker-hash-style=gnu
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin
--enable-initfini-array --enable-java-awt=gtk --disable-dssi
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre
--enable-libgcj-multifile --enable-java-maintainer-mode
--with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib
--with-ppl --with-cloog --with-tune=generic --with-arch_32=i686
--build=x86_64-redhat-linux
Thread model: posix
gcc version 4.7.2 20121109 (Red Hat 4.7.2-8) (GCC)

[Bug c++/56556] New: Wshadow warns for private members in base classes

2013-03-06 Thread david at doublewise dot net


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



 Bug #: 56556

   Summary: Wshadow warns for private members in base classes

Classification: Unclassified

   Product: gcc

   Version: 4.7.2

Status: UNCONFIRMED

  Severity: normal

  Priority: P3

 Component: c++

AssignedTo: unassig...@gcc.gnu.org

ReportedBy: da...@doublewise.net





The following code warns due to -Wshadow:



class Base {

private:

int x;

};



class Derived : public Base {

Derived(int x) {}

};



Perhaps we should consider not having this warn? In my particular case, I have

a Base class with a private member variable, a class Derived that derives from

Base, and a class EvenMoreDerived that derives from Derived. In a member

function of EvenMoreDerived, I am trying to use a variable with the same name

as the private member variable of Base.



The only situation I can think of where this could theoretically be useful is

if there is some kind of overload resolution issue, but due to derived classes

hiding member functions of base classes I don't imagine that would be an issue.


[Bug c++/55357] New: -Wshadow warns about lambda function parameters matching variables in outer scope

2012-11-16 Thread david at doublewise dot net


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



 Bug #: 55357

   Summary: -Wshadow warns about lambda function parameters

matching variables in outer scope

Classification: Unclassified

   Product: gcc

   Version: 4.7.2

Status: UNCONFIRMED

  Severity: normal

  Priority: P3

 Component: c++

AssignedTo: unassig...@gcc.gnu.org

ReportedBy: da...@doublewise.net





Similar to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30566



input:



int main() {

int x = 1;

auto const lambda = [](int x) {

return x;

};

}







output:



src/main.cpp: In lambda function:

src/main.cpp:3:30: error: declaration of 'x' shadows a previous local

[-Werror=shadow]

src/main.cpp:2:6: error: shadowed declaration is here [-Werror=shadow]

src/main.cpp: In static member function 'static int

main()::lambda(int)::_FUN(int)':

src/main.cpp:5:2: error: declaration of 'x' shadows a previous local

[-Werror=shadow]

src/main.cpp:2:6: error: shadowed declaration is here [-Werror=shadow]

cc1plus: all warnings being treated as errors







My lambda has an empty capture specification, so the outer x is not captured.

Note that if I change the lambda parameter's name but do not change the name of

the returned value, I get an error that x was not captured.



I can't decide if this is correct behavior for the warning. It would catch

errors caused by people thinking they were using the outer variables by simply

disallowing overlap, which is good. However, it's not possible to use the outer

scope variable no matter what I name my variables in the inner scope, so there

is no chance of a silent behavior change.



However, the following code should always give a warning with -Wshadow:



int main() {

int x = 1;

// Capture everything

auto const lambda = [](int x) {

return x;

};

}









I also note that gcc warns me about the first line the lambda appears on (line

3) and the last line (line 5).


[Bug c++/55254] New: Warn for implicit conversion from int to char

2012-11-09 Thread david at doublewise dot net


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



 Bug #: 55254

   Summary: Warn for implicit conversion from int to char

Classification: Unclassified

   Product: gcc

   Version: 4.7.2

Status: UNCONFIRMED

  Severity: normal

  Priority: P3

 Component: c++

AssignedTo: unassig...@gcc.gnu.org

ReportedBy: da...@doublewise.net





I sometimes want to construct a string with n copies of a char c. However, I

frequently get the order of elements in the constructor mixed up. Rather than

saying std::string(80, '='), I accidentally call std::string('=', 80).



To me, it seems like the underlying issue here is that gcc does not warn for

implicit conversion from int to char. Whenever I assign a literal to a char, I

always assign something wrapped in single quotes, never an integer literal.



However, I would suggest that perhaps this warning should have two levels. The

first level would only warn for char. The second level would warn for char,

signed char, and unsigned char. The reason for this separation is that int8_t

is a typedef for signed char and uint8_t is a typedef for unsigned char (on

most platforms), and those are regularly used as small integers (I use them

extensively in space-sensitive code). My experience is that when people use a

signed / unsigned char explicitly, or one of the typedefs in cstdint /

stdint.h, they are not used as actual characters, but bytes / small numbers,

and in that case, assigning from an integer wouldn't be incorrect.


[Bug c++/54924] New: Warn for std::string constructor with wrong size

2012-10-14 Thread david at doublewise dot net


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



 Bug #: 54924

   Summary: Warn for std::string constructor with wrong size

Classification: Unclassified

   Product: gcc

   Version: 4.7.2

Status: UNCONFIRMED

  Severity: normal

  Priority: P3

 Component: c++

AssignedTo: unassig...@gcc.gnu.org

ReportedBy: da...@doublewise.net





The constructor for std::string that takes an array of char and a size assumes

that the array of char you pass in is at least as large as the size you

specify. In other words, std::string str('0', 100) is undefined behavior. As I

show in this example, the real issue can be much more subtle if escape

characters are involved:



http://stackoverflow.com/questions/164168/how-do-you-construct-a-stdstring-with-an-embedded-null/12884464#12884464



It would be nice if gcc warned when the size specified in the constructor

exceeds the size of the array passed as the first argument.


[Bug libstdc++/54924] Warn for std::string constructor with wrong size

2012-10-14 Thread david at doublewise dot net


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



David Stone david at doublewise dot net changed:



   What|Removed |Added



 CC||david at doublewise dot net



--- Comment #2 from David Stone david at doublewise dot net 2012-10-14 
18:40:33 UTC ---

Yeah, sorry, I meant the (char const *, size_t) overload, not the (size_t,

char) overload.


[Bug c++/54021] [c++0x] __builtin_constant_p should be constexpr

2012-09-09 Thread david at doublewise dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54021

--- Comment #7 from David Stone david at doublewise dot net 2012-09-09 
06:00:37 UTC ---
That seems to me like saying that `constexpr bool d = sizeof(x);` should be
disallowed because it uses a non-constexpr. You're not using the value of x,
just a property about it. Whether a value is constexpr is guaranteed to be
known at compile time, and so should be usable as a constexpr.


[Bug c++/54535] New: gcc fails to warn when functions are inlined

2012-09-09 Thread david at doublewise dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54535

 Bug #: 54535
   Summary: gcc fails to warn when functions are inlined
Classification: Unclassified
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: minor
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: da...@doublewise.net


#include iostream

namespace {
static void f(bool condition) {
volatile int const x =  (__builtin_constant_p(condition) ? (1 /
(condition)) : 0); \
}
}
int main() {
f(false);
}


I compile this with -Werror=div-by-zero, and I do not get any warnings while
compiling. Instead, I get Floating point exception (core dumped) when I
attempt to run it.

The same sort of thing happens with other situations that should be warned
about, such as indexing an array with a negative number. I do get a warning if
I manually inline the call to f or make it a macro.


gcc -v
Using built-in specs.
COLLECT_GCC=/usr/bin/gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.7.0/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla
--enable-bootstrap --enable-shared --enable-threads=posix
--enable-checking=release --disable-build-with-cxx
--disable-build-poststage1-with-cxx --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-gnu-unique-object
--enable-linker-build-id --with-linker-hash-style=gnu
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin
--enable-initfini-array --enable-java-awt=gtk --disable-dssi
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre
--enable-libgcj-multifile --enable-java-maintainer-mode
--with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib
--with-ppl --with-cloog --with-tune=generic --with-arch_32=i686
--build=x86_64-redhat-linux
Thread model: posix
gcc version 4.7.0 20120507 (Red Hat 4.7.0-5) (GCC)


[Bug c++/54021] [c++0x] __builtin_constant_p should be constexpr

2012-09-08 Thread david at doublewise dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54021

David Stone david at doublewise dot net changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #5 from David Stone david at doublewise dot net 2012-09-08 
21:36:10 UTC ---
I'm running into some issues with this bug, and it's much broader than the test
cases suggest. On gcc 4.7.0, this is what happens:

int main() {
int x = 0;
// This assigns false to a:
bool const a = __builtin_constant_p(x);
// This assigns true to b:
bool const b = __builtin_constant_p(__builtin_constant_p(x));
// This causes error: the value of 'x' is not usable in a constant
expression
constexpr bool c = __builtin_constant_p(x);
}


[Bug other/53313] Add warning levels

2012-08-15 Thread david at doublewise dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53313

David Stone david at doublewise dot net changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #2 from David Stone david at doublewise dot net 2012-08-16 
03:49:07 UTC ---
Naming the meta-warning that turns on all warnings '-Weverything' would match
with clang's syntax, so that's probably what we should name it, too.


[Bug c/7652] -Wswitch-break : Warn if a switch case falls through

2012-07-14 Thread david at doublewise dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=7652

--- Comment #12 from David Stone david at doublewise dot net 2012-07-14 
15:14:13 UTC ---
However, I think it's important to note that they implement the very noisy
behavior of warning for all implicit fall-through. We could make our warning
much more useful by being silent for empty case statements, and in light of
other warnings starting with -Wswitch, I would recommend we name the warning
-Wswitch-fall-through or something similar. If we want to have an additional
warning that warns for all fall-through, as clang does, we could also add
-Wswitch-empty-fall-through.


[Bug c++/53960] New: Add warning about implicit fallthrough in switch

2012-07-13 Thread david at doublewise dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53960

 Bug #: 53960
   Summary: Add warning about implicit fallthrough in switch
Classification: Unclassified
   Product: gcc
   Version: 4.8.0
Status: UNCONFIRMED
  Severity: enhancement
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: da...@doublewise.net


A helpful warning that should catch real bugs would be to warn for cases of
implicit fallthrough in a switch statement in C / C++. This warning is
currently implemented in clang. However, I feel that their implementation is
flawed, and we can do it a little better. It is idiomatic C / C++ to do
something like this, which should not be warned about:

switch(n) {
case 0:
case 1:// Implicit fallthrough, but obviously intended
do_something();
break;
default:
break;
}

Perhaps we should add two sets of warnings? Something like
-Wimplicit-fall-through and -Wimplicit-fall-through-empty-case? The second
warning would be identical to the clang warning, which warns whenever a case in
a switch does not end in something like break or return, while the first
warning is the (much more useful) warning only if a case is not completely
empty.


[Bug c++/53711] New: Wunused-function should warn for functions in the unnamed namespace

2012-06-17 Thread david at doublewise dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53711

 Bug #: 53711
   Summary: Wunused-function should warn for functions in the
unnamed namespace
Classification: Unclassified
   Product: gcc
   Version: 4.8.0
Status: UNCONFIRMED
  Severity: enhancement
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: da...@doublewise.net


Wunused-function currently only warns for functions that are declared as static
that are never used / defined. It should also warn about functions placed in
the unnamed namespace, such as:

namespace {
void f();
}

Such functions have similar mechanics to static functions. In particular, they
can only be referenced in the translation unit, so the compiler knows for
certain that if the function is not used in this translation unit, it is not
used.


[Bug c++/53650] [4.7/4.8 Regression] large array causes huge memory use

2012-06-17 Thread david at doublewise dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53650

--- Comment #5 from David Stone david at doublewise dot net 2012-06-17 
19:54:52 UTC ---
As a workaround for this bug, I was able to compile much faster (so that I can
compile my program with optimizations turned on) by declaring the constructor
for the class in the array as constexpr (which worked just fine for me because
I only cared that a single member variable was 0, and the rest could have
indeterminate values).


[Bug c++/53650] [4.7/4.8 Regression] large array causes huge memory use

2012-06-13 Thread david at doublewise dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53650

David Stone david at doublewise dot net changed:

   What|Removed |Added

 CC||david at doublewise dot net

--- Comment #2 from David Stone david at doublewise dot net 2012-06-13 
18:44:18 UTC ---
Turns out that contrary to my previous report, optimizations don't actually
solve the memory use problem, they just slow it down significantly. Several
hours into compilation, memory use was at ~2 GiB and still growing (very
slowly). It seems that maybe it uses just as much memory, it just takes much,
much longer to get there.


[Bug c++/53650] New: large array causes huge memory use

2012-06-12 Thread david at doublewise dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53650

 Bug #: 53650
   Summary: large array causes huge memory use
Classification: Unclassified
   Product: gcc
   Version: 4.7.0
Status: UNCONFIRMED
  Severity: major
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: da...@doublewise.net


This problem did not exist in 4.6.x. The following program uses  4 GiB of
memory (more than my system has) during compilation. If I reduce the size of
the array a bit, it still uses several GiB but does eventually compile (so the
problem is not infinite recursion) and takes a very long time to compile.
Compiling with optimizations on seems to eliminate the large memory usage but
takes longer than I was willing to wait to compile.

class Class {
public:
Class() {}
};

int main() {
Class table [2048][256] = {};
return 0;
}


Using something like int causes no problems and compiles quickly.

This may also relate to a C++11 missed optimization opportunity, because this
may suggest that the fact that Class has a constructor is making it non-POD,
but the POD rules were relaxed in C++11 to make Class a POD structure (I
think). Compiling with std=c++11 doesn't fix the problem, however.

gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.7.0/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla
--enable-bootstrap --enable-shared --enable-threads=posix
--enable-checking=release --disable-build-with-cxx
--disable-build-poststage1-with-cxx --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-gnu-unique-object
--enable-linker-build-id --with-linker-hash-style=gnu
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin
--enable-initfini-array --enable-java-awt=gtk --disable-dssi
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre
--enable-libgcj-multifile --enable-java-maintainer-mode
--with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib
--with-ppl --with-cloog --with-tune=generic --with-arch_32=i686
--build=x86_64-redhat-linux
Thread model: posix
gcc version 4.7.0 20120507 (Red Hat 4.7.0-5) (GCC)


[Bug c++/16166] -Weffc++ finer granularity

2012-05-29 Thread david at doublewise dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16166

--- Comment #7 from David Stone david at doublewise dot net 2012-05-29 
20:57:22 UTC ---
(In reply to comment #5)
 (In reply to comment #4)
  * Item 11: Define a copy constructor and an assignment operator for classes
  with dynamically allocated memory.
  
  -Wcopy-resource-class
 
 IMHO this warning should just go. With deleted copy ctor/assign and move
 ctor/assign there are even more places where a hard and fast rule isn't 
 useful.
 

And in general, classes should just use a smart pointer from boost / the
standard library, rather than managing their own memory directly. I agree that
this warning probably isn't that useful, and I wouldn't be sad to see it go.

  * Item 12: Prefer initialization to assignment in constructors.
  
  -Wassignment-in-constructor
 
 If I ever get my -Wmeminit patch working properly it would provide this.

Is the issue just finding the time to do it, or are there subtle issues
involved?

  * Item 14: Make destructors virtual in base classes.
  
  Already covered by -Wnon-virtual-dtor
 
 And the more useful -Wdelete-non-virtual-dtor

Yeah, my only thought for the usefulness of -Wnon-virtual-dtor over
-Wdelete-non-virtual-dtor is that a library author may wish to have a class
that users are supposed to derive from, but doesn't actually call delete
anywhere in the library code. They may want to ensure that users of the library
(who may not have any warnings turned on at all) do not run into any surprising
bugs.

(In reply to comment #6)
 David, if you wish to implement such a patch (or, even better, series of
 patches, one for each new option), the only changes needed are:
 

I am currently writing up a patch to update doc/invoke.texi for warnings, to
try and make it easier to see what is turned on by -Wall and -Wextra and what
isn't. Do you think it would be best for me to submit a patch based on the
current documentation, my updated documentation (as a separate patch, of
course), or some combination of the two?


[Bug c++/53514] New: Make -Wpadded a meta-option for -Wpadded-in-middle and -Wpadded-at-end

2012-05-28 Thread david at doublewise dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53514

 Bug #: 53514
   Summary: Make -Wpadded a meta-option for -Wpadded-in-middle and
-Wpadded-at-end
Classification: Unclassified
   Product: gcc
   Version: 4.8.0
Status: UNCONFIRMED
  Severity: enhancement
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: da...@doublewise.net


Warn if padding is included in a structure, either to align an element of the
structure or to align the whole structure. Sometimes when this happens it is
possible to rearrange the fields of the structure to reduce the padding and so
make the structure smaller.

I would find this warning much more useful if it were two different warnings,
-Wpadded-in-middle and -Wpadded-at-end.

-Wpadded-at-end would only warn if padding was added to the end of the
structure. This could theoretically be useful to let you know about structures
that you can add data to for free in terms of size.

What I'm more interested in, however, is -Wpadded-in-middle. This is what
suggests that perhaps you could reduce the size of the structure by changing
the order of the elements.

This suggestion would make -Wpadded become equivalent to -Wpadded-in-middle
-Wpadded-at-end.


[Bug c++/16166] -Weffc++ finer granularity

2012-05-28 Thread david at doublewise dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16166

--- Comment #4 from David Stone david at doublewise dot net 2012-05-29 
02:13:53 UTC ---
I would recommend against naming each warning -Weffc++[n], but rather, give a
more descriptive name. My suggestion is to create a few warnings, so that
-Weffc++ would map to the following set of warnings (with their current
description for reference and my suggested name):

Effective C++:

* Item 11: Define a copy constructor and an assignment operator for classes
with dynamically allocated memory.

-Wcopy-resource-class

* Item 12: Prefer initialization to assignment in constructors.

-Wassignment-in-constructor

* Item 14: Make destructors virtual in base classes.

Already covered by -Wnon-virtual-dtor

* Item 15: Have operator= return a reference to *this.

-Wassignment-operator-return-value

* Item 23: Don't try to return a reference when you must return an object. 

-Wsuspicious-reference-return

More Effective C++:

* Item 6: Distinguish between prefix and postfix forms of increment and
decrement operators.

-Wprefix-postfix

* Item 7: Never overload , ||, or ,. 

Perhaps this should be split into two warnings of its own:
-Woverloaded-short-circuit
-Woverloaded-comma

In summary, you could simulate exactly the behavior of -Weffc++ by turning on
each of these warnings individually, or you could turn on -Weffc++ and
selectively turn off a few warnings that you don't want.


[Bug other/53316] Introduce -Odebug

2012-05-16 Thread david at doublewise dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53316

--- Comment #10 from David Stone david at doublewise dot net 2012-05-16 
15:57:13 UTC ---
I did some research to see how often each optimization level is actually used.
Looking solely at the most followed C and C++ repositories on github, I
collected the following data:

C:

Linux kernel: 2 s
redis: 2 0
vim: 2 6 0 (6 and 0 for commented out options that are selectively enabled for
testing)
git: 2 s 0 (s for debugging, 0 for code coverage tests)
PHP: 0 2 s
openFrameworks: s
memcached: no defaults found (somewhat thorough check, autotools)
libfreenect: 2
xbmc: 2
mruby: 3 (even for debugging!)
wax: no defaults found (rake)
beanstalkd: use the default 0 (implicit, Make)
ccv: 1 (but they preceed it with CC = clang, so it's not really relevant for
us)
yajl-ruby: no defaults found (rake)
libgit2: 2 0
iProxy: seems to be XCode only
http-parser: 0 3
nginx_http_push_module: no build scripts, so no defaults


C++:

hiphop-php: 0 3 s
MongoDB: 0 3
Doom GPL: 0 1 3 (0 and 1 are both used with debugging)
PhantomJS: no defaults found (qmake)
MaNGOS: Does not appear to set (thorough check, CMake)
Scribe: 3 0
TrinityCore: Does not appear to set any optimization level, but does turn on
some 'f' flags specifically (CMake)
bitcoin: 2
firesheep: 0
Mosh: 2
farbrausch/fr_public: Written for Visual Studio
twitter/MySQL: 0 3
Cinder: (uses XCode 3.2 on Mac, Visual C++ on Windows)
therubyracer: no defaults found (rake)
wkhtmltopdf: no defaults found (qmake)
v8: 0 3 2 (the 2 seems to be always added after the 3, so I don't know if the 3
is actually ever used)
depthjs: no defaults found (CMake)
node-canvas: 3
libzmq: 0
HandlerSocket: 3



I think it's interesting to note that -O1 only appears a single time, and that
is in the Doom 3 source. -O0 and -O1 are both used for debugging, with -O3 used
for release. -O0 shows up 16 times for sure (plus possibly some implicit -O0),
-O2 shows up 11 times, -O3 shows up 10 times (although I believe it is
overwritten with -O2 in one of them), and -Os shows up 5 times.

-Os is used 4 times in C code compared to just once in C++. However, -O3 is
used 8 times in C++, compared to only twice in C. In general, C projects seem
to prefer -O2, while C++ projects seem to prefer -O3.

I could not find a default optimization setting for 11 out of 34 projects (+ 4
that definitely do not use gcc). Of those 11 projects:

* 1 has no build scripts at all (and thus the default is just whatever the
compiler default is, therefore -O0)
* 2 use qmake, which I believe can be called with something like -release,
which gets -O3, but defaults to -O0 (I'm not sure on this, I don't use qmake)
* 3 use rake, which may set its own defaults (I don't know). I couldn't find a
single default for projects using rake.
* 3 use CMake, which may set its own defaults (I don't know)
* 1 uses a plain Makefile, and I believe I checked everything and could not
find any defaults (so I counted it as -O0)
* 1 uses the auto-tools, and I checked pretty thoroughly and I could not find
any default settings, but there is a slight chance I may have missed it so I
didn't count it as -O0


[Bug other/53316] Introduce -Odebug

2012-05-11 Thread david at doublewise dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53316

--- Comment #9 from David Stone david at doublewise dot net 2012-05-11 
15:48:53 UTC ---
I suppose this is a much better way to phrase the suggestion as a starting
point. First get -Odebug and then see where we go from there.