[Bug c++/97134] New: partial specialization not more specialized when using CNTTP
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97134 Bug ID: 97134 Summary: partial specialization not more specialized when using CNTTP 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: --- g++, tried trunk on CE along with 10.2 and 10.1 will say the following code is not more specialized when JSONNAMETYPE is a CNTTP(json_name). When it's a NTTP(char const *) it is ok with it. The code works in MSVC's C++20 mode. https://godbolt.org/z/7v4nx5 #include #include #include #include template struct json_name { static_assert(N > 0); char const m_data[N]{}; private: template constexpr json_name(char const (&ptr)[N], std::index_sequence) : m_data{ptr[Is]...} {} public: constexpr json_name(char const (&ptr)[N]) : json_name(ptr, std::make_index_sequence{}) {} // Needed for copy_to_iterator [[nodiscard]] constexpr char const *begin() const { return m_data; } // Needed for copy_to_iterator [[nodiscard]] constexpr char const *end() const { return m_data + static_cast(size()); } [[nodiscard]] static constexpr std::size_t size() noexcept { return N - 1; } template constexpr bool operator==(json_name const &rhs) const { if (N != M) { return false; } for (std::size_t n = 0; n < N; ++n) { if (m_data[n] != rhs.m_data[n]) { return false; } } return true; } constexpr operator std::string_view() const { return std::string_view(m_data, size()); } }; template json_name(Chars...) -> json_name; template json_name(char const (&)[N]) -> json_name; #ifdef USE_CNTTP #define JSONNAMETYPE json_name #else #define JSONNAMETYPE char const * #endif template struct X : std::false_type { static constexpr std::string_view name = Name; }; template struct X : std::true_type { static constexpr std::string_view name = Name; }; int main() { static constexpr char const A[] = "A"; static constexpr char const B[] = "B"; auto a = X::name; auto b = X::name; std::cout << a << b << '\n'; }
[Bug c++/92343] New: [[likely]]/[[unlikely]] prevent method from being a constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92343 Bug ID: 92343 Summary: [[likely]]/[[unlikely]] prevent method from being a constant expression 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: --- Adding the attributes likely or unlikely can cause a function to be a constant expression https://gcc.godbolt.org/z/DGzPoa #include #include template constexpr bool test(B&& b, char const (&reason)[N]) { [[unlikely]] if (not static_cast(b)) { (void)reason; std::abort(); } return true; } static_assert( test( true, "testing" ) )
[Bug c++/92343] [[likely]]/[[unlikely]] prevent method from being a constant expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92343 --- Comment #1 from Darrell Wright --- On compiler explorer this affects 9.1/9.2/trunk
[Bug c++/92411] New: conformance issue with reinterpret_cast in constant expressions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92411 Bug ID: 92411 Summary: conformance issue with reinterpret_cast in constant expressions 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: --- It looks like there is a regression in trunk(20171107 on CE) that allows reinterpret_casts in constant expressions. https://gcc.godbolt.org/z/m7Qytn using size_t = decltype(sizeof(int)); constexpr char const * func( char const * ptr ) { return reinterpret_cast( ptr ); } static_assert( func( nullptr ) == nullptr ); template constexpr char const * func2( char const (&s)[N] ) { return reinterpret_cast( s ); } static_assert( *func2( "Hello" ) == 'H' ); I think this should be ill formed with a diag according to the following links, but it is allowed https://eel.is/c++draft/expr.const#4.15 https://eel.is/c++draft/dcl.pre#6
[Bug c++/92551] New: accepts invalid code in function template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92551 Bug ID: 92551 Summary: accepts invalid code in function template 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: --- I accidently produced this invalid code and it worked as intended until I tested further. However, the integer_sequence should never have been deduced https://gcc.godbolt.org/z/hp4crn This will return 20, but should be an error #include #include namespace algorithm_impl { template constexpr void do_n(Function &&func, Args &&... args, std::integer_sequence) { if constexpr (sizeof...(Is) > 0) { (void)((func(args...), Is) + ...); } } } // namespace algorithm_impl template constexpr void do_n(Function &&func, Args &&... args) noexcept(noexcept(func(args...))) { algorithm_impl::do_n(std::forward(func), std::forward(args)..., std::make_integer_sequence{}); } constexpr int do_n_1_test() { int n = 0; do_n<20>([&n] { ++n; }); return n; } int main() { return do_n_1_test(); }
[Bug c++/92551] accepts invalid code in function template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92551 --- Comment #2 from Darrell Wright --- The Args... is in a non deduced context because it isn't at the end. http://eel.is/c++draft/temp.deduct#type-5.7 With that, I think only trailing packs can be defaulted to empty http://eel.is/c++draft/temp.arg.explicit#4 In the bad code above, the args looks like it is being treated as an empty pack, but I am not sure the standard allows for that.
[Bug c++/92551] accepts invalid code in function template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92551 --- Comment #3 from Darrell Wright --- I think this can be closed and sorry for wasting time. It was explained how this is ok to me https://bugs.llvm.org/show_bug.cgi?id=44034#c2
[Bug c++/92411] conformance issue with reinterpret_cast in constant expressions
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92411 --- Comment #1 from Darrell Wright --- sorry, posted incorrect CE link, but code below demonstrates it
[Bug c++/91418] New: Nested class of templated class cannot declare parent class friend
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91418 Bug ID: 91418 Summary: Nested class of templated class cannot declare parent class friend Product: gcc Version: 9.1.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: --- As seen here https://gcc.godbolt.org/z/FvHncw. One cannot express friend class Parent; when parent is templated from a nested class within a member function As a workaround, it will work with friend class Parent;
[Bug c++/91418] Nested class of templated class cannot declare parent class friend
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91418 --- Comment #1 from Darrell Wright --- The template isn't part of it, https://gcc.godbolt.org/z/KCok90
[Bug c++/91418] Nested class of templated class cannot declare parent class friend
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91418 --- Comment #4 from Darrell Wright --- The weird part is, other than compilers don't agree, but the lookup finds it if you put the template argument in template struct A { auto func( ) { class B { B( ) = default; friend class A; }; return B( ); } }; I don't think a local class can be a template anyways, but it does find global A here
[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.