[Bug c++/92505] New: Using mutable in constexpr

2019-11-13 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92505

Bug ID: 92505
   Summary: Using mutable in constexpr
   Product: gcc
   Version: 10.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

GCC trunk does not accept this well-formed program in -std=c++2a mode:

constexpr int f() {
struct {
mutable int i = 41;
} s;
auto const& cs = s;
return ++cs.i;
}

int main() {
constexpr int i = f();
return 42 - i;
}

Diagnosing (https://godbolt.org/z/n259tb):

: In function 'int main()':
:10:24:   in 'constexpr' expansion of 'f()'
:10:25: error: mutable 'f()i' is not usable in
a constant expression
   10 | constexpr int i = f();
  | ^
Compiler returned: 1

AFAICS this is well-formed back to C++14 since it applies lvalue-to-rvalue
conversion to "a non-volatile glvalue of literal type that refers to a
non-volatile object whose lifetime began within the evaluation of e;".

[Bug c++/90734] [concepts] Pre-normalization substitution into constraints of templated function breaks subsumption

2019-11-15 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90734

Casey Carter  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

--- Comment #4 from Casey Carter  ---
There's some confusion here as a result of my inadequate description in the
original bug. The line `static_assert(S1::f()); // Bogus error` is valid
but was not accepted and the line `static_assert(S2::f()); // Bogus
non-error` is invalid but was not rejected. This should have been tagged both
"rejects-valid" and "accepts-invalid" (or better yet, I should have filed
separate issues instead of conflating the two).

As Andrew says, trunk now both accepts and rejects the cases it should here.
I'll simply close this since I don't think it provides any useful or unique
test case.

[Bug c++/67491] [meta-bug] concepts issues

2019-11-15 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491
Bug 67491 depends on bug 90734, which changed state.

Bug 90734 Summary: [concepts] Pre-normalization substitution into constraints 
of templated function breaks subsumption
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90734

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

[Bug c++/82380] [concepts] Error when using requires constraint with attributes

2019-12-02 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82380

Casey Carter  changed:

   What|Removed |Added

 CC||cjdb.ns at gmail dot com

--- Comment #6 from Casey Carter  ---
(In reply to Jonathan Wakely from comment #5)
> I tested it with "concept" not "concept bool" i.e.
> 
> template 
> concept C = true;
> 
> template 
>   requires C
> [[nodiscard]] int f(T t) {
>   return 22;
> }
> 
> int main() {
>   return 0;
> }

This seems to have regressed (https://godbolt.org/z/SmPx-y).

[Bug c++/59659] large zero-initialized std::array of std::atomic compile time excessive

2014-01-02 Thread Casey at Carter dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59659

--- Comment #1 from Casey Carter  ---
Created attachment 31563
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=31563&action=edit
Minimal test case.

Attached minimal test case. std::atomic arr[100]; compiles correctly,
so it seems to be an interaction between std::atomic and std::array.


[Bug c++/88419] New: [9 Regression] [ICE] "Same canonical type node for different types" for CTAD in noexcept

2018-12-08 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88419

Bug ID: 88419
   Summary: [9 Regression] [ICE] "Same canonical type node for
different types" for CTAD in noexcept
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Created attachment 45191
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45191&action=edit
Repro

This TU:

  template struct ref_view {
  template ref_view(T&&);
  };

  template ref_view(R&) -> ref_view;

  struct ref_fn {
  template auto operator()(R r) const
  noexcept(noexcept(ref_view{r}));
  };

  template struct indirect_view {
  indirect_view(R);
  };

  struct indirect_fn {
  template auto operator()(R r) const
  noexcept(noexcept(indirect_view{r}));
  };

ICEs when compiled with "g++ -std=c++17 -c":

  /home/casey/casey/Desktop/repro.cpp:18:40: internal compiler error: same
canonical type node for different types ‘indirect_view’ and ‘ref_view’
18 | noexcept(noexcept(indirect_view{r}));
|^
  0x9fd2af comptypes(tree_node*, tree_node*, int)
  /home/casey/repos/gcc/gcc/cp/typeck.c:1486
  0x9f3076 cp_tree_equal(tree_node*, tree_node*)
  /home/casey/repos/gcc/gcc/cp/tree.c:3558
  0x9f3d6f cp_tree_equal(tree_node*, tree_node*)
  /home/casey/repos/gcc/gcc/cp/tree.c:3816
  0x9e3772 cp_check_qualified_type
  /home/casey/repos/gcc/gcc/cp/tree.c:2135
  0x9e7557 build_cp_fntype_variant(tree_node*, cp_ref_qualifier, tree_node*,
bool)
  /home/casey/repos/gcc/gcc/cp/tree.c:2568
  0x9e7647 build_cp_fntype_variant(tree_node*, cp_ref_qualifier, tree_node*,
bool)
  /home/casey/repos/gcc/gcc/cp/tree.c:2599
  0x8b9aeb grokdeclarator(cp_declarator const*, cp_decl_specifier_seq*,
decl_context, int, tree_node**)
  /home/casey/repos/gcc/gcc/cp/decl.c:11527
  0x8caa3e grokfield(cp_declarator const*, cp_decl_specifier_seq*, tree_node*,
bool, tree_node*, tree_node*)
  /home/casey/repos/gcc/gcc/cp/decl2.c:814
  0x95b2f1 cp_parser_init_declarator
  /home/casey/repos/gcc/gcc/cp/parser.c:20306
  0x95ef04 cp_parser_single_declaration
  /home/casey/repos/gcc/gcc/cp/parser.c:27954
  0x95f04c cp_parser_template_declaration_after_parameters
  /home/casey/repos/gcc/gcc/cp/parser.c:27546
  0x95f98d cp_parser_explicit_template_declaration
  /home/casey/repos/gcc/gcc/cp/parser.c:27792
  0x95f98d cp_parser_template_declaration_after_export
  /home/casey/repos/gcc/gcc/cp/parser.c:27811
  0x960cbd cp_parser_member_declaration
  /home/casey/repos/gcc/gcc/cp/parser.c:24070
  0x93b07a cp_parser_member_specification_opt
  /home/casey/repos/gcc/gcc/cp/parser.c:23997
  0x93b07a cp_parser_class_specifier_1
  /home/casey/repos/gcc/gcc/cp/parser.c:23141
  0x93d049 cp_parser_class_specifier
  /home/casey/repos/gcc/gcc/cp/parser.c:23403
  0x93d049 cp_parser_type_specifier
  /home/casey/repos/gcc/gcc/cp/parser.c:17259
  0x93e03b cp_parser_decl_specifier_seq
  /home/casey/repos/gcc/gcc/cp/parser.c:13982
  0x93e773 cp_parser_simple_declaration
  /home/casey/repos/gcc/gcc/cp/parser.c:13287
  Please submit a full bug report,
  with preprocessed source if appropriate.
  Please include the complete backtrace with any bug report.
  See <https://gcc.gnu.org/bugs/> for instructions.

[Bug c++/88419] [9 Regression] [ICE] "Same canonical type node for different types" for CTAD in noexcept

2018-12-09 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88419

--- Comment #3 from Casey Carter  ---
8.2 and 7.4 don't ICE: https://godbolt.org/z/VznOao. I was assuming that
r266224 (the fix for #52869) likely caused the regression, although I haven't
investigated.

[Bug c++/88515] New: [concepts] id-expression that names non-static data member rejected in requires-expression

2018-12-15 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88515

Bug ID: 88515
   Summary: [concepts] id-expression that names non-static data
member rejected in requires-expression
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Compiling this TU:

template concept bool C = 
requires { T::value; };

struct S { int value; };
static_assert(C);

with "g++ -std=c++2a -fconcepts -c" produces:

/home/casey/casey/Desktop/repro2.cpp:5:15: error: invalid use of non-static
data member ‘S::value’
5 | static_assert(C);
  |   ^~~~
/home/casey/casey/Desktop/repro2.cpp:4:16: note: declared here
4 | struct S { int value; };
  |^
/home/casey/casey/Desktop/repro2.cpp:5:15: error: static assertion failed
5 | static_assert(C);
  |

when it should compile successfully since an id-expression that denotes a
non-static data member can appear in an unevaluated operand
([expr.prim.id]/2.3) and expressions appearing within a requirement-body are
unevaluated operands ([expr.prim.req]/2).

[Bug c++/88419] [7/8/9 Regression] [ICE] "Same canonical type node for different types" for CTAD in noexcept

2018-12-21 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88419

Casey Carter  changed:

   What|Removed |Added

   Keywords|accepts-invalid |

--- Comment #6 from Casey Carter  ---
Clarifying: 

The sample TU is valid; It's rejected by GCC 6 because that version does not
support C++17 class template argument deduction. 

I claim that the bug is a regression because 7/8 compile it correctly in
default mode, and 9 does not. Yes, it's incorrectly rejected by 7 and 8 as well
when compiling with -fchecking=1, so it's *not* a regression that 9 rejects the
code with -fchecking=1.

[Bug c++/88829] New: Failure to deduce size of array of 2^31 chars

2019-01-13 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88829

Bug ID: 88829
   Summary: Failure to deduce size of array of 2^31 chars
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

This sample TU:

using size_t = decltype(sizeof(int));

template T&& declval();

template
void f(T(&&)[N]) {}

using U = decltype(f(declval())); // error: size of
array is negative

fails to compile on trunk with "g++ -std=c++2a repro.cpp", diagnosing:

:8:51: error: no matching function for call to 'f(char
[2147483648])'
8 | using U = decltype(f(declval())); // error:
size of array is negative
  |   ^
:6:6: note: candidate: 'template void
f(T (&&)[N])'
6 | void f(T(&&)[N]) {}
  |  ^
:6:6: note:   template argument deduction/substitution failed:
: In substitution of 'template void
f(T (&&)[N]) [with T = char; long unsigned int N = 18446744071562067968]':
:8:51:   required from here
:6:6: error: size of array is negative
:6:8: error: size of array is negative
6 | void f(T(&&)[N]) {}
  |^~~~
:8:49: error: invalid initialization of reference of type 'char
(&&)[1]' from expression of type 'char [2147483648]'
8 | using U = decltype(f(declval())); // error:
size of array is negative
  |  ~~~^~
:6:8: note: in passing argument 1 of 'void f(T (&&)[N]) [with T =
char; long unsigned int N = 18446744071562067968]'
6 | void f(T(&&)[N]) {}
  |^~~~

If arrays of size >= 2^31 aren't supported - which is a perfectly legitimate
implementation limit - I expect the formation of the array type to be diagnosed
rather than the deduction to fail. Also, the "size of array is negative"
diagnostic is confusing (#87996 already makes that point).

[Bug libstdc++/70303] Value-initialized debug iterators

2019-01-15 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70303

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #4 from Casey Carter  ---
(In reply to Jonathan Wakely from comment #3)
> Or is the implication of equality being valid that a+n is valid for n==0,
> and therefore b-a is valid, and therefore relational ops are valid?

Certainly b-a is required to be valid, since such an n exists as required by
[random.access.iterators] - but admittedly the IS doesn't specify the domain
for relational comparisons on Cpp17 iterators. IMO this is a defect since it
implies you can *never* compare two iterators with e.g. <. 

We should require the domain of relational comparisons to be the same as the
domain of equality, which would then make it clear that value-initialized
iterators are in their domain. (I was under the impression that we *did*
require this "somewhere" when I filed this issue and fixed MSFTL's iterators.)

[Bug libstdc++/70303] Value-initialized debug iterators

2019-01-15 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70303

--- Comment #5 from Casey Carter  ---
IIRC my reasoning was that [random.access.iterators] specifies the operational
semantics of `a < b` to be `b - a > 0`, which suggests but doesn't quite
require that `a < b` is valid whenever `b - a` is valid.

[Bug c++/85555] Use of concepts gives access to private members.

2018-04-28 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=8

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #1 from Casey Carter  ---
Duplicate of 67225 and/or 78715.

[Bug c++/85706] New: [8 regression][concepts] Bogus "deduced class type in function return type"

2018-05-08 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85706

Bug ID: 85706
   Summary: [8 regression][concepts] Bogus "deduced class type in
function return type"
   Product: gcc
   Version: 8.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Compiling this program:

  template struct S {
  S(T);
  };

  template
  auto f() -> decltype(S(42)); // error

with "-std=c++17 -fconcepts" produces diagnostics:

  /home/casey/casey/Desktop/repro.cpp:6:6: error: deduced class type ‘S’ in
function return type
   auto f() -> decltype(S(42)); // Line 6
^
  /home/casey/casey/Desktop/repro.cpp:1:26: note: ‘template struct S’ 
  declared here
   template struct S {
^

the program compiles without diagnostic if f is a non-template:

  template struct S {
  S(T);
  };

  auto f() -> decltype(S(42));

[Bug c++/85765] [8/9 Regression] Missing SFINAE in default template argument

2018-05-13 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85765

--- Comment #4 from Casey Carter  ---
Narrowing the error down:

template())), decltype(*U(),0) =
0>
U g(T& t, long) { return begin(t); } // #1


prog.cc: In instantiation of 'U g(T&, long int) [with T = volatile il; U =
int*; decltype (((* U()), 0))  = 0]'

The "U = int*" is particularly damning here: it tells us the compiler
substituted `volatile il` into `decltype(begin(declval()))` to get
`begin(declval())`. `int* begin(il);` is a *candidate* for
overload resolution - it has the right name and number of parameters - and it's
a viable candidate because the ICS from lvalue `volatile il` to `il` is an
identity conversion per [over.best.ics]/6: "Any difference in top-level
cv-qualification is subsumed by the initialization itself and does not
constitute a conversion. ... When the parameter has a class type and the
argument expression has the same type, the implicit conversion sequence is an
identity conversion." Since it's the *only* viable function, it is
unambiguously the *best* viable function.

So the only question here is why the compiler omits the final analysis that
would determine that initialization of an `il` from a `volatile il&` is
ill-formed - making the entire function call expression ill-formed - but only
does so when the following `decltype(*U(),0) = 0` is present in the template
parameter list.

[Bug c++/85806] New: [concepts] Hard error for "invalid use of non-static data member" in a requires expression

2018-05-16 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85806

Bug ID: 85806
   Summary: [concepts] Hard error for "invalid use of non-static
data member" in a requires expression
   Product: gcc
   Version: 8.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Compiling this program fragment with g++ -std=c++17 -fconcepts
(https://godbolt.org/g/L1b6TS):

  template using helper = void;

  template
  concept bool HasCount = requires {
  typename ::helper;
  };

  struct S {
  int count = 42;
  };
  static_assert(!HasCount);

produces a diagnostic:

  :11:18: error: invalid use of non-static data member 'S::count'
 static_assert(!HasCount);
^~~
  :9:19: note: declared here
 int count = 42;
 ^~

rather than the expected successful and silent compile.

[Bug c++/85808] New: [concepts] unqualified name lookup breaks after qualified lookup in nested requirement

2018-05-16 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85808

Bug ID: 85808
   Summary: [concepts] unqualified name lookup breaks after
qualified lookup in nested requirement
   Product: gcc
   Version: 8.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Compiling this program fragment with "g++ -std=c++17 -fconcepts"
(https://godbolt.org/g/EXDoD3):

  namespace X {
  template constexpr bool x = true;
  }

  template using helper = void;

  template
  concept bool C = requires {
  requires X::x;
  #ifndef WORKAROUND
  typename helper;
  #else
  typename ::helper; // Workaround
  #endif
  };

  static_assert(C);

produces diagnostics:

  :11:14: error: 'X::helper' has not been declared
   typename helper;
^~
  :11:24: error: expected ';' before '>' token
   typename helper;
  ^
  ;
  :11:24: error: expected '}' before '>' token
  :8:27: note: to match this '{'
   concept bool C = requires {
 ^
  :11:25: error: expected primary-expression before ';' token
   typename helper;
   ^
  :15:1: error: expected declaration before '}' token
   };
   ^

rather than the expected successful and silent compile.

[Bug c++/85892] New: value-initialization failure

2018-05-23 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85892

Bug ID: 85892
   Summary: value-initialization failure
   Product: gcc
   Version: 8.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

This test program aborts because `collector`'s base `item` isn't properly
zero-initialized:

void* operator new(decltype(sizeof(int)), void* ptr) {
return ptr;
}

struct item { int data; };

struct collector : item {
collector() = default;
collector(int) {}
};

struct tuple : collector {
tuple() : collector{} {}
};

int main() {
alignas(tuple) unsigned char space[sizeof(tuple)];
for (auto& c : space) c = 0xff;

auto ptr = ::new(&space) tuple;
int& i = static_cast(*ptr).data;
if (i != 0) __builtin_abort();
}

Default-initialization of `tuple` invokes its constructor, which
value-initializes its `collector` base subobject, which should zero-initialize
`collector`'s `item` base subobject.

[Bug c++/85892] value-initialization failure

2018-05-23 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85892

Casey Carter  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||Casey at Carter dot net
 Resolution|--- |DUPLICATE

--- Comment #2 from Casey Carter  ---
(In reply to Jonathan Wakely from comment #1)
> Is this a dup of Bug 65816 comment 1?

Almost exactly: the sole difference being that 65816 comment 1 observes failure
to zero-init a *member* subobject, and this report observes failure to
zero-init a *base* subobject.

I'll add this repro to 65816.

*** This bug has been marked as a duplicate of bug 65816 ***

[Bug c++/65816] Constructor delegation does not perform zero-initialization

2018-05-23 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65816

--- Comment #4 from Casey Carter  ---
*** Bug 85892 has been marked as a duplicate of this bug. ***

[Bug c++/65816] Constructor delegation does not perform zero-initialization

2018-05-23 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65816

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #3 from Casey Carter  ---
I ran across an almost identical case, but involving a base subobject which
isn't properly zero-initialized rather than the member subobject case in
comment 1:

void* operator new(decltype(sizeof(int)), void* ptr) {
return ptr;
}

struct item { int data; };

struct collector : item {
collector() = default;
collector(int) {}
};

struct tuple : collector {
tuple() : collector{} {}
};

int main() {
alignas(tuple) unsigned char space[sizeof(tuple)];
for (auto& c : space) c = 0xff;

auto ptr = ::new(&space) tuple;
int& i = static_cast(*ptr).data;
if (i != 0) __builtin_abort();
}

Default-initialization of `tuple` invokes its constructor, which
value-initializes its `collector` base subobject, which should zero-initialize
`collector`'s `item` base subobject.

[Bug c++/82507] [concepts] premature substitution into constraint of non-template member function

2018-06-24 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82507

--- Comment #1 from Casey Carter  ---
Gentle ping: working around this bug is making it incredibly hard to prototype
the Ranges design for C++20.

[Bug c++/84140] Inline friends are not constrained by concepts

2018-06-25 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84140

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #1 from Casey Carter  ---
Another repro:

  template constexpr bool is_same_v = false;
  template constexpr bool is_same_v = true;

  template
  concept bool Same = is_same_v;

  template
  concept bool Diff = requires(T& t, U& u) { u - t; };

  template
  int distance(I, S) { return 0; }

  template S>
  int distance(I first, S last) {
  return last - first;
  }

  template
  struct I {
  template
  requires Same
  friend int operator-(I const&, I const&) {
  static_assert(Same);
  return 42;
  }
  };

  int main() {
  return distance(I{}, I{});
  }

Compiling fails when the static_assert in the body of the friend function
template - which simply asserts that the constraint on the template is
satisfied - fires. It would appear the constraints aren't being checked for
satisfaction at all on hidden friends found during overload resolution.

FWIW, this makes it impossible to implement the Ranges proposal as specified.

[Bug c++/84140] Inline friends are not constrained by concepts

2018-06-25 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84140

--- Comment #2 from Casey Carter  ---
*** Bug 69096 has been marked as a duplicate of this bug. ***

[Bug c++/69096] [concepts] return type deduction before checking constraint satisfaction

2018-06-25 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69096

Casey Carter  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |DUPLICATE

--- Comment #1 from Casey Carter  ---
This bug is actually a mislabeled occurrence of #84140.

*** This bug has been marked as a duplicate of bug 84140 ***

[Bug c++/67491] [meta-bug] concepts issues

2018-06-25 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491
Bug 67491 depends on bug 69096, which changed state.

Bug 69096 Summary: [concepts] return type deduction before checking constraint 
satisfaction
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69096

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |DUPLICATE

[Bug libstdc++/91259] Parenthesize requires clauses that contain expressions that are not just a value of type bool

2019-07-25 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91259

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #2 from Casey Carter  ---
It would be nice to fix this on gcc-9-branch as well so clang w/concepts can
use libstdc++.

[Bug libstdc++/91259] Parenthesize requires clauses that contain expressions that are not just a value of type bool

2019-07-29 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91259

--- Comment #7 from Casey Carter  ---
Thanks, Jonathan. I can confirm that grepping for "\b(concept|requires)\b"
finds a great many uses in comments, but only the one concept definition and
one requires-clause in .

[Bug c++/67491] [meta-bug] concepts issues

2019-09-04 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491
Bug 67491 depends on bug 67427, which changed state.

Bug 67427 Summary: [concepts] Subsumption dependence on template parameter 
ordering
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67427

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |INVALID

[Bug c++/67427] [concepts] Subsumption dependence on template parameter ordering

2019-09-04 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67427

Casey Carter  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||Casey at Carter dot net
 Resolution|--- |INVALID

--- Comment #2 from Casey Carter  ---
(In reply to Andrew Sutton from comment #1)
> I believe that the ambiguity is correct under the revised semantics of
> concepts.

I agree. Happy fourth birthday, #67427 - we'll miss you.

[Bug c++/91923] New: [9/10 Regression] Failure-to-SFINAE with class type NTTP in C++17

2019-09-26 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91923

Bug ID: 91923
   Summary: [9/10 Regression] Failure-to-SFINAE with class type
NTTP in C++17
   Product: gcc
   Version: 9.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Compiling this well-formed TU (https://godbolt.org/z/8HYWSC):

template
constexpr bool is_integral_(...) {
return false;
}
template
constexpr bool is_integral_(long) {
return true;
}

static_assert(is_integral_(42));
static_assert(!is_integral_(42));

struct S {};
static_assert(!is_integral_(42));

with -std=c++17 diagnoses:

: In substitution of 'template > constexpr
bool is_integral_(long int) [with T = S; T  = ]':
:14:34:   required from here
:5:26: error: non-type template parameters of class type only
available with '-std=c++2a' or '-std=gnu++2a'
5 | template
  |  ^
Compiler returned: 1

whereas earlier compiler versions (at least 6 though 8) accept the TU without
diagnostic.

This seems to simply be a case of adding the helpful new diagnostic but
forgetting to silence it in SFINAE context.

[Bug c++/71125] [concepts] Spurious 'invalid reference to function concept error' issued when overloads are not all declared with the concept specifier

2019-10-14 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71125

--- Comment #2 from Casey Carter  ---
(In reply to Jonathan Wakely from comment #1)
> Is this valid in C++20?

Definitely not: there are no concept functions in C++20.

> 
> I think G++ is correct to reject it due to redeclaring C1, C2 etc. as a
> different kind of symbol.

I agree. Only functions and function templates may be overloaded, and despite
appearances to the contrary a function concept declaration declares a concept,
not a function template. I suggest classifying this as a poor diagnostic for TS
concepts.

[Bug c++/89300] C++ requires statement does not fail silently for const void *

2019-02-13 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89300

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #1 from Casey Carter  ---
This seems to be a duplicate of #78173.

[Bug c++/82380] [concepts] Error when using requires constraint with attributes

2019-02-18 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82380

--- Comment #2 from Casey Carter  ---
You can work around this bug by using a trailing requires-clause instead of
putting the requires-clause in the template-head.

[Bug libstdc++/89610] Move-assigning a pmr container sometimes copies the elements instead of moving them

2019-03-07 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89610

--- Comment #2 from Casey Carter  ---
This isn't a "missed-optimization", it's non-conforming behavior. The
Allocator-aware container requirements
(http://eel.is/c++draft/container.requirements.general#16.sentence-41) require
only that the element type is Cpp17MoveAssignable and Cpp17MoveInsertable into
the container type, so copies - even if the syntax is valid - cannot achieve
the required postcondition that the target of the move assignment is equal to
the value the source of the move assignment had before moving.

[Bug c++/86044] noexcept(false) of constexpr member function ignored

2019-04-23 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86044

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #1 from Casey Carter  ---
In C++14, this is conforming behavior per N4140 [expr.unary.noexcept]/3:
"""
3. The result of the noexcept operator is false if in a potentially-evaluated
   context the expression would contain
3.1 - a potentially-evaluated call to a function, member function, function
  pointer, or member function pointer that does not have a non-throwing
  exception-specification, unless the call is a constant expression,
[...]
"""

In C++17 and later, it is not conforming per [expr.unary.noexcept]/3:
"""
3 The result of the noexcept operator is true unless the expression is 
  potentially-throwing ([except.spec]).
""
and [except.spec]/6 which defines "potentially-throwing" and includes no
mention of constant expressions (I won't duplicate the full text here).

[Bug c++/82171] Cant use std::declval in concept testing map operator[]

2019-04-24 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82171

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #4 from Casey Carter  ---
Likely a duplicate of 68781.

[Bug c++/90675] New: [concepts] expressions in compound requirements not correctly treated as unevaluated operands

2019-05-29 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90675

Bug ID: 90675
   Summary: [concepts] expressions in compound requirements not
correctly treated as unevaluated operands
   Product: gcc
   Version: 10.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Created attachment 46430
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46430&action=edit
Minimal repro

Compiling this well-formed TU:

  template
  constexpr bool always_false = false;

  template
  struct S {
void f() {
  static_assert(always_false);
}
  };

  template
  concept True = true;

  template
  concept C = requires(T t) {
  #ifndef WORKAROUND
  { t.f() } -> True;
  #else
  t.f();
  requires True;
  #endif
  };

  int main() {
  static_assert(C>);
  }

with "g++ -std=c++2a -fconcepts" (same behavior for all versions from 6.1 to
today's trunk) diagnoses (https://godbolt.org/z/cHC8PE):

  : In instantiation of 'void S::f() [with T = void]':
  :25:19:   required from here
  :7:19: error: static assertion failed
  7 | static_assert(always_false);
|   ^~~
  Compiler returned: 1

Defining "WORKAROUND" allows the program to compile correctly, since the
expression appears in a simple-requirement rather than a compound-requirement.

[Bug c++/90734] New: [concepts] Pre-normalization substitution into constraints of templated function breaks subsumption

2019-06-03 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90734

Bug ID: 90734
   Summary: [concepts] Pre-normalization substitution into
constraints of templated function breaks subsumption
   Product: gcc
   Version: 10.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Created attachment 46447
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46447&action=edit
Repro

Compiling this program:

template 
inline constexpr bool bool_ = B;

#if defined(WORKAROUND)
template
concept bool Same_impl = __is_same_as(T, U);
#else
template 
concept bool Same_impl = bool_<__is_same_as(T, U)>;
#endif

template
concept bool Same = Same_impl && Same_impl;

template
concept bool Foo = Same;

template
concept bool Bar = Foo && Same;

template
struct S1 {
// overload set incorrectly is ambiguous (should resolve to second
overload)
static constexpr bool f() requires Foo { return false; }
static constexpr bool f() requires Bar { return true; }
};

template
struct S2 {
// overload set incorrectly is not ambiguous (resolves to third
overload)
static constexpr bool f() requires Foo { return false; }
static constexpr bool f() requires Bar { return false; }
static constexpr bool f() requires bool_ && true { return true; }
};

template
concept bool can_f = requires { T::f(); };

int main() {
static_assert(Foo);
static_assert(Bar);

static_assert(can_f>);  // Fails
static_assert(S1::f());// Bogus error

static_assert(!can_f>); // Fails
#ifndef WORKAROUND
static_assert(S2::f());// Bogus non-error
#endif
}

with "-std=c++2a -fconcepts" produces diagnostics:

/home/casey/casey/Desktop/repro.cpp: In function ‘int main()’:
/home/casey/casey/Desktop/repro.cpp:43:19: error: static assertion failed
43 | static_assert(can_f>);  // Fails
   |   ^~
/home/casey/casey/Desktop/repro.cpp:44:30: error: call of overloaded ‘f()’
is ambiguous
44 | static_assert(S1::f());// Bogus error
   |  ^
/home/casey/casey/Desktop/repro.cpp:24:27: note: candidate: ‘static
constexpr bool S1::f() requires  Foo [with T = int]’
24 | static constexpr bool f() requires Foo { return false; }
   |   ^
/home/casey/casey/Desktop/repro.cpp:25:27: note: candidate: ‘static
constexpr bool S1::f() requires  Bar [with T = int]’
25 | static constexpr bool f() requires Bar { return true; }
   |   ^
/home/casey/casey/Desktop/repro.cpp:46:19: error: static assertion failed
46 | static_assert(!can_f>); // Fails
   |   ^~~

when it should diagnose only the static_assert on line 48. Bar subsumes
Foo, so S1::f should be unambiguous. Conversely, Neither Bar nor
bool_ && true subsumes the other, so S2::f should be ambiguous. The
compiler's disagreement with both of these facts suggests premature
substitution replacing bool_<__is_same_as(T, T)> and bool_<__is_same_as(const
T&, const T&)> with bool_ *before* determination of subsumption in
overload resolution. That replacement would result in Foo being replaced
with bool_ && bool_, and Bar being replaced with bool_ &&
bool_ && bool_ && bool_ which *would* produce the observed
behavior during overload resolution.

[Bug c++/90734] [concepts] Pre-normalization substitution into constraints of templated function breaks subsumption

2019-06-03 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90734

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #1 from Casey Carter  ---
Note that this may be a duplicate of #82507, or more precisely a different
expression of the same mechanism that causes #82507.

Handy Compiler Explorer link with repro: https://godbolt.org/z/-vPUJx.

[Bug c++/86493] New: [concepts] Hard error for "call to non-'constexpr' function" in a requires expression

2018-07-11 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86493

Bug ID: 86493
   Summary: [concepts] Hard error for "call to non-'constexpr'
function" in a requires expression
   Product: gcc
   Version: 8.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
      Reporter: Casey at Carter dot net
  Target Milestone: ---

Compiling this well-formed program:

  template 
  concept bool Concept = T::f() == 0;

  struct bad {
  static int f() { return 0; }
  };

  int main() {
  static_assert(!Concept);
  }

with -fconcepts and GCC 6.3/7.3/8.1/trunk diagnoses:

  : In function 'int main()':
  :2:30: error: call to non-'constexpr' function 'static int bad::f()'
 concept bool Concept = T::f() == 0;
^~

instead of correctly failing the concept check.

[Bug c++/78173] Hard error subtracting pointers to incomplete type in SFINAE context

2018-07-13 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78173

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net
 Blocks||67491

--- Comment #1 from Casey Carter  ---
This still reproduces on trunk, and in concepts land. This program fragment:

  template 
  concept bool CanDifference = requires(T const& x, T const& y) {
  x - y;
  };

  static_assert(!CanDifference);

produces diagnostics when compiled with "g++ -std=c++2a -fconcepts"
(https://godbolt.org/g/e36eFK):

  :3:7: error: invalid use of 'void'
   x - y;
   ~~^~~


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491
[Bug 67491] [meta-bug] concepts issues

[Bug c++/67491] [meta-bug] concepts issues

2018-08-08 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491
Bug 67491 depends on bug 86493, which changed state.

Bug 86493 Summary: [concepts] Hard error for "call to non-'constexpr' function" 
in a requires expression
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86493

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

[Bug c++/86493] [concepts] Hard error for "call to non-'constexpr' function" in a requires expression

2018-08-08 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86493

Casey Carter  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |INVALID

--- Comment #1 from Casey Carter  ---
[temp.constr.atomic]/3 states:

  To determine if an atomic constraint is satisfied, the parameter mapping 
  and template arguments are first substituted into its expression. If
  substitution results in an invalid type or expression, the constraint is
  not satisfied. Otherwise, the lvalue-to-rvalue conversion is performed if
  necessary, and E shall be a constant expression of type bool.

"E shall be a constant expression" clearly indicates that a substitution that
produces a non-constant-expression is ill-formed, rather than causing the
constraint not to be satisfied. This is a defect in the language rather than a
bug in GCC.

[Bug c++/87814] New: [9 Regression] ICE in in tsubst_copy, at cp/pt.c:15962 with range-v3

2018-10-30 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87814

Bug ID: 87814
   Summary: [9 Regression] ICE in in tsubst_copy, at cp/pt.c:15962
with range-v3
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Created attachment 44932
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44932&action=edit
Preprocessed repro

This program (preprocessed repro attached as repro.i.gz):

  #include 
  #include 
  #include 

  int main() {
  using namespace ranges;

  auto f = [](int) { return iterator_range(); };
  join_view> rng;
  (void) rng.begin();
  }

ICEs in tsubst_copy while instantiating a variadic inherited constructor
template that performs a "double" pack expansion, defined around line 43341 in
the repro.

[Bug c++/67185] [C++14] Link error on ODR-use of variable template partial specialization

2016-03-06 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67185

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net
Version|6.0 |5.3.0
 Blocks|67491   |
Summary|[concepts] Link error on|[C++14] Link error on
   |ODR-use of constexpr|ODR-use of variable
   |constrained variable|template partial
   |template partial|specialization
   |specialization  |

--- Comment #1 from Casey Carter  ---
This same bug is triggered by the purely C++14 program:

template 
bool x = false;

template 
bool x = true;

bool& f() { return x; }

int main() {}

which when compiled with either g++ 5.3 or 6 results in 

/tmp/ccHHu1ip.o: In function `f()':
prog.cc:(.text+0x5): undefined reference to `x'
collect2: error: ld returned 1 exit status

The problem has nothing to do with concepts or constexpr, but seems to be a
general issue when ODR-using an instance of a template variable that was
instantiated from a partial specialization. I'm recasting this as a C++14 bug
against 5.3.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491
[Bug 67491] [meta-bug] concepts issues

[Bug c++/67210] [concepts] Error parsing ">>" after a template-id that names a concept

2016-03-06 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67210

Casey Carter  changed:

   What|Removed |Added

  Attachment #36183|0   |1
is obsolete||
 CC||Casey at Carter dot net

--- Comment #1 from Casey Carter  ---
Created attachment 37879
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37879&action=edit
Minimal non-concepts (C++14) test case

[Bug c++/67185] [C++14] Link error on ODR-use of variable template partial specialization

2016-03-06 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67185

Casey Carter  changed:

   What|Removed |Added

  Attachment #36170|0   |1
is obsolete||

--- Comment #2 from Casey Carter  ---
Created attachment 37880
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37880&action=edit
Minimal non-concepts (C++14) test case

[Bug c++/60799] access checking within injected friend functions does not happen in the context of the enclosing class

2016-03-08 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60799

--- Comment #1 from Casey Carter  ---
This bug is present in both 5.3 and 6.0; it should probably be attached to the
friend meta-bug 65608 since it is a "friend" issue.

[Bug libstdc++/70303] New: Value-initialized debug iterators

2016-03-19 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70303

Bug ID: 70303
   Summary: Value-initialized debug iterators
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Since C++14 requires value-initialized Forward iterators to compare equal, and
subtraction/ordering of RandomAccess iterators is based on equality, this
program should run to completion:

#define _GLIBCXX_DEBUG

#include 
#include 

int main() {
  using I = std::vector::iterator;
  assert(I{} == I{});
  assert(!(I{} != I{}));
  assert(I{} - I{} == 0);
  assert(!(I{} < I{}));
  assert(!(I{} > I{}));
  assert(I{} <= I{});
  assert(I{} >= I{});
}

instead of reporting "Error: attempt to compare a singular iterator to a
singular iterator." for any of the listed iterator operations.

[Bug c++/70522] New: Hidden friend functions block qualified name lookup into nested unnamed namespace

2016-04-03 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70522

Bug ID: 70522
   Summary: Hidden friend functions block qualified name lookup
into nested unnamed namespace
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

This program should compile without error:

namespace N {
struct S {
friend void f(S&) {}
};
namespace {
int f;
}
}

int main() {
N::f = 42;
}

yet GCC 6 diagnoses:

prog.cc: In function 'int main()':
prog.cc:11:5: error: 'f' is not a member of 'N'
 N::f = 42;
 ^
prog.cc:11:5: note: suggested alternative:
prog.cc:6:13: note:   'N::{anonymous}::f'
 int f;
 ^

The program compiles correctly if either the friend declaration of f is
commented out, or the unnamed namespace is made an inline namespace.

Language lawyer justification:
The friend declaration of f is not visible to name lookup of N::f per
[namespace.memdef]/3, so the set of declarations S'(N,f) described in
[namespace.qual]/2 is empty. Name lookup should continue into namespaces
"nominated by using directives" in N; unnamed namespaces are such namespaces
per [namespace.unnamed]/1.

[Bug c++/60799] access checking within injected friend functions does not happen in the context of the enclosing class

2016-04-18 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60799

--- Comment #2 from Casey Carter  ---
[basic.lookup.unqual]/9 says that name *lookup* inside friend functions defined
inline works as it does in member functions, but that doesn’t necessarily imply
that the friend function should have the same *access* as member functions
would to the names so found (excepting, of course, names of the class being
defined). 

Given [class.friend]/2:

Declaring a class to be a friend implies that the names of private and
protected members from the class granting friendship can be accessed in the
base-specifiers and member declarations of the befriended class.

and [class.mem]/1:

… Except when used to declare friends (11.3), to declare an unnamed bit-field
(9.6), or to introduce the name of a member of a base class into a derived
class (7.3.3), or when the declaration is an empty-declaration,
member-declarations declare members of the class, and each such
member-declaration shall declare at least one member name of the class. …

It's "clear" that a friend declaration is a member-declaration which – oddly
enough – does not declare a member. So the critical question is whether the
wording “and member declarations” in [class.friend]/2 means “declarations that
are syntactically member-declarations” or “declarations of members.” I'm
inclined to the second interpretation, which would imply the behavior described
in this bug report is what the standard intends.

[Bug c++/60799] access checking within injected friend functions does not happen in the context of the enclosing class

2016-04-18 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60799

--- Comment #3 from Casey Carter  ---
>  I'm inclined to the second interpretation, which would imply the behavior 
> described in this bug report is what the standard intends.

This is me stumbling over my words attempting to say "I think this is NOT a
bug."

[Bug c++/60799] access checking within injected friend functions does not happen in the context of the enclosing class

2016-04-18 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60799

--- Comment #5 from Casey Carter  ---
(In reply to TC from comment #4)
> 
> I don't think that reading makes much sense. Among member-declarations that
> do not declare a member are static_assert-declarations and unnamed bit-field
> declarations, so that reading disallows
> 
> class A {
> constexpr static bool value = true;
> friend class B;
> };
> 
> class B {
> static_assert(B::value, "");
> };
> 
> And disallows D in the below example but not E:
> 
> class C {
> constexpr static int value = 4;
> friend class D;
> friend class E;
> };
> 
> class D {
> int : C::value;
> };
> 
> class E {
> int i : C::value;
> };

I agree that my interpretation breaks things that should work, but given how
[class.mem]/1 goes out of its way to distinguish between member-declarations
and "declarations of members", it does seem to be what is specified. I think
the intent has been lost in the wording.

I've just discovered this problem is the topic of open CWG issue 1699
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1699; upstream is
already on-the-job.

[Bug c++/70522] Hidden friend functions block qualified name lookup into nested unnamed namespace

2016-04-21 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70522

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #2 from Casey Carter  ---
This is a regression of sorts, FWIW, gcc 4.3 compiled it correctly
(http://melpon.org/wandbox/permlink/Efjfvay0U5sZvZP8) back in the day. I assume
that's not quite "regressive" enough for the 6 branch?

[Bug c++/70522] Hidden friend functions block qualified name lookup into nested unnamed namespace

2016-04-22 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70522

--- Comment #5 from Casey Carter  ---
(In reply to Jason Merrill from comment #4)
> (In reply to Casey Carter from comment #2)
> > This is a regression of sorts, FWIW, gcc 4.3 compiled it correctly
> > (http://melpon.org/wandbox/permlink/Efjfvay0U5sZvZP8) back in the day. I
> > assume that's not quite "regressive" enough for the 6 branch?
> 
> I was thinking of putting it in anyway, but that definitely strengthens the
> case.  :)

Clearly GCC6 MUST NOT SHIP until this critical bug - which has gone unnoticed
for years - is fixed. I would suggest elevating to P0 if it wasn't already
resolved ;)

[Bug c++/71105] New: [6 regression] lambas with default captures improperly have function pointer conversions

2016-05-13 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71105

Bug ID: 71105
   Summary: [6 regression] lambas with default captures improperly
have function pointer conversions
   Product: gcc
   Version: 6.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Created attachment 38483
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38483&action=edit
Minimal test case

N4582 [expr.prim.lambda]/7 says:

The closure type for a non-generic lambda-expression with no lambda-capture has
a conversion function to pointer to function with C++ language linkage (7.5)
having the same parameter and return types as the closure type’s function call
operator. ... For a generic lambda with no lambda-capture, the closure type has
a conversion function template to pointer to function. The conversion function
template has the same invented template-parameter-list, and the pointer to
function has the same parameter types, as the function call operator template.
...

So all of:

static_cast([]{});
static_cast([](auto){});
static_cast([](auto x){ return x; });

should compile. These should all be ill-formed since the lambdas have
lambda-captures:

static_cast([i]{});
static_cast([=]{});
static_cast([&]{});
static_cast([i](auto){});
static_cast([=](auto){});
static_cast([&](auto){});
static_cast([i](auto x){ return x; });
static_cast([=](auto x){ return x; });
static_cast([&](auto x){ return x; });

clang (tested 3.4 - 3.9, all versions that implement generic lambdas) diagnoses
all of these conversions as ill-formed; gcc (4.9.0 - 6.1.0, again all versions
that implement generic lambdas) diagnoses only those with explicit captures.

This issue is significant when a library composes function objects via private
inheritance to take advantage of the empty base optimization and it adapts a
(possibly) underconstrained generic lambda to a different/larger valid space of
parameter types. For example, from range-v3:

#include 

template 
struct indirected : F {
indirected(F f) : F(f) {}
template 
auto operator()(I i) -> decltype(std::declval()(*i)) {
return static_cast(*this)(*i);
}
};

int main() {
auto f = [=](auto i) { return i + i; };
auto i = indirected{f};
static_assert(std::is_same())), int>(),
"");
}

This program compiles correctly with the GCC 4.9 and 5 series compilers, 6.1
diagnoses the static_assert line (See
http://melpon.org/wandbox/permlink/yy61pk0iJRfUVBya):

prog.cc: In instantiation of 'main():: [with auto:1 = int*]':
prog.cc:13:24:   required by substitution of 'template
main()operator decltype
(((main()::)0u).operator()(static_cast()))
(*)(auto:1)() const [with auto:1 = int*]'
prog.cc:15:63:   required from here
prog.cc:13:37: error: invalid operands of types 'int*' and 'int*' to binary
'operator+'
 auto f = [=](auto i) { return i + i; };
   ~~^~~

[Bug c++/71117] [6.1 regression] Overeager application of conversion to function pointer during overload resolution of call to function object

2016-05-14 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71117

--- Comment #1 from Casey Carter  ---
Very closely related, but not an exact duplicate of, PR 71105.

[Bug c++/71173] New: [6 regression] Qualified name lookup

2016-05-18 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71173

Bug ID: 71173
   Summary: [6 regression] Qualified name lookup
   Product: gcc
   Version: 6.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

This program should compile without error:

namespace foo {
  namespace bar {
class foo {};
  }
  class baz {};
}
using namespace foo::bar;
::foo::baz mybaz;

but GCC 6 reports (http://melpon.org/wandbox/permlink/2n9QQUT0UIXog2Cj):

prog.cc:9:8: error: 'baz' in 'class foo::bar::foo' does not name a type
 ::foo::baz mybaz;
^~~

The name `::foo` should refer to the namespace `::foo`, not to the class
`::foo::bar::foo` per [namespace.qual]/2:

For a namespace X and name m, the namespace-qualified lookup set S(X,m) is
defined as follows: Let S0(X,m) be the set of all declarations of m in X and
the inline namespace set of X (7.3.1). If S0(X,m) is not empty, S(X,m) is
S0(X,m); otherwise, S(X,m) is the union of S(Ni,m) for all namespaces Ni
nominated by using-directives in X and its inline namespace set.

S0(::,foo) is not empty, so namespaces nominated by using-directives should
never be examined.

[Bug c++/71225] New: [7 Regression] Overeager instantiation of members of non-template class nested in class template

2016-05-22 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71225

Bug ID: 71225
   Summary: [7 Regression] Overeager instantiation of members of
non-template class nested in class template
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Created attachment 38540
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=38540&action=edit
Repro

r236559 fails to compile this TU:

namespace std {
template  struct enable_if;
}

template 
struct BidirectionalRange;

template
struct stride_view
{
struct adaptor
{
template(), int>::type = 0>
void clean() const
{}
template(), int>::type = 0>
void clean() const
{}
void advance()
{
clean();
}
};
};

with diagnostics:

$ ~/gcc-r236559/bin/g++ repro2.cpp -c
repro2.cpp: In member function ‘void stride_view::adaptor::advance()’:
repro2.cpp:23:19: error: call of overloaded ‘clean()’ is ambiguous
 clean();
   ^
repro2.cpp:15:14: note: candidate: void stride_view::adaptor::clean()
const [with int _c_11 = 42; typename std::enable_if<((_c_11 == 43) ||
BidirectionalRange()), int>::type  = 0; Rng = Rng]
 void clean() const
  ^
repro2.cpp:19:14: note: candidate: void stride_view::adaptor::clean()
const [with int _c_14 = 42; typename std::enable_if<((_c_14 == 43) || (!
BidirectionalRange())), int>::type  = 0; Rng = Rng]
 void clean() const
  ^

This is a regression from the behavior of about a week ago.

[Bug c++/67185] [C++14] Link error on ODR-use of variable template partial specialization

2016-05-30 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67185

--- Comment #6 from Casey Carter  ---
ODR-use of different specializations of the same partially-specialized variable
template still trigger the error in GCC 6 (Error: symbol `x' is already
defined):

template 
bool x = false;

template 
bool x = true;

int main() { return x + x; }

Which may be covered by one of the other "partially-specialized variable
template" bugs.

Hmmm, looks like its in Tom's comment on the regression in 70095
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70095#c2). If you're planning to
address that comment - which I assume from the state changing to ASSIGNED
moments ago - I'll leave this closed.

[Bug libstdc++/71364] [7 regression] recent tuple changes break range-v3 merge.cpp

2016-06-16 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71364

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #4 from Casey Carter  ---
The bug is in range-v3 and the Ranges TS
(https://github.com/ericniebler/stl2/issues/172) which was triggered by libc++
tuple changes on April 15 (https://github.com/ericniebler/range-v3/issues/324). 

Our specification of tagged - the template wrapper that implements
tagged_pair and tagged_tuple - inherits constructors from Base but has no
specific constructors that take Base const& or Base&&. Consequently conversions
from Base have been using tuple/pair's converting constructor instead of the
copy/move constructor. LWG2549
(http://cplusplus.github.io/LWG/lwg-active.html#2549) makes this not work
anymore: the converting constructor refuses to accept argument expressions with
the tuple's same type that should be using the copy/move constructors.

This has been fixed in range-v3, but not yet in the Ranges TS.

[Bug c++/80633] New: [7/8 Regression] -Wstrict-aliasing false positive

2017-05-04 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80633

Bug ID: 80633
   Summary: [7/8 Regression] -Wstrict-aliasing false positive
   Product: gcc
   Version: 7.1.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Created attachment 41321
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41321&action=edit
Repro (sorry, not library-free)

gcc 7.1.1 20170504 and 8.0.0 20170504 - but not 6.2/5.4/4.9.4 - incorrectly
diagnose this program:

#include 

extern void f(std::istream&);
std::ifstream ss;
using T = decltype(f(ss)); // warning: dereferencing type-punned pointer will
break strict-aliasing rules

when compiling with "gcc -Wstrict-aliasing -O2 -c". The diagnostic is notably
not emitted for "decltype(f(std::declval()))".

[Bug c++/81026] New: Lookup of dependent member template incorrectly finds non-member

2017-06-08 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81026

Bug ID: 81026
   Summary: Lookup of dependent member template incorrectly finds
non-member
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

GCC 4/5/6/7/8 diagnose this correct program:

namespace std {
template struct extent;
}

using namespace std;

template 
struct S {
void f() { T{}.template extent<42>(); }
};

with:

prog.cc: In member function 'void S::f()':
prog.cc:9:38: error: type/value mismatch at argument 1 in template parameter
list for 'template struct std::extent'
 void f() { T{}.template extent<42>(); }
  ^
prog.cc:9:38: note:   expected a type, got '42'

[Bug c++/80633] [7/8 Regression] -Wstrict-aliasing false positive

2017-06-19 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80633

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #2 from Casey Carter  ---
(In reply to Jason Merrill from comment #1)
> I can't reproduce this with 20170619.  Are you still seeing it?

Nope - it appears to have disappeared on trunk.

[Bug c++/81178] New: [concepts] poor (partial?) diagnostic for alias substitution failure in a concept body

2017-06-22 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81178

Bug ID: 81178
   Summary: [concepts] poor (partial?) diagnostic for alias
substitution failure in a concept body
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

GCC 6.3/7.1/trunk as of 20170621 all diagnose this ill-formed program
(https://wandbox.org/permlink/uatmNSnlLbhvSvls):

template
concept bool C1 = true;

template
using alias = typename T::type;

template
concept bool C2 = C1>;

void bar(C2) {}

int main() { bar(42); }

with:

prog.cc: In function 'int main()':
prog.cc:12:20: error: cannot call function 'void bar(auto:1) [with auto:1 =
int]'
 int main() { bar(42); }
^
prog.cc:10:6: note:   constraints not satisfied
 void bar(C2) {}
  ^~~
prog.cc:10:6: note: in the expansion of concept 'C2 template
concept const bool C2 [with T = int]'

(Yes, that is the entire diagnostic.) If we expand the definition of C2 fully
into bar (https://wandbox.org/permlink/GKW0vWSPIY5XrGRE):

template
  requires C1>
void bar(T) {}

the compiler gives a more complete diagnostic:

prog.cc: In function 'int main()':
prog.cc:14:20: error: cannot call function 'void bar(T) [with T = int]'
 int main() { bar(42); }
^
prog.cc:12:6: note:   constraints not satisfied
 void bar(T) {}
  ^~~
prog.cc:12:6: note: invalid use of the concept 'C1'
prog.cc:14:20: error: 'int' is not a class, struct, or union type
 int main() { bar(42); }
^

[Bug c++/78841] New: [6 regression] optimizer bug (silent bad codegen)

2016-12-16 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78841

Bug ID: 78841
   Summary: [6 regression] optimizer bug (silent bad codegen)
   Product: gcc
   Version: 6.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

g++ 6.2 (not 5.4, or 4.9, or 4.8, or trunk) generates bad code for the attached
repro at -O2 and higher. "silent bad codegen" just barely trumps "already fixed
on trunk" to my mind, so here's a repro; my feelings won't be hurt if you
WONTFIX this.

Apologies for the huge repro, I've had a hard time reducing it from here
without making the bug disappear.

[Bug c++/78841] [6 regression] optimizer bug (silent bad codegen)

2016-12-19 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78841

--- Comment #2 from Casey Carter  ---
Created attachment 40371
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40371&action=edit
compressed preprocessed repro

[Bug c++/78841] [6 regression] optimizer bug (silent bad codegen)

2016-12-19 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78841

--- Comment #5 from Casey Carter  ---
I have verified that gcc-6-branch compiles the repro correctly, so yes, this is
a dup of PR78047.

[Bug c++/79143] New: [7 Regression][new inheriting constructors] inheriting constructor fails with brace initialization

2017-01-18 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79143

Bug ID: 79143
   Summary: [7 Regression][new inheriting constructors] inheriting
constructor fails with brace initialization
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

r244608 with -std=c++1z fails to compile this program both with and without
-fno-new-inheriting-constructors:

struct base {
  base(int, int) {}
};

template
struct derived : base {
  using base::base;
};

int main() {
  base(13, 42); // Fine
  derived(13, 42); // Fine
  base{13, 42}; // Fine
  derived{13, 42}; // Error
}

with diagnostics:

prog.cc: In function 'int main()':
prog.cc:14:22: error: too many initializers for 'derived'
   derived{13, 42}; // Error
  ^
prog.cc:14:22: error: could not convert '13' from 'int' to 'base'

[Bug c++/68858] Cannot use fold expression in requirements with two parameters packs

2017-02-03 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68858

--- Comment #1 from Casey Carter  ---
This seems to be a duplicate of PR 68812.

[Bug c++/79143] [7 Regression][new inheriting constructors] inheriting constructor fails with brace initialization

2017-02-07 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79143

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #4 from Casey Carter  ---
(In reply to Jonathan Wakely from comment #3)
> I think this is a bug. derived is not an aggregate, because it inherits a
> user-provided constructor, so braced-init should call the base(int, int)
> constructor, not attempt aggregate init.

This. N4618 [dcl.init.aggr]/1 says:

1 An aggregate is an array or a class with

  1.1 --- no user-provided, explicit, or inherited constructors

  [...]

[Bug c++/67384] [concepts] More fun with deduction constraints

2017-02-16 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67384

Casey Carter  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 CC||Casey at Carter dot net
 Resolution|--- |FIXED

--- Comment #1 from Casey Carter  ---
This no longer reproduces on 6.3 or trunk.

[Bug c++/67491] [meta-bug] concepts issues

2017-02-16 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491
Bug 67491 depends on bug 67384, which changed state.

Bug 67384 Summary: [concepts] More fun with deduction constraints
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67384

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

[Bug c++/67491] [meta-bug] concepts issues

2017-02-16 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67491
Bug 67491 depends on bug 67150, which changed state.

Bug 67150 Summary: [c++-concepts] Expression constraint fails with dependent 
types used as a deduction constraint target
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67150

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |FIXED

[Bug c++/67150] [c++-concepts] Expression constraint fails with dependent types used as a deduction constraint target

2017-02-16 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67150

Casey Carter  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 CC||Casey at Carter dot net
 Resolution|--- |FIXED

--- Comment #1 from Casey Carter  ---
This fails to reproduce on both GCC 6.3 and trunk.

[Bug c++/79591] New: [concepts] failure to distinguish overloads from different namespaces with differing constraints

2017-02-18 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79591

Bug ID: 79591
   Summary: [concepts] failure to distinguish overloads from
different namespaces with differing constraints
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Created attachment 40772
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40772&action=edit
Minimal repro

GCC 6.3 and trunk both miscompile this program:

template  concept bool True = true;

// Fine.
namespace X {
  void f(auto) {}
  void f(True) {}
}

void f(auto) {}
namespace Y {
  void f(True) {}
  using ::f;
  // error: 'template void f(auto:3)' conflicts with a previous
declaration
}

The compiler is happy to overload when the two abbreviated function templates
are declared in the same scope - as in namespace X - but not when one is
imported into the namespace via a using declaration.

[Bug c++/78715] [concepts] Access specifiers ignored after concept declaration

2017-04-07 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78715

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #1 from Casey Carter  ---
Another simple program that reproduces this bug with 6.3 and trunk:

template 
concept bool C1 = true;

template 
concept bool C2 = requires { { 42 } -> C1; };

int main() {
class A { int x; } a;
a.x = 42;
}

Use of a partial-concept-id as a constrained-type-specifier seems to be the
trigger.

[Bug c++/82740] New: [concepts] requires clause evaluated early

2017-10-26 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82740

Bug ID: 82740
   Summary: [concepts] requires clause evaluated early
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Created attachment 42483
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42483&action=edit
Repro

Trunk as of 20170825 miscompiles this program
(https://wandbox.org/permlink/70zH8c8JMQZMDUas):

template
concept bool C = requires(const T& t) { t.foo(); };

template
struct Base {
constexpr T const& derived() const { return static_cast(*this); }
constexpr bool bar() const requires
#ifndef WORKAROUND
requires(const T& t) { t.foo(); }
#else
C
#endif
{ derived().foo(); return true; }
};

template
struct Derived : Base> {
constexpr void foo() const {}
};

int main() {
static_assert(Derived{}.bar());
}

with diagnostics:

prog.cc: In instantiation of 'struct Base >':
prog.cc:17:8:   required from 'struct Derived'
prog.cc:22:32:   required from here
prog.cc:9:34: error: invalid use of incomplete type 'const struct Derived'
 requires(const T& t) { t.foo(); }
~~^~~
prog.cc:17:8: note: declaration of 'struct Derived'
 struct Derived : Base> {
^~~

despite that N4700 [temp.inst]/16
(http://eel.is/c++draft/temp.spec#temp.inst-16) specifies that:

The partial-concept-ids and requires-clause of a template specialization or
member function are not instantiated along with the specialization or function
itself, even for a member function of a local class; substitution into the
atomic constraints formed from them is instead performed as specified in
[temp.constr.decl] and [temp.constr.atomic] when determining whether the
constraints are satisfied. [ Note: The satisfaction of constraints is
determined during name lookup or overload resolution ([over.match]). — end note
]

(Note that the text of [temp.inst]/16 in the Concepts TS is similar.)

If WORKAROUND is defined, replacing the ad hoc requirement with an identical
named concept, the program compiles without diagnostics.

[Bug c++/67595] concepts code causes segfault

2017-10-30 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67595

--- Comment #5 from Casey Carter  ---
The original program submission is ill-formed due to the requirement on line
270 being poorly designed:

requires std::is_same::value;

for a random access iterator x, "x - (x - x)" is typically a prvalue of the
same type as x, whereas "x += (x - x)" is typically an lvalue of that type. X
and X& are obviously not the same type.

[Bug c++/82247] [concepts] Name deduction in concepts fails depending on the argument type

2017-10-31 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82247

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #4 from Casey Carter  ---
This is not a bug: it's two-phase name lookup. At the point of definition for
Fooable:

#include 
#include 

template 
bool concept Fooable = requires(const T& t) {
{ foo(t) }; // foo is unknown here
};

the compiler records the set of declarations it has seen for "foo" (the empty
set). When you later "instantiate" the concept foo can only resolve to (a) a
member of the (again, empty) set recorded at definition, or (b) a declaration
found by argument-dependent lookup. Since there are no associated namespaces
for fundamental types, only your user-defined type which has a "foo" defined in
its associated namespace successfully concept checks.

[Bug c++/82768] ICE in synthesize_implicit_template_parm, at cp/parser.c:39338

2017-11-07 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82768

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net

--- Comment #2 from Casey Carter  ---
(In reply to Martin Liška from comment #1)
> Confirmed on all release that support -fconcepts. Is it a valid code?

No. Using a placeholder type for the parameter of a requires expression is not
supported. (Specifically, the Addressable parameter in the definition of
InternalCompilerError.)

[Bug libstdc++/77537] New: pair constructors do not properly SFINAE

2016-09-08 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77537

Bug ID: 77537
   Summary: pair constructors do not properly SFINAE
   Product: gcc
   Version: 6.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Created attachment 39586
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39586&action=edit
Patch

Both static_asserts in this program fail:

#include 
#include 

struct moveonly {
moveonly() = default;
moveonly(moveonly&&) = default;
};

template
using P = std::pair;
static_assert(!std::is_constructible, int, moveonly&>::value,
"FAIL");
static_assert(!std::is_constructible, P>::value,
"FAIL");

Because the resolution of PR 70437 makes many of the pair constructors
inappropriately participate in overload resolution.

Attached patch is a poorly-tested fix. (It works for this repro, and the repro
in 70437, but caveat emptor.)

[Bug libstdc++/77537] pair constructors do not properly SFINAE

2016-09-21 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77537

--- Comment #4 from Casey Carter  ---
Any chance of applying this to 6-branch as well? This is breaking both range-v3
and cmcstl2 in a nasty and hard-to-workaround way.

[Bug libstdc++/77537] [6 Regression] pair constructors do not properly SFINAE

2016-09-26 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77537

--- Comment #11 from Casey Carter  ---
Thanks again Ville - I owe you a beer in Issaquah.

[Bug c++/78173] New: Hard error subtracting pointers to incomplete type in SFINAE context

2016-10-31 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78173

Bug ID: 78173
   Summary: Hard error subtracting pointers to incomplete type in
SFINAE context
   Product: gcc
   Version: 7.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Created attachment 39934
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=39934&action=edit
Minimal repro

This TU, which should compile without errors:

template
T&& declval();

template
using void_t = void;

template
struct foo { static const bool value = false; };
template
struct foo() - declval())>> {
static const bool value = true;
};

struct A;

#define STATIC_ASSERT(...) static_assert(__VA_ARGS__, #__VA_ARGS__)

STATIC_ASSERT(!foo::value); // error: invalid use of 'void'
STATIC_ASSERT(!foo::value); // error: invalid use of incomplete type
'struct A'

instead produces diagnostics
(http://melpon.org/wandbox/permlink/EwcDiz7ZuqpFXdHZ):

prog.cc: In substitution of 'template struct foo() - declval()))> > [with T = void*]':
prog.cc:22:1:   required from here
prog.cc:10:44: error: invalid use of 'void'
 struct foo() - declval())>> {
   ~^~
prog.cc: In substitution of 'template struct foo() - declval()))> > [with T = A*]':
prog.cc:23:1:   required from here
prog.cc:10:44: error: invalid use of incomplete type 'struct A'
prog.cc:14:8: note: forward declaration of 'struct A'
 struct A;
^

[Bug c++/69288] [concepts] Subsumption failure with constrained member functions of class template

2016-11-01 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69288

Casey Carter  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 CC||Casey at Carter dot net
 Resolution|--- |FIXED

--- Comment #1 from Casey Carter  ---
This no longer reproduces with 6.2 or trunk.

[Bug c++/66184] New: Rejection of partial specialization of a variable template in a non-global namespace

2015-05-17 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66184

Bug ID: 66184
   Summary: Rejection of partial specialization of a variable
template in a non-global namespace
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Created attachment 35558
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35558&action=edit
testcase.cpp

Both 5.1.0 on Wandbox and 6.0 r223061 reject this program:

namespace foo {
template  constexpr bool same = false;
template <> constexpr bool same = true;
template  constexpr bool same = true;

static_assert(same, "");
static_assert(!same, "");
}

int main() {}

with error message:

bug2.cpp:4:35: error: specialization of ‘template constexpr const
bool foo::same< ,  >’ in
different namespace [-fpermissive]
 template  constexpr bool same = true;
   ^
bug2.cpp:2:40: error:   from definition of ‘template constexpr
const bool foo::same< ,  >’
[-fpermissive]
 template  constexpr bool same = false;
^
The full specialization of same is accepted regardless of namespace.
Both versions compile the program correctly if "same" is in the global
namespace.

[Bug c++/66218] New: [c++-concepts] "inconsistent deduction for ‘auto’" with a partial-concept-id in a deduction constraint

2015-05-20 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66218

Bug ID: 66218
   Summary: [c++-concepts] "inconsistent deduction for ‘auto’"
with a partial-concept-id in a deduction constraint
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Created attachment 35576
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35576&action=edit
testcase.cpp

Compiling this correct program with r223444 of the c++-concepts branch:

#include 

template 
concept bool Same =
  std::is_same::value;

template 
concept bool C =
  requires(T t) {
{ t } -> Same;
  };

template 
constexpr bool f() { return false; }
template 
constexpr bool f() { return true; }

static_assert(f(), "");
static_assert(f(), "");
static_assert(f(), "");

int main() {}

produces errors:

bug2.cpp:19:22: error: inconsistent deduction for ‘auto’: ‘char’ and then ‘int’
 static_assert(f(), "");
  ^
bug2.cpp:19:1: error: static assertion failed: 
 static_assert(f(), "");
 ^
bug2.cpp:20:25: error: inconsistent deduction for ‘auto’: ‘char’ and then
‘double’
 static_assert(f(), "");
 ^
bug2.cpp:20:1: error: static assertion failed: 
 static_assert(f(), "");
 ^

It appears that the result of the first deduction is stored in memory instead
of being discarded.

[Bug c++/66260] New: [C++14] Failure to compile variable template with recursively defined partial specialization

2015-05-22 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66260

Bug ID: 66260
   Summary: [C++14] Failure to compile variable template with
recursively defined partial specialization
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Created attachment 35604
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35604&action=edit
testcase.cpp

Both GCC 5.1.0 and 6.0 fail to compile this program:

template 
constexpr bool foo = false;
template <>
constexpr bool foo = true;
template 
constexpr bool foo = foo;

static_assert(foo, "");
static_assert(!foo, "");
static_assert(foo, "");
static_assert(!foo, "");
static_assert(foo, "");
static_assert(!foo, "");

int main() {}

5.1.0 doesn't seem to recognize that foo is a template-name in the definition
of the foo partial specialization:

prog.cc:6:33: error: expected primary-expression before '>' token
 constexpr bool foo = foo;
 ^
prog.cc:6:34: error: expected primary-expression before ';' token
 constexpr bool foo = foo;
  ^
prog.cc:6: confused by earlier errors, bailing out

6.0 20150522 at least tries to compile the recursion, but fails nonetheless:

prog.cc: In instantiation of 'constexpr const bool foo':
prog.cc:6:16:   recursively required from 'constexpr const bool foo'
prog.cc:6:16:   required from 'constexpr const bool foo'
prog.cc:10:15:   required from here
prog.cc:6:16: fatal error: template instantiation depth exceeds maximum of 900
(use -ftemplate-depth= to increase the maximum)
 constexpr bool foo = foo;
^
compilation terminated.


[Bug c++/66184] [C++14] Rejection of partial specialization of a variable template in a non-global namespace

2015-05-29 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66184

Casey Carter  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |FIXED

--- Comment #1 from Casey Carter  ---
Fixed in r223462.


[Bug c++/66184] [C++14] Rejection of partial specialization of a variable template in a non-global namespace

2015-05-29 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66184

--- Comment #2 from Casey Carter  ---
Correction: r223462 was a fix on the c++-concepts branch, the trunk fix was
r223461.


[Bug libstdc++/59768] New: [4.8 Regression] std::thread constructor not handling reference_wrapper correctly

2014-01-10 Thread Casey at Carter dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59768

Bug ID: 59768
   Summary: [4.8 Regression] std::thread constructor not handling
reference_wrapper correctly
   Product: gcc
   Version: 4.8.2
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net

Created attachment 31809
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=31809&action=edit
Minimal test case.

Originally reported in Stackoverflow question
http://stackoverflow.com/questions/21059115/c11-thread-class-how-to-use-a-class-member-function

Construction of a std::thread with a pointer-to-member-function and
reference_wrapper as in this simple program:

#include 
#include 
#include 

class A {
public:
void foo(int n) { std::cout << n << std::endl; }
};

int main()
{
A a;

std::thread t1(&A::foo, std::ref(a), 100);
t1.join();
}

incorrectly results in a compilation error:

In file included from /usr/local/include/c++/4.8.2/thread:39:0,
  from check.cc:2:
/usr/local/include/c++/4.8.2/functional: In instantiation of ‘struct
std::_Bind_simple(std::reference_wrapper,
int)>’:
/usr/local/include/c++/4.8.2/thread:137:47:   required from
‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void
(A::*)(int); _Args = {std::reference_wrapper, int}]’
check.cc:13:42:   required from here
/usr/local/include/c++/4.8.2/functional:1697:61: error:no type named ‘type’ in
‘class std::result_of(std::reference_wrapper,
int)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
  ^
/usr/local/include/c++/4.8.2/functional:1727:9: error:no type named ‘type’ in
‘class std::result_of(std::reference_wrapper,
int)>’
  _M_invoke(_Index_tuple<_Indices...>)
  ^

I reduced the original program to:

#include 
#include 

int main() {
  struct A { void foo(int) {} } a;
  std::thread(&A::foo, std::ref(a), 100).join();
}

which still displays the erroneous behavior. Note that std::bind(&A::foo,
std::ref(a), 100) *does* compile correctly, as does a similar program in which
the member function foo has no parameter.

Program is incorrectly compiled by g++ 4.8.2 and 4.8.1, correctly compiles with
4.6.4 and 4.7.3.

[Bug libstdc++/59768] [4.8 Regression] std::thread constructor not handling reference_wrapper correctly

2014-01-11 Thread Casey at Carter dot net
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59768

--- Comment #1 from Casey Carter  ---
This behavior would appear to NOT be erroneous. I was operating under the
assumption that the behavior of the std::thread constructor and std::bind were
identical by design given that both use the "INVOKE" machinery defined by the
standard in [func.require]/1. However, the replacement of reference_wrapper
with its stored reference is specified only for std::bind in
[func.bind.bind]/10:


The values of the bound arguments v1, v2, ..., vN and their corresponding types
V1, V2, ..., VN depend on the types TiD derived from the call to bind and the
cv-qualifiers cv of the call wrapper g as follows:

— if TiD is reference_wrapper, the argument is tid.get() and its type Vi is
T&;


This would then not be a regression in the 4.8 line, but a correction to a
long-standing bug. I apologize for wasting your time with an erroneous bug
report.

[Bug c++/67545] New: [concepts] Failure to properly substitute template parameters into requires-clause

2015-09-10 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67545

Bug ID: 67545
   Summary: [concepts] Failure to properly substitute template
parameters into requires-clause
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

Created attachment 36323
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36323&action=edit
Preprocessed test case

r227603 fails to compile this correct TU:

#include 

struct I {
  int operator*() const;
};

template 
using Ref = decltype(*std::declval());

template 
  requires !__stl2::Swappable, Ref>()
static constexpr bool bar() { return true; }

template 
  requires !__stl2::Swappable, Ref>()
static constexpr bool foo() { return true; }

static_assert(bar()); // Fine
static_assert(foo()); // Error

with error:

~/gcc6/bin/g++ -std=gnu++1z -I ~/cmcstl2/include -I ~/cmcstl2/meta/include
foo.cpp -c
foo.cpp:19:19: error: cannot call function ‘constexpr bool foo() [with U = I]’
 static_assert(foo()); // Error
   ^
foo.cpp:16:23: note:   constraints not satisfied
 static constexpr bool foo() { return true; }
   ^
foo.cpp:16:23: note:   ‘! Swappable, Ref >()’ evaluated to false

Despite the fact that the requirements on foo and bar are functionally
equivalent, the call to bar succeeds whilst the call to `bar` fails to compile.
I conjecture that the substitution of template parameters into foo's requires
clause is not working correctly.

[Bug c++/67545] [concepts] Failure to properly substitute template parameters into requires-clause

2015-09-13 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67545

Casey Carter  changed:

   What|Removed |Added

   Severity|normal  |major

--- Comment #1 from Casey Carter  ---
Raising importance to "major": I have a hunch that this may be the root cause
of some of my other reported bugs.


[Bug c++/67579] New: [concepts] Memoization for constraint expressions

2015-09-14 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67579

Bug ID: 67579
   Summary: [concepts] Memoization for constraint expressions
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: enhancement
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

While implementing the Ranges TS I've found that the implementation of concepts
in GCC scales very poorly to larger and more complex systems. I've been able to
achieve 1-2 order of magnitude improvements in compile time and memory usage by
hand coding memoization for some concepts with constexpr variable templates.
E.g., replacing

  template 
  concept bool Foo = // requirements

with

  template 
  constexpr bool Foo_ = false;
  template 
requires // requirements
  constexpr bool Foo_ = true;

  template 
  concept bool Foo = Foo_;

which is fine when Foo need not participate in subsumption relationships. If
Foo *does* need to participate in subsumption relationships then performing
this transformation by hand is not possible since it hides the relationship
between Foo and "requirements" from the compiler's view.

If concepts & constraint expressions are to be generally applicable the
implementation must provide some means of reducing the cost of repeated
evaluation.


[Bug c++/67810] New: Non-expression recognized as fold expression

2015-10-01 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67810

Bug ID: 67810
   Summary: Non-expression recognized as fold expression
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

r228351 fails to compile this correct program:

template 
constexpr bool Test = true;

template )>
void f();

with error:

~/gcc6-r228351/bin/g++ -std=c++14 -c foo.cpp 
foo.cpp:4:41: warning: fold-expressions only available with -std=c++1z or
-std=gnu++1z
 template )>
 ^
foo.cpp:4:47: error: expected binary operator before ‘)’ token
 template )>
   ^
foo.cpp:5:1: error: expected primary-expression before ‘void’
 void f();
 ^
foo.cpp:5:1: error: expected ‘>’ before ‘void’
foo.cpp:5:9: error: expected unqualified-id before ‘;’ token
 void f();
 ^

[Bug c++/67810] Non-expression recognized as fold expression

2015-10-01 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67810

Casey Carter  changed:

   What|Removed |Added

 CC||Casey at Carter dot net,
   ||jason at gcc dot gnu.org

--- Comment #1 from Casey Carter  ---
Presumably this bug was introduced by the implementation of fold expressions in
r227883. CCing Jason.


[Bug c++/67813] New: [C++14] copy-initialization of object with pointer member fails in constexpr function

2015-10-01 Thread Casey at Carter dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67813

Bug ID: 67813
   Summary: [C++14] copy-initialization of object with pointer
member fails in constexpr function
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: Casey at Carter dot net
  Target Milestone: ---

r223851 fails to compile this correct program fragment:

struct Ptr {
  int* p;

  constexpr Ptr(int* p) noexcept : p{p} {}
  constexpr int& operator*() const {
return *p;
  }
};

constexpr int f(int& i) {
  //Ptr first{&i}; // Works.
  Ptr first = &i;  // Error
  return *first;
}

constexpr int g() {
  int i = 42;
  return f(i);
}

static_assert(g() == 42);

with error:

~/gcc6-r228351/bin/g++ -std=c++14 foo.cpp -c
foo.cpp:21:1: error: non-constant condition for static assertion
 static_assert(g() == 42);
 ^
foo.cpp:21:16:   in constexpr expansion of ‘g()’
foo.cpp:18:11:   in constexpr expansion of ‘f(i)’
foo.cpp:13:11:   in constexpr expansion of ‘first.Ptr::operator*()’
foo.cpp:21:1: error: accessing uninitialized member ‘Ptr::p’

If the local is instead direct-initialized with "Ptr first{&i};", the program
correctly compiles without diagnostics. Results are identical if Ptr's member p
is type int& (with the constructor and operator* updated accordingly).

  1   2   >