[Bug c++/99535] New: g++ rejects valid code in constexpr copy ctor and volatile submember
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99535 Bug ID: 99535 Summary: g++ rejects valid code in constexpr copy ctor and volatile submember Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Darrell.Wright at gmail dot com Target Milestone: --- The following code produces an error struct Thing0 { volatile int a; constexpr Thing0( int v ): a{v} {} constexpr Thing0(Thing0 const& other) : a(other.a) {} constexpr Thing0& operator=(Thing0 const& rhs) { a = rhs.a; return *this; } ~Thing0() = default; }; Thing0 func0() { return Thing0{5}; } : In copy constructor 'constexpr Thing0::Thing0(const Thing0&)': :7:51: error: lvalue-to-rvalue conversion of a volatile lvalue 'other.Thing0::a' with type 'const volatile int' 7 | constexpr Thing0(Thing0 const& other) : a(other.a) {} | ~~^ : In member function 'constexpr Thing0& Thing0::operator=(const Thing0&)': :9:13: error: lvalue-to-rvalue conversion of a volatile lvalue 'rhs.Thing0::a' with type 'const volatile int' 9 | a = rhs.a; | ^ The code should be accepted and is when the special methods are not constexpr.
[Bug c++/99535] g++ rejects valid code in constexpr copy ctor and volatile submember
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99535 --- Comment #1 from Darrell Wright --- I was wrong, http://eel.is/c++draft/expr.const#5.8
[Bug libstdc++/99006] New: make_shared silently works
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99006 Bug ID: 99006 Summary: make_shared silently works Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: Darrell.Wright at gmail dot com Target Milestone: --- std::make_shared in libstdc++ prior to c++20 doesn't fail. The minimal example is #include int func( ) { auto sp = std::make_shared( 55 ); return *sp.get( ); } will return 55; libc++ removes it from the overload set and MS STL fails. https://gcc.godbolt.org/z/PaW6WY With T = int[], I think https://timsong-https://timsong-cpp.github.io/cppwp/n4659/util.smartptr.shared.create#1 should make this not work.
[Bug c++/104980] New: Bad error on variable template instantiation failure
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104980 Bug ID: 104980 Summary: Bad error on variable template instantiation failure Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Darrell.Wright at gmail dot com Target Milestone: --- The error generated when a variable template instantiation failure happens is unhelpful. Clang provides more context in their error output. With the following code https://gcc.godbolt.org/z/KoYf7rhEq #include template inline constexpr bool dependent_false_v = false; struct deleted_t{}; inline constexpr auto deleted = deleted_t{}; #define DELETED_VARIABLE std::enable_if_t, deleted_t> template inline constexpr DELETED_VARIABLE is_foo = deleted; template <> inline constexpr bool is_foo = true; auto a = is_foo; auto b = is_foo; gcc outputs only: 2614 | using enable_if_t = typename enable_if<_Cond, _Tp>::type; | ^~~ Whereas clang gives both the definition and call site in its output: using enable_if_t = typename enable_if<_Cond, _Tp>::type; ^ :12:18: note: in instantiation of template type alias 'enable_if_t' requested here inline constexpr DELETED_VARIABLE is_foo = deleted; ^ :9:31: note: expanded from macro 'DELETED_VARIABLE' #define DELETED_VARIABLE std::enable_if_t, deleted_t> ^ :18:10: note: in instantiation of variable template specialization 'is_foo' requested here auto b = is_foo; This is more desirable as one can see what is going on. Would it be possible to output better information so that a developer can more clearly see what failed?
[Bug c++/104276] New: Fail to eliminate deadstore from vector constructor
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104276 Bug ID: 104276 Summary: Fail to eliminate deadstore from vector constructor Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Darrell.Wright at gmail dot com Target Milestone: --- clang is unable to remove the memset in code like std::vector foo() { auto result = std::vector(SZ); int *ptr = result.data(); for (std::size_t n = 0; n < SZ; ++n) { ptr[n] = static_cast( n ); } return result; } https://gcc.godbolt.org/z/5cbKejfqr This is unaffected if the value is set during resize. That may result in inlining of the memset but does not eliminate it. However for code that uses blessed methods like memset subsequently std::vector foo() { auto result = std::vector(SZ); std::memset(result.data(), 5, sizeof(int) * SZ); return result; } https://gcc.godbolt.org/z/Kfs9x8Pe9 It is. This seems to be the usecase of resize_and_overwrite in future string. Is there a way to formulate the code to do this. Or, and I think a better way, is there a builtin or could there be that lets the compiler assume that the memory will be subsequently written to? e.g. `__bultin_assume_set( void * dest, size_t count )` ?
[Bug tree-optimization/104276] Fail to eliminate deadstore from vector constructor
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104276 --- Comment #3 from Darrell Wright --- (In reply to Andrew Pinski from comment #2) > >clang is unable to remove the memset in code like > > I think you mean GCC there :). :) both are true. This optimization would remove the need for things like resize_and_overwrite which means we all win
[Bug c++/104388] New: Request: A builtin to mark an object as invalid
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104388 Bug ID: 104388 Summary: Request: A builtin to mark an object as invalid Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Darrell.Wright at gmail dot com Target Milestone: --- Would it be possible to get a builtin that marks an object as invalid until it is overwritten and make it IF if the object is used other than destruction, assignment or taking its address/ref. I am naive on the compiler internals here, but this could allow for the safety of destructive moves without the changes to the object model around destruction ordering.
[Bug c++/102916] New: cmath constexpr can lead to ODR violations/incorrect results
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102916 Bug ID: 102916 Summary: cmath constexpr can lead to ODR violations/incorrect results Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Darrell.Wright at gmail dot com Target Milestone: --- Because many of the cmath functions are constexpr, even in conformance mode of the compiler, this can lead to ODR issues. It is detectable in C++20 and gives incorrect results. #include template consteval auto foo( ) { if constexpr (requires { []() {}.template operator()<(F(), void(), 0)>(); }) { return 0; } else { return 1; } } auto a = foo<[]{ return std::sqrt( 4.0 ); }>( ); https://gcc.godbolt.org/z/M6zGTbTfM gcc returns 0, clang/libstdc++ and MSVC return 1. I believe that in conformance -std=c++20 -pedantic mode that gcc should not mark these methods as constexpr
[Bug c++/102916] cmath constexpr can lead to ODR violations/incorrect results
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102916 --- Comment #2 from Darrell Wright --- The constexpr value returned is different depending on the compiler. If one uses clang and gcc this leads to an ODR issue as void bar( ) { if constexpr( foo<[]{ return std::sqrt( 4.0 ); }>( ) ) { doA( ); } else { doB( ); } }
[Bug c++/102916] cmath constexpr can lead to ODR violations/incorrect results
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102916 --- Comment #3 from Darrell Wright --- Also http://eel.is/c++draft/library#constexpr.functions-1 An issue is that it's high level observable and not just an optimization
[Bug libstdc++/102916] cmath constexpr can lead to ODR violations/incorrect results
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102916 --- Comment #6 from Darrell Wright --- Right, mostly it can fall under as-if(if it wasn't explicitly disallowed) but because it's observable it can lead to some interesting behaviour differences when libstdc++ is compiled with gcc and clang.
[Bug libstdc++/102916] cmath constexpr can lead to ODR violations/incorrect results
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102916 --- Comment #11 from Darrell Wright --- (In reply to Jonathan Wakely from comment #7) > C++23 is making these constexpr anyway so I'm not very inclined to change > this now. That is good to hear, I thought I had read/heard that there was a lot of roadblocks on that and the behaviour of things like rounding modes.
[Bug tree-optimization/104276] memset is not elimited when followed by a store loop writing to that memory location
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104276 --- Comment #8 from Darrell Wright --- What about something like a __builtin_overwrite( ptr, size_t ) that tells the compiler that the range specified will be written. It forms a contract to do so with the compiler and would allow the memset to be eliminated or augmented to part of the range
[Bug c++/109518] New: invalid constexpr code is accepted
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109518 Bug ID: 109518 Summary: invalid constexpr code is accepted Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Darrell.Wright at gmail dot com Target Milestone: --- The following invalid code is UB but accepted by gcc. The life of x has not started yet, https://eel.is/c++draft/basic.life#1.2 , but it is accessed. constexpr void init(int & x) { x = 42; } constexpr int foo() { int x = (init(x), x); return x; } static_assert( foo( ) == 42 ); https://gcc.godbolt.org/z/oGE51eMz4
[Bug c++/109961] New: storage size of 'variable name' isn't known
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109961 Bug ID: 109961 Summary: storage size of 'variable name' isn't known Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Darrell.Wright at gmail dot com Target Milestone: --- The following valid code fails to compile in gcc-trunk on https://foo.godbolt.org/z/vGMGbv8oP auto a = requires{ []( int b ) consteval { if( b ) { throw b; } }( 0 ); }; With the following error :3:6: error: storage size of 'a' isn't known 3 | auto a = requires{ | ^ Compiler returned: 1
[Bug c++/117454] New: Template parameter hidden by base class name
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117454 Bug ID: 117454 Summary: Template parameter hidden by base class name Product: gcc Version: 15.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: Darrell.Wright at gmail dot com Target Milestone: --- There should be a warning when a template parameter name is hidden by a base classes usage of it. e.g ``` struct Base { int Value = 42; }; template struct Derived : Base { int v = Value; }; static_assert( Derived<66>{}.v == 66 ); ``` Will fail to compile, the intent is clear. This happens with any name it seems ``` #include struct Base { using Type = int; }; template struct Derived : Base { Type field; }; static_assert( std::is_same_v{}.field), double> ); ``` However, if the Base is a dependent type the behaviour is reversed. The user fix is to change the template param name, but I think compilers should have a warning for this here as the code is probably broken
[Bug c++/117454] Template parameter hidden by base class name
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117454 --- Comment #2 from Darrell Wright --- Thanks, yeah, I forgot to add that, I did try something like -Wall -Wextra -pedantic -pedantic-errors -Wshadow -O1
[Bug c++/117454] Template parameter hidden by base class name
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117454 --- Comment #4 from Darrell Wright --- #include struct Base { using Type = int; }; template struct Derived : Base { Type field; }; static_assert( std::is_same_v{}.field), double> ); I think this should warn too, the intent is clear and the user hopefully gets a conversion warning/error.