[Bug c++/93807] New: -std=c++2a allows to omit out-of-class declaration in template class

2020-02-18 Thread bobogu at atlas dot cz
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93807

Bug ID: 93807
   Summary: -std=c++2a allows to omit out-of-class declaration in
template class
   Product: gcc
   Version: 9.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: bobogu at atlas dot cz
  Target Milestone: ---

gcc -v:
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/9.2.1/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib
--libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info
--with-pkgversion='Arch Linux 9.2.1+20200130-2'
--with-bugurl=https://bugs.archlinux.org/
--enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --enable-shared
--enable-threads=posix --with-system-zlib --with-isl --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch
--disable-libssp --enable-gnu-unique-object --enable-linker-build-id
--enable-lto --enable-plugin --enable-install-libiberty
--with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib
--disable-werror --enable-checking=release --enable-default-pie
--enable-default-ssp --enable-cet=auto gdc_include_dir=/usr/include/dlang/gdc
Thread model: posix
gcc version 9.2.1 20200130 (Arch Linux 9.2.1+20200130-2)

Command line:
gcc -lstdc++ -std=c++2a main.cpp

With -std=c++2a, gcc allows me to omit out-of-class declaration of a friend
member function in a template class:

// template 
// class Foo;
// template 
// constexpr bool operator==(T lhs, const Foo& rhs);

template 
class Foo {
public:
constexpr Foo(T k) : mK(k) {}

constexpr friend bool operator==(T lhs, const Foo& rhs);
private:
T mK;
};

template 
constexpr bool operator==(T lhs, const Foo& rhs) {
return lhs == rhs.mK;
}

int main() {
return 1 == Foo(1) ? 0 : 1;
}

This code compiles just fine and the binary returns 0, although I didn't find
anything in the C++20 standard that would allow us to omit the out-of-class
declaration. I would expect this code to work only if the first 4 lines were
uncommented.

The same behaviour was also reproduced on a gcc 9.1.0.

For reference, clang doesn't accept this code.

[Bug c++/87016] std::optional::operator= in constexpr context

2018-08-20 Thread bobogu at atlas dot cz
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87016

--- Comment #9 from bobogu at atlas dot cz ---
(In reply to Jonathan Wakely from comment #8)
> (In reply to bobogu from comment #7)
> > All right, I'm sorry then... I just thought that as this is undocumented, it
> > could lead to producing an unportable code.
> 
> It could, except that you should get the same behaviour for every correct
> implementation. Your example doesn't compile with libc++, but that's a bug:
> https://bugs.llvm.org/show_bug.cgi?id=38638

Yes, that was just my misconception before you got me on the right track - I
thought clang's behaviour was correct because of what I saw in the standard :-)

[Bug c++/87016] std::optional::operator= in constexpr context

2018-08-20 Thread bobogu at atlas dot cz
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87016

--- Comment #7 from bobogu at atlas dot cz ---
(In reply to Jonathan Wakely from comment #5)
> (In reply to bobogu from comment #4)
> All implementations define the assignment operator as defaulted, and so the
> compiler makes it constexpr.
> 
> In fact the p0602R3 proposal you linked to is relevant, because it would
> *require* implementations to define the operator as defaulted (in order to
> be trivial) and so the compiler is always going to make it constexpr for
> std::optional.

Ah, finally it makes sense to me!

> Anyway, I don't consider "I can use more things in constant expressions than
> the standard says" to be a bug.

All right, I'm sorry then... I just thought that as this is undocumented, it
could lead to producing an unportable code.

Anyway, thank you for clearing it out.

> I've raised this with the standards committee.
Thanks!

[Bug c++/87016] std::optional::operator= in constexpr context

2018-08-20 Thread bobogu at atlas dot cz
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87016

--- Comment #4 from bobogu at atlas dot cz ---
(In reply to Jonathan Wakely from comment #3)
> (In reply to bobogu from comment #2)
> When you assign an int to optional it is equivalent to constructing a
> temporary optional and then assigning that to the left-hand operand.

I feel stupid, but I still don't understand how that can work in a constexpr
context when the current c++17 standard doesn't specify any constexpr
assignment operator. 

The second line of this snippet
  std::optional bar = 3;
  bar = std::optional(10);

would call the 3rd assignment operator
(https://en.cppreference.com/w/cpp/utility/optional/operator%3D), right? And
the operator isn't constexpr, but works in a constexpr function.

[Bug c++/87016] std::optional::operator= in constexpr context

2018-08-20 Thread bobogu at atlas dot cz
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87016

--- Comment #2 from bobogu at atlas dot cz ---
Do I understand it correctly that this will get optimized into one statement
saying

  bar = std::optional(10);

If so, is there something that could prevent such optimizations in order to
check if the code is portable?

Also, just to clarify, this has nothing to do with this proposal
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0602r3.html to which
someone has pointed me to?

[Bug c++/87016] New: std::optional::operator= in constexpr context

2018-08-19 Thread bobogu at atlas dot cz
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87016

Bug ID: 87016
   Summary: std::optional::operator= in constexpr context
   Product: gcc
   Version: 8.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: bobogu at atlas dot cz
  Target Milestone: ---

Created attachment 44558
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44558&action=edit
preprocessed TU

According to the standard, there is no assignment operator that should work in
a constexpr context, however, I am able to successfully compile and use the
following snippet:

// gcc -lstdc++ -std=c++17 main.cpp @Linux laptop 4.17.11-arch1 x86_64

constexpr std::optional foo() {
std::optional bar = 3;
bar = 10;
return bar;
}