[Bug c++/80039] `constexpr` member function calls in a `constexpr` constructor are ignored if the object is defined locally
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
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
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
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
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
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
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
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]]
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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.