[Bug c++/92505] New: Using mutable in constexpr
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92505 Bug ID: 92505 Summary: Using mutable in constexpr Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- GCC trunk does not accept this well-formed program in -std=c++2a mode: constexpr int f() { struct { mutable int i = 41; } s; auto const& cs = s; return ++cs.i; } int main() { constexpr int i = f(); return 42 - i; } Diagnosing (https://godbolt.org/z/n259tb): : In function 'int main()': :10:24: in 'constexpr' expansion of 'f()' :10:25: error: mutable 'f()i' is not usable in a constant expression 10 | constexpr int i = f(); | ^ Compiler returned: 1 AFAICS this is well-formed back to C++14 since it applies lvalue-to-rvalue conversion to "a non-volatile glvalue of literal type that refers to a non-volatile object whose lifetime began within the evaluation of e;".
[Bug c++/90734] [concepts] Pre-normalization substitution into constraints of templated function breaks subsumption
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90734 Casey Carter changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #4 from Casey Carter --- There's some confusion here as a result of my inadequate description in the original bug. The line `static_assert(S1::f()); // Bogus error` is valid but was not accepted and the line `static_assert(S2::f()); // Bogus non-error` is invalid but was not rejected. This should have been tagged both "rejects-valid" and "accepts-invalid" (or better yet, I should have filed separate issues instead of conflating the two). As Andrew says, trunk now both accepts and rejects the cases it should here. I'll simply close this since I don't think it provides any useful or unique test case.
[Bug c++/67491] [meta-bug] concepts issues
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491 Bug 67491 depends on bug 90734, which changed state. Bug 90734 Summary: [concepts] Pre-normalization substitution into constraints of templated function breaks subsumption https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90734 What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED
[Bug c++/82380] [concepts] Error when using requires constraint with attributes
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82380 Casey Carter changed: What|Removed |Added CC||cjdb.ns at gmail dot com --- Comment #6 from Casey Carter --- (In reply to Jonathan Wakely from comment #5) > I tested it with "concept" not "concept bool" i.e. > > template > concept C = true; > > template > requires C > [[nodiscard]] int f(T t) { > return 22; > } > > int main() { > return 0; > } This seems to have regressed (https://godbolt.org/z/SmPx-y).
[Bug c++/59659] large zero-initialized std::array of std::atomic compile time excessive
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59659 --- Comment #1 from Casey Carter --- Created attachment 31563 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=31563&action=edit Minimal test case. Attached minimal test case. std::atomic arr[100]; compiles correctly, so it seems to be an interaction between std::atomic and std::array.
[Bug c++/88419] New: [9 Regression] [ICE] "Same canonical type node for different types" for CTAD in noexcept
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88419 Bug ID: 88419 Summary: [9 Regression] [ICE] "Same canonical type node for different types" for CTAD in noexcept Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 45191 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45191&action=edit Repro This TU: template struct ref_view { template ref_view(T&&); }; template ref_view(R&) -> ref_view; struct ref_fn { template auto operator()(R r) const noexcept(noexcept(ref_view{r})); }; template struct indirect_view { indirect_view(R); }; struct indirect_fn { template auto operator()(R r) const noexcept(noexcept(indirect_view{r})); }; ICEs when compiled with "g++ -std=c++17 -c": /home/casey/casey/Desktop/repro.cpp:18:40: internal compiler error: same canonical type node for different types ‘indirect_view’ and ‘ref_view’ 18 | noexcept(noexcept(indirect_view{r})); |^ 0x9fd2af comptypes(tree_node*, tree_node*, int) /home/casey/repos/gcc/gcc/cp/typeck.c:1486 0x9f3076 cp_tree_equal(tree_node*, tree_node*) /home/casey/repos/gcc/gcc/cp/tree.c:3558 0x9f3d6f cp_tree_equal(tree_node*, tree_node*) /home/casey/repos/gcc/gcc/cp/tree.c:3816 0x9e3772 cp_check_qualified_type /home/casey/repos/gcc/gcc/cp/tree.c:2135 0x9e7557 build_cp_fntype_variant(tree_node*, cp_ref_qualifier, tree_node*, bool) /home/casey/repos/gcc/gcc/cp/tree.c:2568 0x9e7647 build_cp_fntype_variant(tree_node*, cp_ref_qualifier, tree_node*, bool) /home/casey/repos/gcc/gcc/cp/tree.c:2599 0x8b9aeb grokdeclarator(cp_declarator const*, cp_decl_specifier_seq*, decl_context, int, tree_node**) /home/casey/repos/gcc/gcc/cp/decl.c:11527 0x8caa3e grokfield(cp_declarator const*, cp_decl_specifier_seq*, tree_node*, bool, tree_node*, tree_node*) /home/casey/repos/gcc/gcc/cp/decl2.c:814 0x95b2f1 cp_parser_init_declarator /home/casey/repos/gcc/gcc/cp/parser.c:20306 0x95ef04 cp_parser_single_declaration /home/casey/repos/gcc/gcc/cp/parser.c:27954 0x95f04c cp_parser_template_declaration_after_parameters /home/casey/repos/gcc/gcc/cp/parser.c:27546 0x95f98d cp_parser_explicit_template_declaration /home/casey/repos/gcc/gcc/cp/parser.c:27792 0x95f98d cp_parser_template_declaration_after_export /home/casey/repos/gcc/gcc/cp/parser.c:27811 0x960cbd cp_parser_member_declaration /home/casey/repos/gcc/gcc/cp/parser.c:24070 0x93b07a cp_parser_member_specification_opt /home/casey/repos/gcc/gcc/cp/parser.c:23997 0x93b07a cp_parser_class_specifier_1 /home/casey/repos/gcc/gcc/cp/parser.c:23141 0x93d049 cp_parser_class_specifier /home/casey/repos/gcc/gcc/cp/parser.c:23403 0x93d049 cp_parser_type_specifier /home/casey/repos/gcc/gcc/cp/parser.c:17259 0x93e03b cp_parser_decl_specifier_seq /home/casey/repos/gcc/gcc/cp/parser.c:13982 0x93e773 cp_parser_simple_declaration /home/casey/repos/gcc/gcc/cp/parser.c:13287 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.
[Bug c++/88419] [9 Regression] [ICE] "Same canonical type node for different types" for CTAD in noexcept
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88419 --- Comment #3 from Casey Carter --- 8.2 and 7.4 don't ICE: https://godbolt.org/z/VznOao. I was assuming that r266224 (the fix for #52869) likely caused the regression, although I haven't investigated.
[Bug c++/88515] New: [concepts] id-expression that names non-static data member rejected in requires-expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88515 Bug ID: 88515 Summary: [concepts] id-expression that names non-static data member rejected in requires-expression Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Compiling this TU: template concept bool C = requires { T::value; }; struct S { int value; }; static_assert(C); with "g++ -std=c++2a -fconcepts -c" produces: /home/casey/casey/Desktop/repro2.cpp:5:15: error: invalid use of non-static data member ‘S::value’ 5 | static_assert(C); | ^~~~ /home/casey/casey/Desktop/repro2.cpp:4:16: note: declared here 4 | struct S { int value; }; |^ /home/casey/casey/Desktop/repro2.cpp:5:15: error: static assertion failed 5 | static_assert(C); | when it should compile successfully since an id-expression that denotes a non-static data member can appear in an unevaluated operand ([expr.prim.id]/2.3) and expressions appearing within a requirement-body are unevaluated operands ([expr.prim.req]/2).
[Bug c++/88419] [7/8/9 Regression] [ICE] "Same canonical type node for different types" for CTAD in noexcept
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88419 Casey Carter changed: What|Removed |Added Keywords|accepts-invalid | --- Comment #6 from Casey Carter --- Clarifying: The sample TU is valid; It's rejected by GCC 6 because that version does not support C++17 class template argument deduction. I claim that the bug is a regression because 7/8 compile it correctly in default mode, and 9 does not. Yes, it's incorrectly rejected by 7 and 8 as well when compiling with -fchecking=1, so it's *not* a regression that 9 rejects the code with -fchecking=1.
[Bug c++/88829] New: Failure to deduce size of array of 2^31 chars
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88829 Bug ID: 88829 Summary: Failure to deduce size of array of 2^31 chars Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- This sample TU: using size_t = decltype(sizeof(int)); template T&& declval(); template void f(T(&&)[N]) {} using U = decltype(f(declval())); // error: size of array is negative fails to compile on trunk with "g++ -std=c++2a repro.cpp", diagnosing: :8:51: error: no matching function for call to 'f(char [2147483648])' 8 | using U = decltype(f(declval())); // error: size of array is negative | ^ :6:6: note: candidate: 'template void f(T (&&)[N])' 6 | void f(T(&&)[N]) {} | ^ :6:6: note: template argument deduction/substitution failed: : In substitution of 'template void f(T (&&)[N]) [with T = char; long unsigned int N = 18446744071562067968]': :8:51: required from here :6:6: error: size of array is negative :6:8: error: size of array is negative 6 | void f(T(&&)[N]) {} |^~~~ :8:49: error: invalid initialization of reference of type 'char (&&)[1]' from expression of type 'char [2147483648]' 8 | using U = decltype(f(declval())); // error: size of array is negative | ~~~^~ :6:8: note: in passing argument 1 of 'void f(T (&&)[N]) [with T = char; long unsigned int N = 18446744071562067968]' 6 | void f(T(&&)[N]) {} |^~~~ If arrays of size >= 2^31 aren't supported - which is a perfectly legitimate implementation limit - I expect the formation of the array type to be diagnosed rather than the deduction to fail. Also, the "size of array is negative" diagnostic is confusing (#87996 already makes that point).
[Bug libstdc++/70303] Value-initialized debug iterators
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70303 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #4 from Casey Carter --- (In reply to Jonathan Wakely from comment #3) > Or is the implication of equality being valid that a+n is valid for n==0, > and therefore b-a is valid, and therefore relational ops are valid? Certainly b-a is required to be valid, since such an n exists as required by [random.access.iterators] - but admittedly the IS doesn't specify the domain for relational comparisons on Cpp17 iterators. IMO this is a defect since it implies you can *never* compare two iterators with e.g. <. We should require the domain of relational comparisons to be the same as the domain of equality, which would then make it clear that value-initialized iterators are in their domain. (I was under the impression that we *did* require this "somewhere" when I filed this issue and fixed MSFTL's iterators.)
[Bug libstdc++/70303] Value-initialized debug iterators
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70303 --- Comment #5 from Casey Carter --- IIRC my reasoning was that [random.access.iterators] specifies the operational semantics of `a < b` to be `b - a > 0`, which suggests but doesn't quite require that `a < b` is valid whenever `b - a` is valid.
[Bug c++/85555] Use of concepts gives access to private members.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=8 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #1 from Casey Carter --- Duplicate of 67225 and/or 78715.
[Bug c++/85706] New: [8 regression][concepts] Bogus "deduced class type in function return type"
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85706 Bug ID: 85706 Summary: [8 regression][concepts] Bogus "deduced class type in function return type" Product: gcc Version: 8.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Compiling this program: template struct S { S(T); }; template auto f() -> decltype(S(42)); // error with "-std=c++17 -fconcepts" produces diagnostics: /home/casey/casey/Desktop/repro.cpp:6:6: error: deduced class type ‘S’ in function return type auto f() -> decltype(S(42)); // Line 6 ^ /home/casey/casey/Desktop/repro.cpp:1:26: note: ‘template struct S’ declared here template struct S { ^ the program compiles without diagnostic if f is a non-template: template struct S { S(T); }; auto f() -> decltype(S(42));
[Bug c++/85765] [8/9 Regression] Missing SFINAE in default template argument
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85765 --- Comment #4 from Casey Carter --- Narrowing the error down: template())), decltype(*U(),0) = 0> U g(T& t, long) { return begin(t); } // #1 prog.cc: In instantiation of 'U g(T&, long int) [with T = volatile il; U = int*; decltype (((* U()), 0)) = 0]' The "U = int*" is particularly damning here: it tells us the compiler substituted `volatile il` into `decltype(begin(declval()))` to get `begin(declval())`. `int* begin(il);` is a *candidate* for overload resolution - it has the right name and number of parameters - and it's a viable candidate because the ICS from lvalue `volatile il` to `il` is an identity conversion per [over.best.ics]/6: "Any difference in top-level cv-qualification is subsumed by the initialization itself and does not constitute a conversion. ... When the parameter has a class type and the argument expression has the same type, the implicit conversion sequence is an identity conversion." Since it's the *only* viable function, it is unambiguously the *best* viable function. So the only question here is why the compiler omits the final analysis that would determine that initialization of an `il` from a `volatile il&` is ill-formed - making the entire function call expression ill-formed - but only does so when the following `decltype(*U(),0) = 0` is present in the template parameter list.
[Bug c++/85806] New: [concepts] Hard error for "invalid use of non-static data member" in a requires expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85806 Bug ID: 85806 Summary: [concepts] Hard error for "invalid use of non-static data member" in a requires expression Product: gcc Version: 8.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Compiling this program fragment with g++ -std=c++17 -fconcepts (https://godbolt.org/g/L1b6TS): template using helper = void; template concept bool HasCount = requires { typename ::helper; }; struct S { int count = 42; }; static_assert(!HasCount); produces a diagnostic: :11:18: error: invalid use of non-static data member 'S::count' static_assert(!HasCount); ^~~ :9:19: note: declared here int count = 42; ^~ rather than the expected successful and silent compile.
[Bug c++/85808] New: [concepts] unqualified name lookup breaks after qualified lookup in nested requirement
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85808 Bug ID: 85808 Summary: [concepts] unqualified name lookup breaks after qualified lookup in nested requirement Product: gcc Version: 8.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Compiling this program fragment with "g++ -std=c++17 -fconcepts" (https://godbolt.org/g/EXDoD3): namespace X { template constexpr bool x = true; } template using helper = void; template concept bool C = requires { requires X::x; #ifndef WORKAROUND typename helper; #else typename ::helper; // Workaround #endif }; static_assert(C); produces diagnostics: :11:14: error: 'X::helper' has not been declared typename helper; ^~ :11:24: error: expected ';' before '>' token typename helper; ^ ; :11:24: error: expected '}' before '>' token :8:27: note: to match this '{' concept bool C = requires { ^ :11:25: error: expected primary-expression before ';' token typename helper; ^ :15:1: error: expected declaration before '}' token }; ^ rather than the expected successful and silent compile.
[Bug c++/85892] New: value-initialization failure
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85892 Bug ID: 85892 Summary: value-initialization failure Product: gcc Version: 8.0.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- This test program aborts because `collector`'s base `item` isn't properly zero-initialized: void* operator new(decltype(sizeof(int)), void* ptr) { return ptr; } struct item { int data; }; struct collector : item { collector() = default; collector(int) {} }; struct tuple : collector { tuple() : collector{} {} }; int main() { alignas(tuple) unsigned char space[sizeof(tuple)]; for (auto& c : space) c = 0xff; auto ptr = ::new(&space) tuple; int& i = static_cast(*ptr).data; if (i != 0) __builtin_abort(); } Default-initialization of `tuple` invokes its constructor, which value-initializes its `collector` base subobject, which should zero-initialize `collector`'s `item` base subobject.
[Bug c++/85892] value-initialization failure
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85892 Casey Carter changed: What|Removed |Added Status|NEW |RESOLVED CC||Casey at Carter dot net Resolution|--- |DUPLICATE --- Comment #2 from Casey Carter --- (In reply to Jonathan Wakely from comment #1) > Is this a dup of Bug 65816 comment 1? Almost exactly: the sole difference being that 65816 comment 1 observes failure to zero-init a *member* subobject, and this report observes failure to zero-init a *base* subobject. I'll add this repro to 65816. *** This bug has been marked as a duplicate of bug 65816 ***
[Bug c++/65816] Constructor delegation does not perform zero-initialization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65816 --- Comment #4 from Casey Carter --- *** Bug 85892 has been marked as a duplicate of this bug. ***
[Bug c++/65816] Constructor delegation does not perform zero-initialization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65816 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #3 from Casey Carter --- I ran across an almost identical case, but involving a base subobject which isn't properly zero-initialized rather than the member subobject case in comment 1: void* operator new(decltype(sizeof(int)), void* ptr) { return ptr; } struct item { int data; }; struct collector : item { collector() = default; collector(int) {} }; struct tuple : collector { tuple() : collector{} {} }; int main() { alignas(tuple) unsigned char space[sizeof(tuple)]; for (auto& c : space) c = 0xff; auto ptr = ::new(&space) tuple; int& i = static_cast(*ptr).data; if (i != 0) __builtin_abort(); } Default-initialization of `tuple` invokes its constructor, which value-initializes its `collector` base subobject, which should zero-initialize `collector`'s `item` base subobject.
[Bug c++/82507] [concepts] premature substitution into constraint of non-template member function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82507 --- Comment #1 from Casey Carter --- Gentle ping: working around this bug is making it incredibly hard to prototype the Ranges design for C++20.
[Bug c++/84140] Inline friends are not constrained by concepts
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84140 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #1 from Casey Carter --- Another repro: template constexpr bool is_same_v = false; template constexpr bool is_same_v = true; template concept bool Same = is_same_v; template concept bool Diff = requires(T& t, U& u) { u - t; }; template int distance(I, S) { return 0; } template S> int distance(I first, S last) { return last - first; } template struct I { template requires Same friend int operator-(I const&, I const&) { static_assert(Same); return 42; } }; int main() { return distance(I{}, I{}); } Compiling fails when the static_assert in the body of the friend function template - which simply asserts that the constraint on the template is satisfied - fires. It would appear the constraints aren't being checked for satisfaction at all on hidden friends found during overload resolution. FWIW, this makes it impossible to implement the Ranges proposal as specified.
[Bug c++/84140] Inline friends are not constrained by concepts
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84140 --- Comment #2 from Casey Carter --- *** Bug 69096 has been marked as a duplicate of this bug. ***
[Bug c++/69096] [concepts] return type deduction before checking constraint satisfaction
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69096 Casey Carter changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |DUPLICATE --- Comment #1 from Casey Carter --- This bug is actually a mislabeled occurrence of #84140. *** This bug has been marked as a duplicate of bug 84140 ***
[Bug c++/67491] [meta-bug] concepts issues
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491 Bug 67491 depends on bug 69096, which changed state. Bug 69096 Summary: [concepts] return type deduction before checking constraint satisfaction https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69096 What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |DUPLICATE
[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 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #2 from Casey Carter --- It would be nice to fix this on gcc-9-branch as well so clang w/concepts can use libstdc++.
[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 --- Comment #7 from Casey Carter --- Thanks, Jonathan. I can confirm that grepping for "\b(concept|requires)\b" finds a great many uses in comments, but only the one concept definition and one requires-clause in .
[Bug c++/67491] [meta-bug] concepts issues
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491 Bug 67491 depends on bug 67427, which changed state. Bug 67427 Summary: [concepts] Subsumption dependence on template parameter ordering https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67427 What|Removed |Added Status|NEW |RESOLVED Resolution|--- |INVALID
[Bug c++/67427] [concepts] Subsumption dependence on template parameter ordering
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67427 Casey Carter changed: What|Removed |Added Status|NEW |RESOLVED CC||Casey at Carter dot net Resolution|--- |INVALID --- Comment #2 from Casey Carter --- (In reply to Andrew Sutton from comment #1) > I believe that the ambiguity is correct under the revised semantics of > concepts. I agree. Happy fourth birthday, #67427 - we'll miss you.
[Bug c++/91923] New: [9/10 Regression] Failure-to-SFINAE with class type NTTP in C++17
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91923 Bug ID: 91923 Summary: [9/10 Regression] Failure-to-SFINAE with class type NTTP in C++17 Product: gcc Version: 9.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Compiling this well-formed TU (https://godbolt.org/z/8HYWSC): template constexpr bool is_integral_(...) { return false; } template constexpr bool is_integral_(long) { return true; } static_assert(is_integral_(42)); static_assert(!is_integral_(42)); struct S {}; static_assert(!is_integral_(42)); with -std=c++17 diagnoses: : In substitution of 'template > constexpr bool is_integral_(long int) [with T = S; T = ]': :14:34: required from here :5:26: error: non-type template parameters of class type only available with '-std=c++2a' or '-std=gnu++2a' 5 | template | ^ Compiler returned: 1 whereas earlier compiler versions (at least 6 though 8) accept the TU without diagnostic. This seems to simply be a case of adding the helpful new diagnostic but forgetting to silence it in SFINAE context.
[Bug c++/71125] [concepts] Spurious 'invalid reference to function concept error' issued when overloads are not all declared with the concept specifier
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71125 --- Comment #2 from Casey Carter --- (In reply to Jonathan Wakely from comment #1) > Is this valid in C++20? Definitely not: there are no concept functions in C++20. > > I think G++ is correct to reject it due to redeclaring C1, C2 etc. as a > different kind of symbol. I agree. Only functions and function templates may be overloaded, and despite appearances to the contrary a function concept declaration declares a concept, not a function template. I suggest classifying this as a poor diagnostic for TS concepts.
[Bug c++/89300] C++ requires statement does not fail silently for const void *
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89300 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #1 from Casey Carter --- This seems to be a duplicate of #78173.
[Bug c++/82380] [concepts] Error when using requires constraint with attributes
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82380 --- Comment #2 from Casey Carter --- You can work around this bug by using a trailing requires-clause instead of putting the requires-clause in the template-head.
[Bug libstdc++/89610] Move-assigning a pmr container sometimes copies the elements instead of moving them
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89610 --- Comment #2 from Casey Carter --- This isn't a "missed-optimization", it's non-conforming behavior. The Allocator-aware container requirements (http://eel.is/c++draft/container.requirements.general#16.sentence-41) require only that the element type is Cpp17MoveAssignable and Cpp17MoveInsertable into the container type, so copies - even if the syntax is valid - cannot achieve the required postcondition that the target of the move assignment is equal to the value the source of the move assignment had before moving.
[Bug c++/86044] noexcept(false) of constexpr member function ignored
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86044 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #1 from Casey Carter --- In C++14, this is conforming behavior per N4140 [expr.unary.noexcept]/3: """ 3. The result of the noexcept operator is false if in a potentially-evaluated context the expression would contain 3.1 - a potentially-evaluated call to a function, member function, function pointer, or member function pointer that does not have a non-throwing exception-specification, unless the call is a constant expression, [...] """ In C++17 and later, it is not conforming per [expr.unary.noexcept]/3: """ 3 The result of the noexcept operator is true unless the expression is potentially-throwing ([except.spec]). "" and [except.spec]/6 which defines "potentially-throwing" and includes no mention of constant expressions (I won't duplicate the full text here).
[Bug c++/82171] Cant use std::declval in concept testing map operator[]
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82171 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #4 from Casey Carter --- Likely a duplicate of 68781.
[Bug c++/90675] New: [concepts] expressions in compound requirements not correctly treated as unevaluated operands
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90675 Bug ID: 90675 Summary: [concepts] expressions in compound requirements not correctly treated as unevaluated operands Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 46430 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46430&action=edit Minimal repro Compiling this well-formed TU: template constexpr bool always_false = false; template struct S { void f() { static_assert(always_false); } }; template concept True = true; template concept C = requires(T t) { #ifndef WORKAROUND { t.f() } -> True; #else t.f(); requires True; #endif }; int main() { static_assert(C>); } with "g++ -std=c++2a -fconcepts" (same behavior for all versions from 6.1 to today's trunk) diagnoses (https://godbolt.org/z/cHC8PE): : In instantiation of 'void S::f() [with T = void]': :25:19: required from here :7:19: error: static assertion failed 7 | static_assert(always_false); | ^~~ Compiler returned: 1 Defining "WORKAROUND" allows the program to compile correctly, since the expression appears in a simple-requirement rather than a compound-requirement.
[Bug c++/90734] New: [concepts] Pre-normalization substitution into constraints of templated function breaks subsumption
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90734 Bug ID: 90734 Summary: [concepts] Pre-normalization substitution into constraints of templated function breaks subsumption Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 46447 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46447&action=edit Repro Compiling this program: template inline constexpr bool bool_ = B; #if defined(WORKAROUND) template concept bool Same_impl = __is_same_as(T, U); #else template concept bool Same_impl = bool_<__is_same_as(T, U)>; #endif template concept bool Same = Same_impl && Same_impl; template concept bool Foo = Same; template concept bool Bar = Foo && Same; template struct S1 { // overload set incorrectly is ambiguous (should resolve to second overload) static constexpr bool f() requires Foo { return false; } static constexpr bool f() requires Bar { return true; } }; template struct S2 { // overload set incorrectly is not ambiguous (resolves to third overload) static constexpr bool f() requires Foo { return false; } static constexpr bool f() requires Bar { return false; } static constexpr bool f() requires bool_ && true { return true; } }; template concept bool can_f = requires { T::f(); }; int main() { static_assert(Foo); static_assert(Bar); static_assert(can_f>); // Fails static_assert(S1::f());// Bogus error static_assert(!can_f>); // Fails #ifndef WORKAROUND static_assert(S2::f());// Bogus non-error #endif } with "-std=c++2a -fconcepts" produces diagnostics: /home/casey/casey/Desktop/repro.cpp: In function ‘int main()’: /home/casey/casey/Desktop/repro.cpp:43:19: error: static assertion failed 43 | static_assert(can_f>); // Fails | ^~ /home/casey/casey/Desktop/repro.cpp:44:30: error: call of overloaded ‘f()’ is ambiguous 44 | static_assert(S1::f());// Bogus error | ^ /home/casey/casey/Desktop/repro.cpp:24:27: note: candidate: ‘static constexpr bool S1::f() requires Foo [with T = int]’ 24 | static constexpr bool f() requires Foo { return false; } | ^ /home/casey/casey/Desktop/repro.cpp:25:27: note: candidate: ‘static constexpr bool S1::f() requires Bar [with T = int]’ 25 | static constexpr bool f() requires Bar { return true; } | ^ /home/casey/casey/Desktop/repro.cpp:46:19: error: static assertion failed 46 | static_assert(!can_f>); // Fails | ^~~ when it should diagnose only the static_assert on line 48. Bar subsumes Foo, so S1::f should be unambiguous. Conversely, Neither Bar nor bool_ && true subsumes the other, so S2::f should be ambiguous. The compiler's disagreement with both of these facts suggests premature substitution replacing bool_<__is_same_as(T, T)> and bool_<__is_same_as(const T&, const T&)> with bool_ *before* determination of subsumption in overload resolution. That replacement would result in Foo being replaced with bool_ && bool_, and Bar being replaced with bool_ && bool_ && bool_ && bool_ which *would* produce the observed behavior during overload resolution.
[Bug c++/90734] [concepts] Pre-normalization substitution into constraints of templated function breaks subsumption
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90734 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #1 from Casey Carter --- Note that this may be a duplicate of #82507, or more precisely a different expression of the same mechanism that causes #82507. Handy Compiler Explorer link with repro: https://godbolt.org/z/-vPUJx.
[Bug c++/86493] New: [concepts] Hard error for "call to non-'constexpr' function" in a requires expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86493 Bug ID: 86493 Summary: [concepts] Hard error for "call to non-'constexpr' function" in a requires expression Product: gcc Version: 8.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Compiling this well-formed program: template concept bool Concept = T::f() == 0; struct bad { static int f() { return 0; } }; int main() { static_assert(!Concept); } with -fconcepts and GCC 6.3/7.3/8.1/trunk diagnoses: : In function 'int main()': :2:30: error: call to non-'constexpr' function 'static int bad::f()' concept bool Concept = T::f() == 0; ^~ instead of correctly failing the concept check.
[Bug c++/78173] Hard error subtracting pointers to incomplete type in SFINAE context
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78173 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net Blocks||67491 --- Comment #1 from Casey Carter --- This still reproduces on trunk, and in concepts land. This program fragment: template concept bool CanDifference = requires(T const& x, T const& y) { x - y; }; static_assert(!CanDifference); produces diagnostics when compiled with "g++ -std=c++2a -fconcepts" (https://godbolt.org/g/e36eFK): :3:7: error: invalid use of 'void' x - y; ~~^~~ Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491 [Bug 67491] [meta-bug] concepts issues
[Bug c++/67491] [meta-bug] concepts issues
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491 Bug 67491 depends on bug 86493, which changed state. Bug 86493 Summary: [concepts] Hard error for "call to non-'constexpr' function" in a requires expression https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86493 What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID
[Bug c++/86493] [concepts] Hard error for "call to non-'constexpr' function" in a requires expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86493 Casey Carter changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #1 from Casey Carter --- [temp.constr.atomic]/3 states: To determine if an atomic constraint is satisfied, the parameter mapping and template arguments are first substituted into its expression. If substitution results in an invalid type or expression, the constraint is not satisfied. Otherwise, the lvalue-to-rvalue conversion is performed if necessary, and E shall be a constant expression of type bool. "E shall be a constant expression" clearly indicates that a substitution that produces a non-constant-expression is ill-formed, rather than causing the constraint not to be satisfied. This is a defect in the language rather than a bug in GCC.
[Bug c++/87814] New: [9 Regression] ICE in in tsubst_copy, at cp/pt.c:15962 with range-v3
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87814 Bug ID: 87814 Summary: [9 Regression] ICE in in tsubst_copy, at cp/pt.c:15962 with range-v3 Product: gcc Version: 9.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 44932 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44932&action=edit Preprocessed repro This program (preprocessed repro attached as repro.i.gz): #include #include #include int main() { using namespace ranges; auto f = [](int) { return iterator_range(); }; join_view> rng; (void) rng.begin(); } ICEs in tsubst_copy while instantiating a variadic inherited constructor template that performs a "double" pack expansion, defined around line 43341 in the repro.
[Bug c++/67185] [C++14] Link error on ODR-use of variable template partial specialization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67185 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net Version|6.0 |5.3.0 Blocks|67491 | Summary|[concepts] Link error on|[C++14] Link error on |ODR-use of constexpr|ODR-use of variable |constrained variable|template partial |template partial|specialization |specialization | --- Comment #1 from Casey Carter --- This same bug is triggered by the purely C++14 program: template bool x = false; template bool x = true; bool& f() { return x; } int main() {} which when compiled with either g++ 5.3 or 6 results in /tmp/ccHHu1ip.o: In function `f()': prog.cc:(.text+0x5): undefined reference to `x' collect2: error: ld returned 1 exit status The problem has nothing to do with concepts or constexpr, but seems to be a general issue when ODR-using an instance of a template variable that was instantiated from a partial specialization. I'm recasting this as a C++14 bug against 5.3. Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491 [Bug 67491] [meta-bug] concepts issues
[Bug c++/67210] [concepts] Error parsing ">>" after a template-id that names a concept
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67210 Casey Carter changed: What|Removed |Added Attachment #36183|0 |1 is obsolete|| CC||Casey at Carter dot net --- Comment #1 from Casey Carter --- Created attachment 37879 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37879&action=edit Minimal non-concepts (C++14) test case
[Bug c++/67185] [C++14] Link error on ODR-use of variable template partial specialization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67185 Casey Carter changed: What|Removed |Added Attachment #36170|0 |1 is obsolete|| --- Comment #2 from Casey Carter --- Created attachment 37880 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37880&action=edit Minimal non-concepts (C++14) test case
[Bug c++/60799] access checking within injected friend functions does not happen in the context of the enclosing class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60799 --- Comment #1 from Casey Carter --- This bug is present in both 5.3 and 6.0; it should probably be attached to the friend meta-bug 65608 since it is a "friend" issue.
[Bug libstdc++/70303] New: Value-initialized debug iterators
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70303 Bug ID: 70303 Summary: Value-initialized debug iterators Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Since C++14 requires value-initialized Forward iterators to compare equal, and subtraction/ordering of RandomAccess iterators is based on equality, this program should run to completion: #define _GLIBCXX_DEBUG #include #include int main() { using I = std::vector::iterator; assert(I{} == I{}); assert(!(I{} != I{})); assert(I{} - I{} == 0); assert(!(I{} < I{})); assert(!(I{} > I{})); assert(I{} <= I{}); assert(I{} >= I{}); } instead of reporting "Error: attempt to compare a singular iterator to a singular iterator." for any of the listed iterator operations.
[Bug c++/70522] New: Hidden friend functions block qualified name lookup into nested unnamed namespace
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70522 Bug ID: 70522 Summary: Hidden friend functions block qualified name lookup into nested unnamed namespace Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- This program should compile without error: namespace N { struct S { friend void f(S&) {} }; namespace { int f; } } int main() { N::f = 42; } yet GCC 6 diagnoses: prog.cc: In function 'int main()': prog.cc:11:5: error: 'f' is not a member of 'N' N::f = 42; ^ prog.cc:11:5: note: suggested alternative: prog.cc:6:13: note: 'N::{anonymous}::f' int f; ^ The program compiles correctly if either the friend declaration of f is commented out, or the unnamed namespace is made an inline namespace. Language lawyer justification: The friend declaration of f is not visible to name lookup of N::f per [namespace.memdef]/3, so the set of declarations S'(N,f) described in [namespace.qual]/2 is empty. Name lookup should continue into namespaces "nominated by using directives" in N; unnamed namespaces are such namespaces per [namespace.unnamed]/1.
[Bug c++/60799] access checking within injected friend functions does not happen in the context of the enclosing class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60799 --- Comment #2 from Casey Carter --- [basic.lookup.unqual]/9 says that name *lookup* inside friend functions defined inline works as it does in member functions, but that doesn’t necessarily imply that the friend function should have the same *access* as member functions would to the names so found (excepting, of course, names of the class being defined). Given [class.friend]/2: Declaring a class to be a friend implies that the names of private and protected members from the class granting friendship can be accessed in the base-specifiers and member declarations of the befriended class. and [class.mem]/1: … Except when used to declare friends (11.3), to declare an unnamed bit-field (9.6), or to introduce the name of a member of a base class into a derived class (7.3.3), or when the declaration is an empty-declaration, member-declarations declare members of the class, and each such member-declaration shall declare at least one member name of the class. … It's "clear" that a friend declaration is a member-declaration which – oddly enough – does not declare a member. So the critical question is whether the wording “and member declarations” in [class.friend]/2 means “declarations that are syntactically member-declarations” or “declarations of members.” I'm inclined to the second interpretation, which would imply the behavior described in this bug report is what the standard intends.
[Bug c++/60799] access checking within injected friend functions does not happen in the context of the enclosing class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60799 --- Comment #3 from Casey Carter --- > I'm inclined to the second interpretation, which would imply the behavior > described in this bug report is what the standard intends. This is me stumbling over my words attempting to say "I think this is NOT a bug."
[Bug c++/60799] access checking within injected friend functions does not happen in the context of the enclosing class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60799 --- Comment #5 from Casey Carter --- (In reply to TC from comment #4) > > I don't think that reading makes much sense. Among member-declarations that > do not declare a member are static_assert-declarations and unnamed bit-field > declarations, so that reading disallows > > class A { > constexpr static bool value = true; > friend class B; > }; > > class B { > static_assert(B::value, ""); > }; > > And disallows D in the below example but not E: > > class C { > constexpr static int value = 4; > friend class D; > friend class E; > }; > > class D { > int : C::value; > }; > > class E { > int i : C::value; > }; I agree that my interpretation breaks things that should work, but given how [class.mem]/1 goes out of its way to distinguish between member-declarations and "declarations of members", it does seem to be what is specified. I think the intent has been lost in the wording. I've just discovered this problem is the topic of open CWG issue 1699 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1699; upstream is already on-the-job.
[Bug c++/70522] Hidden friend functions block qualified name lookup into nested unnamed namespace
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70522 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #2 from Casey Carter --- This is a regression of sorts, FWIW, gcc 4.3 compiled it correctly (http://melpon.org/wandbox/permlink/Efjfvay0U5sZvZP8) back in the day. I assume that's not quite "regressive" enough for the 6 branch?
[Bug c++/70522] Hidden friend functions block qualified name lookup into nested unnamed namespace
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70522 --- Comment #5 from Casey Carter --- (In reply to Jason Merrill from comment #4) > (In reply to Casey Carter from comment #2) > > This is a regression of sorts, FWIW, gcc 4.3 compiled it correctly > > (http://melpon.org/wandbox/permlink/Efjfvay0U5sZvZP8) back in the day. I > > assume that's not quite "regressive" enough for the 6 branch? > > I was thinking of putting it in anyway, but that definitely strengthens the > case. :) Clearly GCC6 MUST NOT SHIP until this critical bug - which has gone unnoticed for years - is fixed. I would suggest elevating to P0 if it wasn't already resolved ;)
[Bug c++/71105] New: [6 regression] lambas with default captures improperly have function pointer conversions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71105 Bug ID: 71105 Summary: [6 regression] lambas with default captures improperly have function pointer conversions Product: gcc Version: 6.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 38483 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38483&action=edit Minimal test case N4582 [expr.prim.lambda]/7 says: The closure type for a non-generic lambda-expression with no lambda-capture has a conversion function to pointer to function with C++ language linkage (7.5) having the same parameter and return types as the closure type’s function call operator. ... For a generic lambda with no lambda-capture, the closure type has a conversion function template to pointer to function. The conversion function template has the same invented template-parameter-list, and the pointer to function has the same parameter types, as the function call operator template. ... So all of: static_cast([]{}); static_cast([](auto){}); static_cast([](auto x){ return x; }); should compile. These should all be ill-formed since the lambdas have lambda-captures: static_cast([i]{}); static_cast([=]{}); static_cast([&]{}); static_cast([i](auto){}); static_cast([=](auto){}); static_cast([&](auto){}); static_cast([i](auto x){ return x; }); static_cast([=](auto x){ return x; }); static_cast([&](auto x){ return x; }); clang (tested 3.4 - 3.9, all versions that implement generic lambdas) diagnoses all of these conversions as ill-formed; gcc (4.9.0 - 6.1.0, again all versions that implement generic lambdas) diagnoses only those with explicit captures. This issue is significant when a library composes function objects via private inheritance to take advantage of the empty base optimization and it adapts a (possibly) underconstrained generic lambda to a different/larger valid space of parameter types. For example, from range-v3: #include template struct indirected : F { indirected(F f) : F(f) {} template auto operator()(I i) -> decltype(std::declval()(*i)) { return static_cast(*this)(*i); } }; int main() { auto f = [=](auto i) { return i + i; }; auto i = indirected{f}; static_assert(std::is_same())), int>(), ""); } This program compiles correctly with the GCC 4.9 and 5 series compilers, 6.1 diagnoses the static_assert line (See http://melpon.org/wandbox/permlink/yy61pk0iJRfUVBya): prog.cc: In instantiation of 'main():: [with auto:1 = int*]': prog.cc:13:24: required by substitution of 'template main()operator decltype (((main()::)0u).operator()(static_cast())) (*)(auto:1)() const [with auto:1 = int*]' prog.cc:15:63: required from here prog.cc:13:37: error: invalid operands of types 'int*' and 'int*' to binary 'operator+' auto f = [=](auto i) { return i + i; }; ~~^~~
[Bug c++/71117] [6.1 regression] Overeager application of conversion to function pointer during overload resolution of call to function object
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71117 --- Comment #1 from Casey Carter --- Very closely related, but not an exact duplicate of, PR 71105.
[Bug c++/71173] New: [6 regression] Qualified name lookup
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71173 Bug ID: 71173 Summary: [6 regression] Qualified name lookup Product: gcc Version: 6.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- This program should compile without error: namespace foo { namespace bar { class foo {}; } class baz {}; } using namespace foo::bar; ::foo::baz mybaz; but GCC 6 reports (http://melpon.org/wandbox/permlink/2n9QQUT0UIXog2Cj): prog.cc:9:8: error: 'baz' in 'class foo::bar::foo' does not name a type ::foo::baz mybaz; ^~~ The name `::foo` should refer to the namespace `::foo`, not to the class `::foo::bar::foo` per [namespace.qual]/2: For a namespace X and name m, the namespace-qualified lookup set S(X,m) is defined as follows: Let S0(X,m) be the set of all declarations of m in X and the inline namespace set of X (7.3.1). If S0(X,m) is not empty, S(X,m) is S0(X,m); otherwise, S(X,m) is the union of S(Ni,m) for all namespaces Ni nominated by using-directives in X and its inline namespace set. S0(::,foo) is not empty, so namespaces nominated by using-directives should never be examined.
[Bug c++/71225] New: [7 Regression] Overeager instantiation of members of non-template class nested in class template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71225 Bug ID: 71225 Summary: [7 Regression] Overeager instantiation of members of non-template class nested in class template Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 38540 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38540&action=edit Repro r236559 fails to compile this TU: namespace std { template struct enable_if; } template struct BidirectionalRange; template struct stride_view { struct adaptor { template(), int>::type = 0> void clean() const {} template(), int>::type = 0> void clean() const {} void advance() { clean(); } }; }; with diagnostics: $ ~/gcc-r236559/bin/g++ repro2.cpp -c repro2.cpp: In member function ‘void stride_view::adaptor::advance()’: repro2.cpp:23:19: error: call of overloaded ‘clean()’ is ambiguous clean(); ^ repro2.cpp:15:14: note: candidate: void stride_view::adaptor::clean() const [with int _c_11 = 42; typename std::enable_if<((_c_11 == 43) || BidirectionalRange()), int>::type = 0; Rng = Rng] void clean() const ^ repro2.cpp:19:14: note: candidate: void stride_view::adaptor::clean() const [with int _c_14 = 42; typename std::enable_if<((_c_14 == 43) || (! BidirectionalRange())), int>::type = 0; Rng = Rng] void clean() const ^ This is a regression from the behavior of about a week ago.
[Bug c++/67185] [C++14] Link error on ODR-use of variable template partial specialization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67185 --- Comment #6 from Casey Carter --- ODR-use of different specializations of the same partially-specialized variable template still trigger the error in GCC 6 (Error: symbol `x' is already defined): template bool x = false; template bool x = true; int main() { return x + x; } Which may be covered by one of the other "partially-specialized variable template" bugs. Hmmm, looks like its in Tom's comment on the regression in 70095 (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70095#c2). If you're planning to address that comment - which I assume from the state changing to ASSIGNED moments ago - I'll leave this closed.
[Bug libstdc++/71364] [7 regression] recent tuple changes break range-v3 merge.cpp
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71364 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #4 from Casey Carter --- The bug is in range-v3 and the Ranges TS (https://github.com/ericniebler/stl2/issues/172) which was triggered by libc++ tuple changes on April 15 (https://github.com/ericniebler/range-v3/issues/324). Our specification of tagged - the template wrapper that implements tagged_pair and tagged_tuple - inherits constructors from Base but has no specific constructors that take Base const& or Base&&. Consequently conversions from Base have been using tuple/pair's converting constructor instead of the copy/move constructor. LWG2549 (http://cplusplus.github.io/LWG/lwg-active.html#2549) makes this not work anymore: the converting constructor refuses to accept argument expressions with the tuple's same type that should be using the copy/move constructors. This has been fixed in range-v3, but not yet in the Ranges TS.
[Bug c++/80633] New: [7/8 Regression] -Wstrict-aliasing false positive
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80633 Bug ID: 80633 Summary: [7/8 Regression] -Wstrict-aliasing false positive Product: gcc Version: 7.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 41321 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41321&action=edit Repro (sorry, not library-free) gcc 7.1.1 20170504 and 8.0.0 20170504 - but not 6.2/5.4/4.9.4 - incorrectly diagnose this program: #include extern void f(std::istream&); std::ifstream ss; using T = decltype(f(ss)); // warning: dereferencing type-punned pointer will break strict-aliasing rules when compiling with "gcc -Wstrict-aliasing -O2 -c". The diagnostic is notably not emitted for "decltype(f(std::declval()))".
[Bug c++/81026] New: Lookup of dependent member template incorrectly finds non-member
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81026 Bug ID: 81026 Summary: Lookup of dependent member template incorrectly finds non-member Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- GCC 4/5/6/7/8 diagnose this correct program: namespace std { template struct extent; } using namespace std; template struct S { void f() { T{}.template extent<42>(); } }; with: prog.cc: In member function 'void S::f()': prog.cc:9:38: error: type/value mismatch at argument 1 in template parameter list for 'template struct std::extent' void f() { T{}.template extent<42>(); } ^ prog.cc:9:38: note: expected a type, got '42'
[Bug c++/80633] [7/8 Regression] -Wstrict-aliasing false positive
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80633 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #2 from Casey Carter --- (In reply to Jason Merrill from comment #1) > I can't reproduce this with 20170619. Are you still seeing it? Nope - it appears to have disappeared on trunk.
[Bug c++/81178] New: [concepts] poor (partial?) diagnostic for alias substitution failure in a concept body
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81178 Bug ID: 81178 Summary: [concepts] poor (partial?) diagnostic for alias substitution failure in a concept body Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- GCC 6.3/7.1/trunk as of 20170621 all diagnose this ill-formed program (https://wandbox.org/permlink/uatmNSnlLbhvSvls): template concept bool C1 = true; template using alias = typename T::type; template concept bool C2 = C1>; void bar(C2) {} int main() { bar(42); } with: prog.cc: In function 'int main()': prog.cc:12:20: error: cannot call function 'void bar(auto:1) [with auto:1 = int]' int main() { bar(42); } ^ prog.cc:10:6: note: constraints not satisfied void bar(C2) {} ^~~ prog.cc:10:6: note: in the expansion of concept 'C2 template concept const bool C2 [with T = int]' (Yes, that is the entire diagnostic.) If we expand the definition of C2 fully into bar (https://wandbox.org/permlink/GKW0vWSPIY5XrGRE): template requires C1> void bar(T) {} the compiler gives a more complete diagnostic: prog.cc: In function 'int main()': prog.cc:14:20: error: cannot call function 'void bar(T) [with T = int]' int main() { bar(42); } ^ prog.cc:12:6: note: constraints not satisfied void bar(T) {} ^~~ prog.cc:12:6: note: invalid use of the concept 'C1' prog.cc:14:20: error: 'int' is not a class, struct, or union type int main() { bar(42); } ^
[Bug c++/78841] New: [6 regression] optimizer bug (silent bad codegen)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78841 Bug ID: 78841 Summary: [6 regression] optimizer bug (silent bad codegen) Product: gcc Version: 6.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- g++ 6.2 (not 5.4, or 4.9, or 4.8, or trunk) generates bad code for the attached repro at -O2 and higher. "silent bad codegen" just barely trumps "already fixed on trunk" to my mind, so here's a repro; my feelings won't be hurt if you WONTFIX this. Apologies for the huge repro, I've had a hard time reducing it from here without making the bug disappear.
[Bug c++/78841] [6 regression] optimizer bug (silent bad codegen)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78841 --- Comment #2 from Casey Carter --- Created attachment 40371 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40371&action=edit compressed preprocessed repro
[Bug c++/78841] [6 regression] optimizer bug (silent bad codegen)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78841 --- Comment #5 from Casey Carter --- I have verified that gcc-6-branch compiles the repro correctly, so yes, this is a dup of PR78047.
[Bug c++/79143] New: [7 Regression][new inheriting constructors] inheriting constructor fails with brace initialization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79143 Bug ID: 79143 Summary: [7 Regression][new inheriting constructors] inheriting constructor fails with brace initialization Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- r244608 with -std=c++1z fails to compile this program both with and without -fno-new-inheriting-constructors: struct base { base(int, int) {} }; template struct derived : base { using base::base; }; int main() { base(13, 42); // Fine derived(13, 42); // Fine base{13, 42}; // Fine derived{13, 42}; // Error } with diagnostics: prog.cc: In function 'int main()': prog.cc:14:22: error: too many initializers for 'derived' derived{13, 42}; // Error ^ prog.cc:14:22: error: could not convert '13' from 'int' to 'base'
[Bug c++/68858] Cannot use fold expression in requirements with two parameters packs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68858 --- Comment #1 from Casey Carter --- This seems to be a duplicate of PR 68812.
[Bug c++/79143] [7 Regression][new inheriting constructors] inheriting constructor fails with brace initialization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79143 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #4 from Casey Carter --- (In reply to Jonathan Wakely from comment #3) > I think this is a bug. derived is not an aggregate, because it inherits a > user-provided constructor, so braced-init should call the base(int, int) > constructor, not attempt aggregate init. This. N4618 [dcl.init.aggr]/1 says: 1 An aggregate is an array or a class with 1.1 --- no user-provided, explicit, or inherited constructors [...]
[Bug c++/67384] [concepts] More fun with deduction constraints
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67384 Casey Carter changed: What|Removed |Added Status|NEW |RESOLVED CC||Casey at Carter dot net Resolution|--- |FIXED --- Comment #1 from Casey Carter --- This no longer reproduces on 6.3 or trunk.
[Bug c++/67491] [meta-bug] concepts issues
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491 Bug 67491 depends on bug 67384, which changed state. Bug 67384 Summary: [concepts] More fun with deduction constraints https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67384 What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED
[Bug c++/67491] [meta-bug] concepts issues
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491 Bug 67491 depends on bug 67150, which changed state. Bug 67150 Summary: [c++-concepts] Expression constraint fails with dependent types used as a deduction constraint target https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67150 What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED
[Bug c++/67150] [c++-concepts] Expression constraint fails with dependent types used as a deduction constraint target
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67150 Casey Carter changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED CC||Casey at Carter dot net Resolution|--- |FIXED --- Comment #1 from Casey Carter --- This fails to reproduce on both GCC 6.3 and trunk.
[Bug c++/79591] New: [concepts] failure to distinguish overloads from different namespaces with differing constraints
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79591 Bug ID: 79591 Summary: [concepts] failure to distinguish overloads from different namespaces with differing constraints Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 40772 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40772&action=edit Minimal repro GCC 6.3 and trunk both miscompile this program: template concept bool True = true; // Fine. namespace X { void f(auto) {} void f(True) {} } void f(auto) {} namespace Y { void f(True) {} using ::f; // error: 'template void f(auto:3)' conflicts with a previous declaration } The compiler is happy to overload when the two abbreviated function templates are declared in the same scope - as in namespace X - but not when one is imported into the namespace via a using declaration.
[Bug c++/78715] [concepts] Access specifiers ignored after concept declaration
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78715 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #1 from Casey Carter --- Another simple program that reproduces this bug with 6.3 and trunk: template concept bool C1 = true; template concept bool C2 = requires { { 42 } -> C1; }; int main() { class A { int x; } a; a.x = 42; } Use of a partial-concept-id as a constrained-type-specifier seems to be the trigger.
[Bug c++/82740] New: [concepts] requires clause evaluated early
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82740 Bug ID: 82740 Summary: [concepts] requires clause evaluated early Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 42483 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42483&action=edit Repro Trunk as of 20170825 miscompiles this program (https://wandbox.org/permlink/70zH8c8JMQZMDUas): template concept bool C = requires(const T& t) { t.foo(); }; template struct Base { constexpr T const& derived() const { return static_cast(*this); } constexpr bool bar() const requires #ifndef WORKAROUND requires(const T& t) { t.foo(); } #else C #endif { derived().foo(); return true; } }; template struct Derived : Base> { constexpr void foo() const {} }; int main() { static_assert(Derived{}.bar()); } with diagnostics: prog.cc: In instantiation of 'struct Base >': prog.cc:17:8: required from 'struct Derived' prog.cc:22:32: required from here prog.cc:9:34: error: invalid use of incomplete type 'const struct Derived' requires(const T& t) { t.foo(); } ~~^~~ prog.cc:17:8: note: declaration of 'struct Derived' struct Derived : Base> { ^~~ despite that N4700 [temp.inst]/16 (http://eel.is/c++draft/temp.spec#temp.inst-16) specifies that: The partial-concept-ids and requires-clause of a template specialization or member function are not instantiated along with the specialization or function itself, even for a member function of a local class; substitution into the atomic constraints formed from them is instead performed as specified in [temp.constr.decl] and [temp.constr.atomic] when determining whether the constraints are satisfied. [ Note: The satisfaction of constraints is determined during name lookup or overload resolution ([over.match]). — end note ] (Note that the text of [temp.inst]/16 in the Concepts TS is similar.) If WORKAROUND is defined, replacing the ad hoc requirement with an identical named concept, the program compiles without diagnostics.
[Bug c++/67595] concepts code causes segfault
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67595 --- Comment #5 from Casey Carter --- The original program submission is ill-formed due to the requirement on line 270 being poorly designed: requires std::is_same::value; for a random access iterator x, "x - (x - x)" is typically a prvalue of the same type as x, whereas "x += (x - x)" is typically an lvalue of that type. X and X& are obviously not the same type.
[Bug c++/82247] [concepts] Name deduction in concepts fails depending on the argument type
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82247 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #4 from Casey Carter --- This is not a bug: it's two-phase name lookup. At the point of definition for Fooable: #include #include template bool concept Fooable = requires(const T& t) { { foo(t) }; // foo is unknown here }; the compiler records the set of declarations it has seen for "foo" (the empty set). When you later "instantiate" the concept foo can only resolve to (a) a member of the (again, empty) set recorded at definition, or (b) a declaration found by argument-dependent lookup. Since there are no associated namespaces for fundamental types, only your user-defined type which has a "foo" defined in its associated namespace successfully concept checks.
[Bug c++/82768] ICE in synthesize_implicit_template_parm, at cp/parser.c:39338
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82768 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net --- Comment #2 from Casey Carter --- (In reply to Martin Liška from comment #1) > Confirmed on all release that support -fconcepts. Is it a valid code? No. Using a placeholder type for the parameter of a requires expression is not supported. (Specifically, the Addressable parameter in the definition of InternalCompilerError.)
[Bug libstdc++/77537] New: pair constructors do not properly SFINAE
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77537 Bug ID: 77537 Summary: pair constructors do not properly SFINAE Product: gcc Version: 6.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 39586 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39586&action=edit Patch Both static_asserts in this program fail: #include #include struct moveonly { moveonly() = default; moveonly(moveonly&&) = default; }; template using P = std::pair; static_assert(!std::is_constructible, int, moveonly&>::value, "FAIL"); static_assert(!std::is_constructible, P>::value, "FAIL"); Because the resolution of PR 70437 makes many of the pair constructors inappropriately participate in overload resolution. Attached patch is a poorly-tested fix. (It works for this repro, and the repro in 70437, but caveat emptor.)
[Bug libstdc++/77537] pair constructors do not properly SFINAE
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77537 --- Comment #4 from Casey Carter --- Any chance of applying this to 6-branch as well? This is breaking both range-v3 and cmcstl2 in a nasty and hard-to-workaround way.
[Bug libstdc++/77537] [6 Regression] pair constructors do not properly SFINAE
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77537 --- Comment #11 from Casey Carter --- Thanks again Ville - I owe you a beer in Issaquah.
[Bug c++/78173] New: Hard error subtracting pointers to incomplete type in SFINAE context
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78173 Bug ID: 78173 Summary: Hard error subtracting pointers to incomplete type in SFINAE context Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 39934 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39934&action=edit Minimal repro This TU, which should compile without errors: template T&& declval(); template using void_t = void; template struct foo { static const bool value = false; }; template struct foo() - declval())>> { static const bool value = true; }; struct A; #define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__) STATIC_ASSERT(!foo::value); // error: invalid use of 'void' STATIC_ASSERT(!foo::value); // error: invalid use of incomplete type 'struct A' instead produces diagnostics (http://melpon.org/wandbox/permlink/EwcDiz7ZuqpFXdHZ): prog.cc: In substitution of 'template struct foo() - declval()))> > [with T = void*]': prog.cc:22:1: required from here prog.cc:10:44: error: invalid use of 'void' struct foo() - declval())>> { ~^~ prog.cc: In substitution of 'template struct foo() - declval()))> > [with T = A*]': prog.cc:23:1: required from here prog.cc:10:44: error: invalid use of incomplete type 'struct A' prog.cc:14:8: note: forward declaration of 'struct A' struct A; ^
[Bug c++/69288] [concepts] Subsumption failure with constrained member functions of class template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69288 Casey Carter changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED CC||Casey at Carter dot net Resolution|--- |FIXED --- Comment #1 from Casey Carter --- This no longer reproduces with 6.2 or trunk.
[Bug c++/66184] New: Rejection of partial specialization of a variable template in a non-global namespace
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66184 Bug ID: 66184 Summary: Rejection of partial specialization of a variable template in a non-global namespace Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 35558 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35558&action=edit testcase.cpp Both 5.1.0 on Wandbox and 6.0 r223061 reject this program: namespace foo { template constexpr bool same = false; template <> constexpr bool same = true; template constexpr bool same = true; static_assert(same, ""); static_assert(!same, ""); } int main() {} with error message: bug2.cpp:4:35: error: specialization of ‘template constexpr const bool foo::same< , >’ in different namespace [-fpermissive] template constexpr bool same = true; ^ bug2.cpp:2:40: error: from definition of ‘template constexpr const bool foo::same< , >’ [-fpermissive] template constexpr bool same = false; ^ The full specialization of same is accepted regardless of namespace. Both versions compile the program correctly if "same" is in the global namespace.
[Bug c++/66218] New: [c++-concepts] "inconsistent deduction for ‘auto’" with a partial-concept-id in a deduction constraint
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66218 Bug ID: 66218 Summary: [c++-concepts] "inconsistent deduction for ‘auto’" with a partial-concept-id in a deduction constraint Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 35576 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35576&action=edit testcase.cpp Compiling this correct program with r223444 of the c++-concepts branch: #include template concept bool Same = std::is_same::value; template concept bool C = requires(T t) { { t } -> Same; }; template constexpr bool f() { return false; } template constexpr bool f() { return true; } static_assert(f(), ""); static_assert(f(), ""); static_assert(f(), ""); int main() {} produces errors: bug2.cpp:19:22: error: inconsistent deduction for ‘auto’: ‘char’ and then ‘int’ static_assert(f(), ""); ^ bug2.cpp:19:1: error: static assertion failed: static_assert(f(), ""); ^ bug2.cpp:20:25: error: inconsistent deduction for ‘auto’: ‘char’ and then ‘double’ static_assert(f(), ""); ^ bug2.cpp:20:1: error: static assertion failed: static_assert(f(), ""); ^ It appears that the result of the first deduction is stored in memory instead of being discarded.
[Bug c++/66260] New: [C++14] Failure to compile variable template with recursively defined partial specialization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66260 Bug ID: 66260 Summary: [C++14] Failure to compile variable template with recursively defined partial specialization Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 35604 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35604&action=edit testcase.cpp Both GCC 5.1.0 and 6.0 fail to compile this program: template constexpr bool foo = false; template <> constexpr bool foo = true; template constexpr bool foo = foo; static_assert(foo, ""); static_assert(!foo, ""); static_assert(foo, ""); static_assert(!foo, ""); static_assert(foo, ""); static_assert(!foo, ""); int main() {} 5.1.0 doesn't seem to recognize that foo is a template-name in the definition of the foo partial specialization: prog.cc:6:33: error: expected primary-expression before '>' token constexpr bool foo = foo; ^ prog.cc:6:34: error: expected primary-expression before ';' token constexpr bool foo = foo; ^ prog.cc:6: confused by earlier errors, bailing out 6.0 20150522 at least tries to compile the recursion, but fails nonetheless: prog.cc: In instantiation of 'constexpr const bool foo': prog.cc:6:16: recursively required from 'constexpr const bool foo' prog.cc:6:16: required from 'constexpr const bool foo' prog.cc:10:15: required from here prog.cc:6:16: fatal error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum) constexpr bool foo = foo; ^ compilation terminated.
[Bug c++/66184] [C++14] Rejection of partial specialization of a variable template in a non-global namespace
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66184 Casey Carter changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED --- Comment #1 from Casey Carter --- Fixed in r223462.
[Bug c++/66184] [C++14] Rejection of partial specialization of a variable template in a non-global namespace
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66184 --- Comment #2 from Casey Carter --- Correction: r223462 was a fix on the c++-concepts branch, the trunk fix was r223461.
[Bug libstdc++/59768] New: [4.8 Regression] std::thread constructor not handling reference_wrapper correctly
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59768 Bug ID: 59768 Summary: [4.8 Regression] std::thread constructor not handling reference_wrapper correctly Product: gcc Version: 4.8.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Created attachment 31809 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=31809&action=edit Minimal test case. Originally reported in Stackoverflow question http://stackoverflow.com/questions/21059115/c11-thread-class-how-to-use-a-class-member-function Construction of a std::thread with a pointer-to-member-function and reference_wrapper as in this simple program: #include #include #include class A { public: void foo(int n) { std::cout << n << std::endl; } }; int main() { A a; std::thread t1(&A::foo, std::ref(a), 100); t1.join(); } incorrectly results in a compilation error: In file included from /usr/local/include/c++/4.8.2/thread:39:0, from check.cc:2: /usr/local/include/c++/4.8.2/functional: In instantiation of ‘struct std::_Bind_simple(std::reference_wrapper, int)>’: /usr/local/include/c++/4.8.2/thread:137:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (A::*)(int); _Args = {std::reference_wrapper, int}]’ check.cc:13:42: required from here /usr/local/include/c++/4.8.2/functional:1697:61: error:no type named ‘type’ in ‘class std::result_of(std::reference_wrapper, int)>’ typedef typename result_of<_Callable(_Args...)>::type result_type; ^ /usr/local/include/c++/4.8.2/functional:1727:9: error:no type named ‘type’ in ‘class std::result_of(std::reference_wrapper, int)>’ _M_invoke(_Index_tuple<_Indices...>) ^ I reduced the original program to: #include #include int main() { struct A { void foo(int) {} } a; std::thread(&A::foo, std::ref(a), 100).join(); } which still displays the erroneous behavior. Note that std::bind(&A::foo, std::ref(a), 100) *does* compile correctly, as does a similar program in which the member function foo has no parameter. Program is incorrectly compiled by g++ 4.8.2 and 4.8.1, correctly compiles with 4.6.4 and 4.7.3.
[Bug libstdc++/59768] [4.8 Regression] std::thread constructor not handling reference_wrapper correctly
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59768 --- Comment #1 from Casey Carter --- This behavior would appear to NOT be erroneous. I was operating under the assumption that the behavior of the std::thread constructor and std::bind were identical by design given that both use the "INVOKE" machinery defined by the standard in [func.require]/1. However, the replacement of reference_wrapper with its stored reference is specified only for std::bind in [func.bind.bind]/10: The values of the bound arguments v1, v2, ..., vN and their corresponding types V1, V2, ..., VN depend on the types TiD derived from the call to bind and the cv-qualifiers cv of the call wrapper g as follows: — if TiD is reference_wrapper, the argument is tid.get() and its type Vi is T&; This would then not be a regression in the 4.8 line, but a correction to a long-standing bug. I apologize for wasting your time with an erroneous bug report.
[Bug c++/67545] New: [concepts] Failure to properly substitute template parameters into requires-clause
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67545 Bug ID: 67545 Summary: [concepts] Failure to properly substitute template parameters into requires-clause Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- Created attachment 36323 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36323&action=edit Preprocessed test case r227603 fails to compile this correct TU: #include struct I { int operator*() const; }; template using Ref = decltype(*std::declval()); template requires !__stl2::Swappable, Ref>() static constexpr bool bar() { return true; } template requires !__stl2::Swappable, Ref>() static constexpr bool foo() { return true; } static_assert(bar()); // Fine static_assert(foo()); // Error with error: ~/gcc6/bin/g++ -std=gnu++1z -I ~/cmcstl2/include -I ~/cmcstl2/meta/include foo.cpp -c foo.cpp:19:19: error: cannot call function ‘constexpr bool foo() [with U = I]’ static_assert(foo()); // Error ^ foo.cpp:16:23: note: constraints not satisfied static constexpr bool foo() { return true; } ^ foo.cpp:16:23: note: ‘! Swappable, Ref >()’ evaluated to false Despite the fact that the requirements on foo and bar are functionally equivalent, the call to bar succeeds whilst the call to `bar` fails to compile. I conjecture that the substitution of template parameters into foo's requires clause is not working correctly.
[Bug c++/67545] [concepts] Failure to properly substitute template parameters into requires-clause
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67545 Casey Carter changed: What|Removed |Added Severity|normal |major --- Comment #1 from Casey Carter --- Raising importance to "major": I have a hunch that this may be the root cause of some of my other reported bugs.
[Bug c++/67579] New: [concepts] Memoization for constraint expressions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67579 Bug ID: 67579 Summary: [concepts] Memoization for constraint expressions Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- While implementing the Ranges TS I've found that the implementation of concepts in GCC scales very poorly to larger and more complex systems. I've been able to achieve 1-2 order of magnitude improvements in compile time and memory usage by hand coding memoization for some concepts with constexpr variable templates. E.g., replacing template concept bool Foo = // requirements with template constexpr bool Foo_ = false; template requires // requirements constexpr bool Foo_ = true; template concept bool Foo = Foo_; which is fine when Foo need not participate in subsumption relationships. If Foo *does* need to participate in subsumption relationships then performing this transformation by hand is not possible since it hides the relationship between Foo and "requirements" from the compiler's view. If concepts & constraint expressions are to be generally applicable the implementation must provide some means of reducing the cost of repeated evaluation.
[Bug c++/67810] New: Non-expression recognized as fold expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67810 Bug ID: 67810 Summary: Non-expression recognized as fold expression Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- r228351 fails to compile this correct program: template constexpr bool Test = true; template )> void f(); with error: ~/gcc6-r228351/bin/g++ -std=c++14 -c foo.cpp foo.cpp:4:41: warning: fold-expressions only available with -std=c++1z or -std=gnu++1z template )> ^ foo.cpp:4:47: error: expected binary operator before ‘)’ token template )> ^ foo.cpp:5:1: error: expected primary-expression before ‘void’ void f(); ^ foo.cpp:5:1: error: expected ‘>’ before ‘void’ foo.cpp:5:9: error: expected unqualified-id before ‘;’ token void f(); ^
[Bug c++/67810] Non-expression recognized as fold expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67810 Casey Carter changed: What|Removed |Added CC||Casey at Carter dot net, ||jason at gcc dot gnu.org --- Comment #1 from Casey Carter --- Presumably this bug was introduced by the implementation of fold expressions in r227883. CCing Jason.
[Bug c++/67813] New: [C++14] copy-initialization of object with pointer member fails in constexpr function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67813 Bug ID: 67813 Summary: [C++14] copy-initialization of object with pointer member fails in constexpr function Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Casey at Carter dot net Target Milestone: --- r223851 fails to compile this correct program fragment: struct Ptr { int* p; constexpr Ptr(int* p) noexcept : p{p} {} constexpr int& operator*() const { return *p; } }; constexpr int f(int& i) { //Ptr first{&i}; // Works. Ptr first = &i; // Error return *first; } constexpr int g() { int i = 42; return f(i); } static_assert(g() == 42); with error: ~/gcc6-r228351/bin/g++ -std=c++14 foo.cpp -c foo.cpp:21:1: error: non-constant condition for static assertion static_assert(g() == 42); ^ foo.cpp:21:16: in constexpr expansion of ‘g()’ foo.cpp:18:11: in constexpr expansion of ‘f(i)’ foo.cpp:13:11: in constexpr expansion of ‘first.Ptr::operator*()’ foo.cpp:21:1: error: accessing uninitialized member ‘Ptr::p’ If the local is instead direct-initialized with "Ptr first{&i};", the program correctly compiles without diagnostics. Results are identical if Ptr's member p is type int& (with the constructor and operator* updated accordingly).