[Bug c++/95511] Class template argument deduction: guide generated from constructor preferred over deduction-guide.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95511 Olivier Kannengieser changed: What|Removed |Added Resolution|--- |FIXED Status|UNCONFIRMED |RESOLVED --- Comment #2 from Olivier Kannengieser --- The bug is not more here in GCC version 10.2.
[Bug c++/96361] New: return type not deduced for a function template specialization given as argument of a template function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96361 Bug ID: 96361 Summary: return type not deduced for a function template specialization given as argument of a template function Product: gcc Version: 10.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- This bug exist since GCC 6.1 and is still present in version GCC 10.2 The following code should compile: template auto f(T v){ return v+v; } template void g(T && v); void h(){ g(f); //Error } GCC error message is: no matching function for call to 'g()' There is no error if the return type of f is not deduced or if some code is used to force the return type deduction. For exemple if the function h is changed to: void h(){ using x = decltype (f); g(f); // No error } the code compile.
[Bug c++/95417] Static storage duration objects that are constant initialized should be destroyed after the destruction of dynamically initialized object.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95417 Olivier Kannengieser changed: What|Removed |Added Resolution|FIXED |INVALID --- Comment #4 from Olivier Kannengieser --- It is thus an invalid bug.
[Bug c++/95417] Static storage duration objects that are constant initialized should be destroyed after the destruction of dynamically initialized object.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95417 Olivier Kannengieser changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED --- Comment #3 from Olivier Kannengieser --- I have just found a paragraph in the standard that specifies that GCC behavior is standard compliant, [basic.start.term]/3: "If an object is initialized statically, the object is destroyed in the same order as if the object was dynamically initialized."
[Bug c++/77595] concepts: constrained member functions illegally instantiated during explicit class template instantiation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77595 --- Comment #4 from Olivier Kannengieser --- The bug is still there in GCC 10.1, and was the cause of a question of stackoverflow: https://stackoverflow.com/questions/62659801/constrained-member-functions-and-explicit-template-instantiation
[Bug c++/95860] New: Wrong "looser exception specification" when a class has 2 prospective destructors.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95860 Bug ID: 95860 Summary: Wrong "looser exception specification" when a class has 2 prospective destructors. Product: gcc Version: 10.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- Tested with gcc --version: gcc (GCC) 10.1.1 20200613 Copyright (C) 2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. The following code should compile: struct A { virtual ~A() =default; }; template struct B :A { ~ B() =default; //destructor 1 ~ B() requires (C) =default;//destructor 2 }; int main(){ B b; } The destructor of B is the "destrurcor 2". Nevertheless, GCC complains that "destructor 1" has a looser exception specification than the base destructor: test.cpp: In instantiation of ‘struct B’: test.cpp:144:10: required from here test.cpp:138:2: error: looser exception specification on overriding virtual function ‘B::~B() [with bool C = true]’ 138 | ~ B() =default; | ^ test.cpp:131:10: note: overridden function is ‘virtual constexpr A::~A() noexcept’ 131 | virtual ~A() =default; | ^
[Bug c++/95511] Class template argument deduction: guide generated from constructor preferred over deduction-guide.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95511 --- Comment #1 from Olivier Kannengieser --- Actualy it is a bug that happens during the selection of the best viable function: template void func (auto...); void func (auto...); void g(){ func (10); // this should not compile } According to clang the call `func(10)` is ambiguous. But GCC select fun<,int>. This is precisely what it does for the deduction guide.
[Bug c++/95511] New: Class template argument deduction: guide generated from constructor preferred over deduction-guide.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95511 Bug ID: 95511 Summary: Class template argument deduction: guide generated from constructor preferred over deduction-guide. Product: gcc Version: 10.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- This bug exists since gcc 7 and all following version. It also exists on the current GCC-10 release branch. The following code should compile: template struct tpl { tpl (Ts...); }; template struct A : tpl { template A (Args...args) : tpl (args...) {} }; template A (Ts...) -> A ; A a {10}; //error: no matching function for call to 'tpl<>::tpl(int&)' Clang compile this code. Maybe overload resolution considers that the guide generated from the constructor of A is a better match than the one generated from the deduction-guide.
[Bug c++/95417] New: Static storage duration objects that are constant initialized should be destroyed after the destruction of dynamically initialized object.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95417 Bug ID: 95417 Summary: Static storage duration objects that are constant initialized should be destroyed after the destruction of dynamically initialized object. Product: gcc Version: 10.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- This is a bug that is here since at least GCC 5.1. Variable with static storage duration that are constant initialized should be destroyed after the destruction of all variables with static storage duration that are dynamically initialized. This is specified in the standard. This answer on SO, (by a C++ comity member I think) explain it: https://stackoverflow.com/a/27197836/5632316 This break the mental model that objects are destroyed in the reverse order of their construction (even if in this case this order is not sensible). The program whose code is bellow should output: non constant delete constant delete ``` But it output the opposite: non constant delete constant delete ``` #include struct NonConstant{ NonConstant(){ std::cout<<""; } ~NonConstant(){std::cout << "non constant delete" <
[Bug c++/95050] New: coroutine: no "mandatory copy elision" for prvalue await_resume expression.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95050 Bug ID: 95050 Summary: coroutine: no "mandatory copy elision" for prvalue await_resume expression. Product: gcc Version: 10.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- Checked with gcc version 10.1.1 20200508 (GCC) (see bellow for the `gcc -v` output) The result of the await-resume expression is not directly used to initialize the result of the co_await expression. This has the observable side effect to cause a (move) copy construction when the result the await-resume expression is a prvalue. I think the pertinent standard paragraph is, [expr.await]/§5.3 > [...] the await-resume expression is evaluated, and its result is the result > of the await-expression. The code bellow compiles on clang but fail to compile on gcc: #ifdef __clang__ #include using namespace std::experimental; #else #include using namespace std; #endif struct task { struct promise_type { auto get_return_object () -> task { return {}; } auto initial_suspend () -> suspend_never { return {}; } auto final_suspend () -> suspend_always { return {}; } void unhandled_exception () { } void return_void () {} }; }; struct ret_type { ret_type () = default; ret_type (const ret_type&) =delete; }; struct awaiter { auto await_ready() const -> bool { return true; } void await_suspend (coroutine_handle<>) {} auto await_resume() -> ret_type { return {}; } }; task f() { ret_type r2 {co_await awaiter{}}; }; int main() { auto x = f(); return 0; } This code was tentatively compiled with `c++ -std=c++20 -fcoroutines` `gcc -v`: Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/home/olivier/usr/libexec/gcc/x86_64-pc-linux-gnu/10/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc/configure --enable-libsanitizer --prefix=/home/olivier/usr/ --with-gcc-major-version-only --disable-bootstrap --enable-language=c,c++,lto Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 10.1.1 20200508 (GCC)
[Bug c++/95020] New: requires expression always evaluates to true in the definition of template lambda defined within template function
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95020 Bug ID: 95020 Summary: requires expression always evaluates to true in the definition of template lambda defined within template function Product: gcc Version: 10.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- gcc -v: COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/home/olivier/usr/libexec/gcc/x86_64-pc-linux-gnu/10/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc/configure --enable-libsanitizer --prefix=/home/olivier/usr/ --with-gcc-major-version-only --disable-bootstrap --enable-language=c,c++,lto Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 10.1.1 20200508 (GCC) Requires expression that appears in the definition of template lambda defined in the body of template function always evaluates to true: The 2 last static assertion should fire because we multiply a pointer: void good1(){ auto t = [](auto v) { static_assert (!requires {v*10;}); //return v*10; }; void * ptr=nullptr; t(ptr); } template void good2(){ auto t = [](T v) { static_assert (!requires {v*10;}); }; void * ptr=nullptr; t(ptr); } template void bad1 (){ auto t = [](auto v) { static_assert (requires {v*10;}); }; void * ptr=nullptr; t(ptr); } template void bad2 (){ auto t = [](auto v) { static_assert (requires {v*10;}); }; T * ptr=nullptr; t(ptr); } int main() { good1 (); good2 (); bad1 (); bad2 (); return 0; }
[Bug c++/95009] New: decltype of increment or decrement bitfield expressions are wrong and causes assembler errors.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95009 Bug ID: 95009 Summary: decltype of increment or decrement bitfield expressions are wrong and causes assembler errors. Product: gcc Version: 10.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- This bug exists since gcc version 6 The code bellow should not compile: #include struct A { int i:31; }; A a; //I am not sure the standard require that (a.i) and ++a.i have the same type. static_assert(!std::is_same_v ); // int& int:31& //but I do believe that decltype(a.i+=1) and decltype(++a.i) shall have the same type static_assert(!std::is_same_v ); //int&int:31& [expr.pre.incr]/1 "The expression ++x is equivalent to x+=1." Actualy those weird "int:N" types cause a lot of trouble. This code cause assembler error: //test.cpp struct A{ int i:31; }; template void f(){ } int main(){ A a; f(); f(); return 0; } `c++ test.cpp` outputs: /tmp/ccTayNZZ.s: Assembler messages: /tmp/ccTayNZZ.s:43: Error: symbol `_Z1fIRiEvv' is already defined
[Bug libstdc++/94679] New: link time error: undefined reference to std::projected<...>::operator *() const
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94679 Bug ID: 94679 Summary: link time error: undefined reference to std::projected<...>::operator *() const Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- Host: x86_64-pc-linux-gnu Target: x86_64 Build: x86_64-pc-linux-gnu When compiling with -coverage -fkeep-inline-functions, it is possible to get a linkage error: 'undefined reference to `std::projected::operator*() const' gcc --version: gcc (GCC) 10.0.1 20200416 (experimental) Copyright (C) 2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. gcc -v: Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/home/olivier/usr/libexec/gcc/x86_64-pc-linux-gnu/10/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc/configure --enable-libsanitizer --prefix=/home/olivier/usr/ --with-gcc-major-version-only --disable-bootstrap --enable-language=c,c++,lto Thread model: posix Supported LTO compression algorithms: zlib gcc version 10.0.1 20200416 (experimental) (GCC) The following code compiled with: 'c++ -coverage -fkeep-inline-functions -std=c++20 file.cpp' #include int main(){ int a[]={1,2,3}; std::ranges::next_permutation(a); return 0; } This produce error message: /usr/bin/ld: /tmp/ccF8BXBM.o: in function `decltype(auto) std::ranges::__cust_imove::_IMove::operator()&>(std::projected&) const': test.cpp:(.text._ZNKSt6ranges12__cust_imove6_IMoveclIRSt9projectedIPiSt8identityEEEDcOT_[_ZNKSt6ranges12__cust_imove6_IMoveclIRSt9projectedIPiSt8identityEEEDcOT_]+0x2a): undefined reference to `std::projected::operator*() const' /usr/bin/ld: /tmp/ccF8BXBM.o: in function `decltype(auto) std::ranges::__cust_imove::_IMove::operator() const&>(std::projected const&) const': test.cpp:(.text._ZNKSt6ranges12__cust_imove6_IMoveclIRKSt9projectedIPiSt8identityEEEDcOT_[_ZNKSt6ranges12__cust_imove6_IMoveclIRKSt9projectedIPiSt8identityEEEDcOT_]+0x2a): undefined reference to `std::projected::operator*() const' collect2: error: ld returned 1 exit status
[Bug gcov-profile/94636] New: gcov should and could output overall coverage. This is just a 2 code lines change.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94636 Bug ID: 94636 Summary: gcov should and could output overall coverage. This is just a 2 code lines change. Product: gcc Version: 10.0 Status: UNCONFIRMED Keywords: easyhack Severity: normal Priority: P3 Component: gcov-profile Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com CC: marxin at gcc dot gnu.org Target Milestone: --- Created attachment 48301 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48301=edit Patch to output overall coverage Gcov could output the computed overall code coverage when processing multiple file. This overall coverage is often all what is needed in CI reports. It think this is just a 2 lines change. diff --git a/gcc/gcov.c b/gcc/gcov.c index a291bac3e9e..c16895e640a 100644 --- a/gcc/gcov.c +++ b/gcc/gcov.c @@ -1510,7 +1510,8 @@ generate_results (const char *file_name) } } - if (!file_name) +if (file_name) + fnotice(stdout,"Overall:\n"); executed_summary (total_lines, total_executed); }
[Bug c++/94061] New: defaulted member operator <=> defined as deleted if a base has protected member operator <=>
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94061 Bug ID: 94061 Summary: defaulted member operator <=> defined as deleted if a base has protected member operator <=> Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- Version: GCC 10.0.1 20200229 When a base class declares the three way comparison member operator as protected, a defaulted three way comparison member operator in the derived is defined as deleted, while it shall obviously not: Code: #include struct A{ protected: auto operator <=> (const A&) const = default; }; struct B : A { auto operator <=> (const B&) const = default; }; void f(B b){ b <=> b; //error see bellow } Error message: : In function 'void f(B)': :15:11: error: use of deleted function 'constexpr auto B::operator<=>(const B&) const' 15 | b <=> b; | ^ :11:10: note: 'constexpr auto B::operator<=>(const B&) const' is implicitly deleted because the default definition would be ill-formed: 11 | auto operator <=> (const B&) const = default; | ^~~~ :11:10: error: 'auto A::operator<=>(const A&) const' is protected within this context :5:10: note: declared protected here 5 | auto operator <=> (const A&) const = default; | ^~~~ Compiler returned: 1
[Bug c++/94058] New: defaulted three way comparison operator defined as deleted when a member is a small bitfield of long type.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94058 Bug ID: 94058 Summary: defaulted three way comparison operator defined as deleted when a member is a small bitfield of long type. Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- Version: GCC 10.0.1 20200229 Exemple of code: #include struct A{ long i : 48; auto operator <=> (const A&) const = default; }; struct B{ long i : 8; auto operator <=> (const B&) const = default; }; void f(A a, B b){ a <=> a; //OK b <=> b; //error (see bellow) } Error message: : In function 'void f(A, B)': :15:11: error: use of deleted function 'constexpr auto B::operator<=>(const B&) const' 15 | b <=> b; | ^ :10:10: note: 'constexpr auto B::operator<=>(const B&) const' is implicitly deleted because the default definition would be ill-formed: 10 | auto operator <=> (const B&) const = default; | ^~~~ :10:10: warning: narrowing conversion of '((const B*)this)->B::i' from 'long int' to 'int' [-Wnarrowing] :10:10: warning: narrowing conversion of '.B::i' from 'long int' to 'int' [-Wnarrowing] Compiler returned: 1
[Bug c++/88252] New: Deduction guide assume the constructor parameter is a forwarding reference if constructor defined outside class
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88252 Bug ID: 88252 Summary: Deduction guide assume the constructor parameter is a forwarding reference if constructor defined outside class Product: gcc Version: 8.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- Constructor parameter that have the forms of a forwarding reference (T&&) inside a constructor are not forwarding reference if T is a parameter of the class template. But gcc assumes it is a forwarding reference if the constructor is defined outside the class: template struct B1 { B1(T&& x){} }; template struct B2 { B2(T&& x) ; }; template B2::B2(T&& x){} int i; B1 a{i};//Expect: compilation error, class template argument deduction failed B2 b{i};//Unexpected: no compilation error.
[Bug c++/83342] extern marked variable template with later definition emits error
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83342 Olivier Kannengieser changed: What|Removed |Added CC||okannen at gmail dot com --- Comment #2 from Olivier Kannengieser --- Whit gcc 8.2, there is no more bug for constant template variables. But compilation produces undefined symbol error at linking phase if variables templates are non const: template extern T value4; template T value4= 0; auto test4 = value4; //linking phase error: undefined symbol value4 template extern T value5; template inline T value5=0; auto test5 = value5; //linking phase error: undefined symbol value5 There are no error with Clang.
[Bug c++/88164] New: Copy initialization of function argument not performed inside lambda when the argument is a constexpr block scope variable.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88164 Bug ID: 88164 Summary: Copy initialization of function argument not performed inside lambda when the argument is a constexpr block scope variable. Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- In the code bellow the copy constructor of "a" should be called: struct A { int x=12; constexpr A(){} A(const A& x); }; int f(A); // This function should not compile // And the generated code does not call the copy constructor of A int test() { constexpr A a{}; auto lambda = []{ return f(a); // Unexpected: does not call the copy constructor, // should not compile: a should be explicitly captured }; return lambda(); } The the call to the copy constructor does not appear in the generated assembly: test(): subq$24, %rsp leaq12(%rsp), %rdi movl$12, 12(%rsp) callf(A) addq$24, %rsp ret While without the lambda: int test_expect_assembly(){ constexpr A a{}; return f(a); } the copy constructor is called: test_expect_assembly(): subq$24, %rsp leaq8(%rsp), %rsi leaq12(%rsp), %rdi movl$12, 8(%rsp) callA::A(A const&) leaq12(%rsp), %rdi callf(A) addq$24, %rsp ret This unexpected copy constructor elision only happens for function arguments construction. The code below produces the expected assembly and GCC requires the explicit capture of "a": int test_copy_initialization() { constexpr A a{}; auto lambda = []{ // a must be captured A b=a; return a.x; }; return lambda(); } Moreover there is a related bug when the variable has global scope, the copy constructor is called, nevertheless GCC should not implicitly captures the variable because the variable is ODR used. The capture should be explicit, the code below should not compile: constexpr A n_a{}; int test_ns() { auto lambda = []{ return f(n_a);// call the copy constructor so odr use n_a // Unexpected: n_a should be explictly captured }; return lambda(); }
[Bug c++/88103] New: Wrong value category when conditional expression result is used as object expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88103 Bug ID: 88103 Summary: Wrong value category when conditional expression result is used as object expression Product: gcc Version: 8.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- In the code below, if the conditional expression is an xvalue, and only when this xvalue is used as the object expression in class member access, gcc treat it as if it were an lvalue. The problem does not happen when the conditional expression is a prvalue: struct A { A(int); A&& foo() && ; int i; }; void free(A&&); void test_xvalue(A a){ //No error A&& ref = true? static_cast(a) : static_cast(a); //No error free(true? static_cast(a) : static_cast(a)); //Unexpected error: passing A as this discard qualifier (true? static_cast(a) : static_cast(a)).foo(); //Unexpected error: error cannot bind rvalue reference // of type int&& to lvalue of type int int&& k=(true? static_cast(a) : static_cast(a)).i; } void test_prvalue(A a){ //No error A&& ref = true? static_cast(a) : 1; //No error free(true? static_cast(a) : 1); //No error (true? static_cast(a) : 1).foo(); //No error int&& k=(true? static_cast(a) : 1).i; }
[Bug c++/87629] function template parameter deduction succeeds but parameter and deduced arg does not match.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87629 --- Comment #2 from Olivier Kannengieser --- This is not a bug, this bug report should be removed! The function call is undeduced context so the rule [temp.call.deduct]/4 is bypassed.
[Bug c++/87629] function template parameter deduction succeeds but parameter and deduced arg does not match.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87629 --- Comment #1 from Olivier Kannengieser --- This is maybe not a compiler bug, to be confirmed/unconfirmed by an expert of the standard.
[Bug c++/87629] New: function template parameter deduction succeeds but parameter and deduced arg does not match.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87629 Bug ID: 87629 Summary: function template parameter deduction succeeds but parameter and deduced arg does not match. Product: gcc Version: 8.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- This bug is present in all gcc versions. Consider the following code: template struct x{ x(void(*)(int)); }; void foo(int); template void Tfoo(T); template void x_func(x a); void test(){ x_func(foo); //does not compile => standard compliant x_func(Tfoo); //compile! template deduction + conversion => not standard compliant } `x_func(Tfoo)` compiles, but this violate this standard rule [\[temp.deduct.call\]/4](http://eel.is/c++draft/temp.deduct#call-4) which states that the deduced function argument type shall match (almost) the type of the argument: In general, the deduction process attempts to find template argument values that will make the deduced A identical to A (after the type A is transformed as described above). However, there are three cases that allow a difference: > - If the original P is a reference type, the deduced A (i.e., the type > referred to by the reference) can be more cv-qualified than the transformed A. > - The transformed A can be another pointer or pointer-to-member type that > can be converted to the deduced A via a function pointer conversion and/or > qualification conversion. > - If P is a class and P has the form simple-template-id, then the > transformed A can be a derived class of the deduced A. Likewise, if P is a > pointer to a class of the form simple-template-id, the transformed A can be a > pointer to a derived class pointed to by the deduced A. See also this stackoverflow question:https://stackoverflow.com/q/52845621/5632316
[Bug c++/87478] Hidden member function falsely takes part in qualified name lookup
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87478 Olivier Kannengieser changed: What|Removed |Added CC||okannen at gmail dot com --- Comment #2 from Olivier Kannengieser --- Is this realy a bug or an other instance of core issue 1980: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1980. I think the behavior of Gcc is the one expected by the standardization commitee.
[Bug libstdc++/87278] GCC 8 fails to compile make_shared()
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87278 Olivier Kannengieser changed: What|Removed |Added CC||okannen at gmail dot com --- Comment #1 from Olivier Kannengieser --- This bug appeared after commit 7086d631 "PR libstdc++/48101 improve errors for invalid container specializations" which invalidated use of standard allocator of cv qualified type.
[Bug c++/87066] New: new expression and potential destructor invokation
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87066 Bug ID: 87066 Summary: new expression and potential destructor invokation Product: gcc Version: 8.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- In the c++ standard [expr.new]: >> if the new-expression creates an array of objects of class type, the >> destructor is potentially invoked. And potentially invoked means that it is odr-used [basic.odr.def]. Gcc seems to apply this rule chaotically: #include struct A { ~A() = delete; std::string s; }; struct B { ~B() = delete; }; int main() { new A{}; //accepted new B{}; //error: use of deleted function ~B() //this is not a odr-use of ~B because this is not //an array creation new B; //accepted new B[1]{}; //wrongly accepted: array creation odr-use the deleted destructor new B[1]; //wrongly accepted: array creation odr-use the deleted }
[Bug c++/71484] Class with implicit public constructor triggers `-Wctor-dtor-privacy`
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71484 Olivier Kannengieser changed: What|Removed |Added CC||okannen at gmail dot com --- Comment #2 from Olivier Kannengieser --- In GCC 8.1, #pragma GCC diagnostic ignored "-Wctor-dtor-privacy", does not fully disable the diagnostic message: --> without ignored diagnostic: test.cpp:2:8: warning: ‘struct S’ only defines private constructors and has no friends [-Wctor-dtor-privacy] struct S{ ^ test.cpp:4:3: note: ‘constexpr S::S(const S&)’ is public, but requires an existing ‘struct S’ object S(const S&) = default; ---> with ignored diagnostic: test.cpp:4:3: note: ‘constexpr S::S(const S&)’ is public, but requires an existing ‘struct S’ object S(const S&) = default;
[Bug c++/84699] discarded value expression of volatile class type shall materialize a temporary
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84699 --- Comment #1 from Olivier Kannengieser --- A link to an answer to a question on stack overflow that details what should happen: https://stackoverflow.com/a/29873914/5632316
[Bug c++/84699] New: discarded value expression of volatile class type shall materialize a temporary
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84699 Bug ID: 84699 Summary: discarded value expression of volatile class type shall materialize a temporary Product: gcc Version: 7.3.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- *Description When a discarded value expression if of class type, a temporary shall be created by copy construction. This copy construction causes the access to the value of the copied object. Example: struct s{ int i; s()=default; s(const volatile s& o):i{o.i}{} }; struct s1{ int i; }; volatile s as; volatile s1 as1; void test(){ as; //should call the copy constructor of s as1; //should not compile (void)as; //should call the copy constructor of s (void)as1; //should not compile (as,as); //should call twice the copy constructor of s (as1,as1); //should not compile } Remark: Neither Clang nor MSVC behave according to the standard. *Standard requirement: **Since at least C++11,[expr].11 (https://timsong-cpp.github.io/cppwp/n4140/expr#11): In some contexts, an expression only appears for its side effects. Such an expression is called a discarded-value expression. The expression is evaluated and its value is discarded. The array-to-pointer ([conv.array]) and function-to-pointer ([conv.func]) standard conversions are not applied. The lvalue-to-rvalue conversion ([conv.lval]) is applied if and only if the expression is a glvalue of volatile-qualified type and it is one of the following:[...] **Since C++14 standard a Note has been added to this which is explicit (https://timsong-cpp.github.io/cppwp/n4659/expr#12): [[...] If the lvalue is of class type, it must have a volatile copy constructor to initialize the temporary that is the result of the lvalue-to-rvalue conversion.]
[Bug c++/84686] New: Parenthesized discarded value expression are not evaluated with option -std=c++14
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84686 Bug ID: 84686 Summary: Parenthesized discarded value expression are not evaluated with option -std=c++14 Product: gcc Version: 8.0.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- This bug appears first in version 4.9 and is still here in version 7.3 and above. Compilation option: -std=c++14 or a newer c++ version. *Description: Evaluation of discarded value expression are not performed if the expression is parenthesized: volatile int i; i; //evaluated (a load is performed) (i); //unevaluated => the load shall be performed (void)i; //evaluated (a load is performed) (void)(i); //unevaluated => the load shall be performed (void)i; //evaluated (a load is performed) (void)(i); //unevaluated => the load shall be performed (i,i); // the two subexpression are evaluated ((i),(i)); // no evaluation, => two loads shall happen Remark: Clang does perform all loads. *C++ standard requirements (N4140) **[expr.prim.general]/6: A parenthesized expression is a primary expression whose type and value are identical to those of the enclosed expression. The presence of parentheses does not affect whether the expression is an lvalue. The parenthesized expression can be used in exactly the same contexts as those where the enclosed expression can be used, and with the same meaning, except as otherwise indicated. **[expr]/11: In some contexts, an expression only appears for its side effects. Such an expression is called a discarded-value expression. The expression is evaluated and its value is discarded. The array-to-pointer ([conv.array]) and function-to-pointer ([conv.func]) standard conversions are not applied. The lvalue-to-rvalue conversion ([conv.lval]) is applied if and only if the expression is a glvalue of volatile-qualified type and it is one of the following: - ( expression ), where expression is one of these expressions, - [...]
[Bug c++/80962] No more access violation control after certain declarations using concepts
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80962 --- Comment #1 from Olivier Kannengieser --- Inside the comment section BUGGY CODE, the second commented line should be uncommented to see that gcc does not complaning for private access violation. The attached file is the version which causes gcc to bug.
[Bug c++/80962] New: No more access violation control after certain declarations using concepts
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80962 Bug ID: 80962 Summary: No more access violation control after certain declarations using concepts Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: okannen at gmail dot com Target Milestone: --- Created attachment 41462 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41462=edit The buggy code as described in the comment. GCC VERSION: (gcc -v) Utilisation des specs internes. COLLECT_GCC=3Dgcc COLLECT_LTO_WRAPPER=3D/usr/local/gcc7/libexec/gcc/x86_64-pc-linux-gnu/7.1.1/lto-wrapper Cible : x86_64-pc-linux-gnu Configur=C3=A9 avec: ../configure --prefix=3D/usr/local/gcc7 --disable-=multilib Mod=C3=A8le de thread: posix gcc version 7.1.1 20170503 (GCC) BUG DESCRIPTION: gcc stops to perform member access violation rule checking: If in a compound requirement using a partialy specialized concept as placeholder, then gcc stop any access schecking test (one can have access to private member of classes). COMMAND LINE: c++ -fconcepts file.cpp BUGGY CODE: This code should not compile, but it does (no access violation performed). class a_class { int f(int){return 33;} //private member }; template concept bool AnyConcept =true; template concept bool OtherConcept = requires(const T& a) { //Gcc do not bug without the the following line. //{a && a} -> AnyConcept; {a && a} -> bool; }; int main() { a_class obj; obj.f(10); //Error not reported by gcc. } BUGGY CODE: This code shows normal gcc behavior, an error is reported: "int a_class::f(int) is private in this context" class a_class { int f(int){return 33;} //private member }; template concept bool AnyConcept =true; template concept bool OtherConcept = requires(const T& a) { //Gcc do not bug without the the following line. //{a && a} -> AnyConcept; {a && a} -> bool; }; int main() { a_class obj; obj.f(10); //Error not reported by gcc. } OTHER PROBABLY RELATED ISSUES: with larger code I have observed that the same issue could happen if any of the following code line occurs: 1. partialy specialized concept used as placeholder inside function argument list template concept bool Same = std::is_same<T,U>::value; int afunc(Same&& x); 2. partialy specialized concept used as placeholder inside template argument list template<Same T> void afunc(T&&); 3. concept inside if constexpr (not sure it is inside the concept TS, but it causes the exact same trouble, + command line option -std=c++17) template concept bool Constructible = std::is_constructible::value; ... if constexpr(Constructible<int,int>)