[Bug c++/99686] ICE when using both concepts and full specialization

2021-03-20 Thread webrown.cpp at gmail dot com via Gcc-bugs
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

2021-03-25 Thread webrown.cpp at gmail dot com via Gcc-bugs
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

2021-01-18 Thread webrown.cpp at gmail dot com via Gcc-bugs
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

2021-04-29 Thread webrown.cpp at gmail dot com via Gcc-bugs
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

2021-04-29 Thread webrown.cpp at gmail dot com via Gcc-bugs
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

2021-05-19 Thread webrown.cpp at gmail dot com via Gcc-bugs
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

2021-06-23 Thread webrown.cpp at gmail dot com via Gcc-bugs
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

2021-11-09 Thread webrown.cpp at gmail dot com via Gcc-bugs
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

2022-12-10 Thread webrown.cpp at gmail dot com via Gcc-bugs
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

2022-12-22 Thread webrown.cpp at gmail dot com via Gcc-bugs
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

2022-12-22 Thread webrown.cpp at gmail dot com via Gcc-bugs
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

2024-02-22 Thread webrown.cpp at gmail dot com via Gcc-bugs
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.