[Bug c++/99686] ICE when using both concepts and full specialization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99686 W E Brown changed: What|Removed |Added CC||webrown.cpp at gmail dot com --- Comment #2 from W E Brown --- Since C++ has no partial specializations of function templates, the test case in Comment 1 is somewhat mischaracterized there. Instead, what we have in that test case are, first, two distinct primary templates that happen to share a common name within a single scope, and hence overload that name. Note that these primary templates are distinguishable because one is more constrained (via its requires-clause) than the other (which is unconstrained): whenever these primary templates produce equally viable candidates during overload resolution, C++ specifies that the more constrained declaration should be selected. Finally, the test case defines a complete specialization, but which of the overloaded primary templates is being specialized? That's the real question for the compiler to determine in its role of language lawyer. Note that if one of the two primary templates were removed from the test case, the compiler's decision would become near-trivial to make, as there would remain only a single candidate. If, instead, the explicit specialization were removed from the test case, such a compiler determination would be no longer needed at all.
[Bug c++/99686] ICE when using both concepts and full specialization
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99686 --- Comment #4 from W E Brown --- (In reply to Steven Sun from comment #3) > I would expect the complete specialization is full > specialization for both primary templates. No, any given explicit or partial specialization can be a specialization of only one primary template. (Suppose that two overloaded primary templates had different signatures. How then, in general, could both be specialized by any single explicit or partial specialization?) > ... > In conclusion, this makes sences but I didn't see that coming. Anyway, I > think a possible improvement is make ICE to an error of "ambigous full > specialization". Or even better, a change in C++23 standard. Given two or more very similar primary templates, C++ already specifies an algorithm (known as "partial* ordering") to determine which one is being specialized by a given explicit or partial specialization. Therefore, unless you can find some issue with that algorithm, I see no reason to propose any language change in this area; partial ordering has been part of C++ for several decades. (However, I speculate that your test cases may have exposed a bug in GCC's implementation of partial ordering, possibly just a failure to diagnose an ambiguous situation. I'm sure the GCC internals experts will provide proper diagnosis and remediation in due course.) * The algorithn is termed "partial" because there are cases that can't be decided and therefore result in an ill-formed program. If you'd like some further details on this topic, I can recommend my video 😊 https://www.youtube.com/watch?v=nfIX8yWlByY.
[Bug c++/98735] New: ICE with -std=c++20 -fmodules-ts -fsanitize=undefined
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98735 Bug ID: 98735 Summary: ICE with -std=c++20 -fmodules-ts -fsanitize=undefined Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: webrown.cpp at gmail dot com Target Milestone: --- Using gcc version 11.0.0 20210116 (experimental) (Homebrew GCC HEAD-2c356f2_2) and compiling with flags: -std=c++20 -fmodules-ts -fsanitize=undefined produces: internal compiler error: in tree_node, at cp/module.cc:9125 pointing at the module keyword (line 1) in the following innocuous program: export module X; export inline constexpr bool f( ) noexcept { return true; } Removing -fsanitize=undefined permits successful compilation.
[Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335 W E Brown changed: What|Removed |Added CC||webrown.cpp at gmail dot com --- Comment #1 from W E Brown --- According to C++20 [over.load]/2.3: "Member function declarations ... cannot be overloaded if any of them, but not all, have a ref-qualifier" Therefore, the above example's Base class compiles because each of its overloaded member functions has a ref-qualifier. However, Derived::method is not ref-qualified, so treating it as an overload of those Base functions would violate the above-cited passage. Accordingly, unless I've overlooked some exception to this rule, I respectfully suggest this issue be closed as invalid.
[Bug c++/100335] Using statement of a ref-qualified method from base class: method not callable on derived object
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100335 --- Comment #4 from W E Brown --- I won't comment on any compiler's behavior, but do want to thank you for reminding me of [namespace.udecl]/14: "When a using-declarator brings declarations from a base class into a derived class, member functions ... in the derived class override and/or hide member functions .. with the same name, parameter-type-list ..., and ref-qualifier (if any), in a base class" Upon reflection, I believe that [namespace.udecl]/14 does not apply to the original example because the ref-qualifier on Derived::method (i.e., none) is not "the same" as the ref-qualifier on either Base::method. Thus, there's no overriding and/or hiding to be done there. However, I believe that [namespace.udecl]/14 *does* apply to the example in Comment 3, where Base::method and Derived::method do have "the same" ref-qualifier (i.e., none). There, Derived::method ought to hide Base::method as [over.load]/2.3 seems be inapplicable. In brief, I believe Comment 3's example ought compile due to [namespace.udecl]/14, but the original example ought not compile due to [over.load]/2.3.
[Bug c++/100687] New: [modules, concepts] imported concept gives different result
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100687 Bug ID: 100687 Summary: [modules, concepts] imported concept gives different result Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: webrown.cpp at gmail dot com Target Milestone: --- Using recent trunk [g++-HEAD (Homebrew GCC HEAD-5380e3c) 12.0.0 20210513], compiling with significant flags -std=c++23 -fmodules-ts -c. I have two source files, as follows: // export module bug_a; template< class T > inline constexpr bool probe = false; // template< class R, class C > inline constexpr bool probe = true; export template< class T > concept mbr_ptr = probe; struct S { int f( ); }; using mf_t = decltype( &S::f ); static_assert( mbr_ptr< mf_t > ); // This bug_a module compiles successfully. In particular, the static_assert passes. // export module bug_b; import bug_a; struct S { int f( ); }; using mf_t = decltype( &S::f ); static_assert( mbr_ptr< mf_t > ); // This bug_b module does not compile. The diagnostics are reproduced below, including the somewhat mysterious lone apostrophe: bug_b.cc:8:16: error: static assertion failed 8 | static_assert( mbr_ptr< mf_t > ); |^~~ bug_b.cc:8:16: note: constraints not satisfied ' bug_a.cc:12: confused by earlier errors, bailing out Please note that the static_assert and supporting declarations in module bug_a are identical to those in module bug_a, yet one compiles while the other does not. Thus we seem to have two problems: (1) the lone apostrophe amongst the diagnostics, and (2) the inconsistent evaluation of identical expressions. Finally, please note that if I use a class template (instead of the variable template) in module bug_a, both modules' static_asserts now compile without complaint: // template< class T > struct probe { static constexpr bool value = false; }; // template< class R, class C > struct probe { static constexpr bool value = true; }; export template< class T > concept mbr_ptr = probe::value; //
[Bug c++/101181] New: ICE when using an alias template
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101181 Bug ID: 101181 Summary: ICE when using an alias template Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: webrown.cpp at gmail dot com Target Milestone: --- The following program produces "Segmentation fault: 11 signal terminated program cc1plus" when compiled with flags -std=c++23 -fmodules-ts -pedantic-errors -O0 -c using gcc trunk version (Homebrew GCC HEAD-da13e4e_1) 12.0.0 20210623 (experimental) template< class T , bool = requires { typename T::pointer; } > struct p { using type = void; }; template< class T > struct p { using type = T::pointer; }; template< class T > using P = typename p::type; Without the final alias template, all seems well.
[Bug c++/103049] [C++23] P0849R8 - auto(x): decay-copy in the language
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103049 --- Comment #2 from W E Brown --- (In reply to Marek Polacek from comment #1) > Patch on review. In the proposed patch, I respectfully recommend a slight rewording of the new pedwarn messages in gcc/cp/semantics.c and gcc/cp/typeck2.c: either s/only available with/available only with/ or s/only available with/unavailable without/ or s/only available with/requires/ would emphasize the required flag rather than focus on the feature's availability. (FWIW, of the above suggestions, the last ["requires"] seems to me the most direct and simplest to understand.) Thank you.
[Bug c++/108052] New: forward-declared constexpr variable template unusable in constexpr context
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108052 Bug ID: 108052 Summary: forward-declared constexpr variable template unusable in constexpr context Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: webrown.cpp at gmail dot com Target Milestone: --- Similar to bug 59123, the following code compiles with no complaint: extern const double e; // a fwd-declaration constexpr double e = 2.71; // its corresponding def'n static_assert( e == 2.71 ); // verification But the following analogous, templatized, code...: template< class T > extern const T pi; // a fwd-declaration template< class T > constexpr T pi = 3.14; // its corresponding def'n static_assert( pi == 3.14 ); // verification ... produces the following unexpected diagnostics: error: non-constant condition for static assertion error: the value of 'pi' is not usable in a constant expression note: 'pi' was not declared 'constexpr' ...when compiling with gcc version 13.0.0 20221122 and any of: -std=c++17, -std=c++20, or -std=c++23. However, further experimentation reveals that the following int variation of the above static_assert does compile (although an expected float-conversion warning is produced if enabled): template< class T > extern const T pi; // a fwd-declaration Finally, bug 92576 and bug 68012 seem tangentially related. template< class T > constexpr T pi = 3.14; // its corresponding def'n static_assert( pi == 3 ); // verification A knowledgeable CWG colleague conjectures that the double-vs-int difference may be "somehow related to the special rule for 'const integral types' vs. 'constexpr any type'." Finally, bug 68012, bug 84255, and bug 92576 seem tangentially related, although these do not involve any extern declaration.
[Bug libstdc++/107778] handle_contract_violation should reflect _GLIBCXX_VERBOSE
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107778 --- Comment #10 from W E Brown --- > On Dec 22, 2022, at 6:51 PM, cvs-commit at gcc dot gnu.org > wrote: > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107778 > > --- Comment #9 from CVS Commits --- > The master branch has been updated by Jason Merrill : > > https://gcc.gnu.org/g:8ec5fcb6fc79e5bcca23c3fecbaf09d4566cb1d5 > > commit r13-4861-g8ec5fcb6fc79e5bcca23c3fecbaf09d4566cb1d5 > Author: Arsen ArsenoviÄ > Date: Thu Dec 22 12:03:06 2022 +0100 > >libstdc++: Improve output of default contract violation handler [PR107792] > >Make the output more readable. Don't output anything unless verbose >termination is enabled at configure-time. > >The testsuite change was almost entirely mechanical. Save for two files >which had very short matches, these changes were produced by two seds and a >Perl script, for the more involved cases. The latter will be added in a >subsequent commit. The former are as follows: > >sed -E -i "/dg-output/s/default std::handle_contract_violation called: > \ >(\S+) (\S+) (\S+(<[A-Za-z0-9, ]*)?>?)\ >/contract violation in function \3 at \1:\2: /" *.C >sed -i '/dg-output/s/ */ /g' > >Whichever files remained failing after the above changes were checked-out, >re-ran, with output extracted, and ran through dg-out-generator.pl. > >Co-Authored-By: Jonathan Wakely > >libstdc++-v3/ChangeLog: > >PR libstdc++/107792 >PR libstdc++/107778 >* src/experimental/contract.cc (handle_contract_violation): Make >output more readable. > >gcc/testsuite/ChangeLog: > >* g++.dg/contracts/contracts-access1.C: Convert to new default >violation handler. >* g++.dg/contracts/contracts-assume2.C: Ditto. >* g++.dg/contracts/contracts-config1.C: Ditto. >* g++.dg/contracts/contracts-constexpr1.C: Ditto. >* g++.dg/contracts/contracts-ctor-dtor1.C: Ditto. >* g++.dg/contracts/contracts-deduced2.C: Ditto. >* g++.dg/contracts/contracts-friend1.C: Ditto. >* g++.dg/contracts/contracts-multiline1.C: Ditto. >* g++.dg/contracts/contracts-post3.C: Ditto. >* g++.dg/contracts/contracts-pre10.C: Ditto. >* g++.dg/contracts/contracts-pre2.C: Ditto. >* g++.dg/contracts/contracts-pre2a2.C: Ditto. >* g++.dg/contracts/contracts-pre3.C: Ditto. >* g++.dg/contracts/contracts-pre4.C: Ditto. >* g++.dg/contracts/contracts-pre5.C: Ditto. >* g++.dg/contracts/contracts-pre7.C: Ditto. >* g++.dg/contracts/contracts-pre9.C: Ditto. >* g++.dg/contracts/contracts-redecl3.C: Ditto. >* g++.dg/contracts/contracts-redecl4.C: Ditto. >* g++.dg/contracts/contracts-redecl6.C: Ditto. >* g++.dg/contracts/contracts-redecl7.C: Ditto. >* g++.dg/contracts/contracts-tmpl-spec1.C: Ditto. >* g++.dg/contracts/contracts-tmpl-spec2.C: Ditto. >* g++.dg/contracts/contracts-tmpl-spec3.C: Ditto. >* g++.dg/contracts/contracts10.C: Ditto. >* g++.dg/contracts/contracts14.C: Ditto. >* g++.dg/contracts/contracts15.C: Ditto. >* g++.dg/contracts/contracts16.C: Ditto. >* g++.dg/contracts/contracts17.C: Ditto. >* g++.dg/contracts/contracts19.C: Ditto. >* g++.dg/contracts/contracts25.C: Ditto. >* g++.dg/contracts/contracts3.C: Ditto. >* g++.dg/contracts/contracts35.C: Ditto. >* g++.dg/contracts/contracts5.C: Ditto. >* g++.dg/contracts/contracts7.C: Ditto. >* g++.dg/contracts/contracts9.C: Ditto. > > -- > You are receiving this mail because: > You are on the CC list for the bug.
[Bug c++/108205] New: ICE following "unused parameter" in precondition
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108205 Bug ID: 108205 Summary: ICE following "unused parameter" in precondition Product: gcc Version: 13.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: webrown.cpp at gmail dot com Target Milestone: --- Using (Homebrew GCC HEAD-37c2d99) 13.0.0 20221213 (experimental) and compiling via: g++-HEAD -std=c++23 -fmodules-ts -fcontracts -pedantic-errors \ -O0 -Wall -Wextra -Werror -Wpedantic \ -fno-builtin -fconcepts-diagnostics-depth=2 on an x86 MacBook Pro. This code compiles: [[nodiscard]] constexpr int quotient( double x, double y ) noexcept { [[assume (y != 0.0)]]; return int(x / y); } The same code also compiles as a module: export module test; export [[nodiscard]] constexpr int quotient( double x, double y ) noexcept { [[assume (y != 0.0)]]; return int(x / y); } But reformulating the assumption as a precondition causes issues. First, this code is diagnosed with "unused parameter 'x'", which seems misleading: [[nodiscard]] constexpr int quotient( double x, double y ) noexcept [[ pre: y != 0.0 ]] { return int(x / y); } Second, when the above is compiled as a module, the compiler additionally segfaults: export module test; export [[nodiscard]] constexpr int quotient( double x, double y ) noexcept [[ pre: y != 0.0 ]] { return int(x / y); }
[Bug c++/104111] [DR2589] Concept evaluation depends on context where it was first checked
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104111 --- Comment #10 from W E Brown --- (In reply to Eric Estievenart from comment #9) Sorry, but I find neither "weirdness" nor "spooky"-ness in the comment #9 code as shown. Rather, I believe it to be simply an example of a program that the C++ standard would describe as "ill-formed, no diagnostic required." A common, yet incorrect expectation that template instantiation somehow mirrors function call semantics seems to me to lie at the heart of the misunderstanding. Hypothetically, if the above program were to be well-formed, the compiler would need to instantiate the member template twice *with identical template arguments* in order to obtain the expected two different outcomes. However, I recall no specification, in the C++ standard, that requires such (relatively expensive!) duplication of compiler effort: once a template has been instantiated, the compiler seems fully entitled, say, to cache the result of that instantiation and reuse that outcome as may be needed during the remainder of that TU's compilation. Put another way, defining the same function in two different ways (one instantiation as deleted, one not) seems to be a form of ODR violation. Perhaps the OP is also a manifestation of a similar misunderstanding; I've not checked. If so, I would respectfully recommend this PR be closed as invalid.