Bug 108769 - [C++20] __is_trivial returns true even if a default constructor's constraints are unsatisfied
Summary: [C++20] __is_trivial returns true even if a default constructor's constraints...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Marek Polacek
URL:
Keywords: accepts-invalid
Depends on:
Blocks:
 
Reported: 2023-02-13 09:06 UTC by Roy Jacobson
Modified: 2024-07-18 19:19 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2023-02-13 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Roy Jacobson 2023-02-13 09:06:49 UTC
GCC accepts this code:

template <class T>
struct S {
    S() requires false = default;
};
static_assert(__is_trivial(S<int>));

There are some related DRs that GCC doesn't implement (like DR1363), but I don't think this falls under any of them.
Comment 1 GCC Commits 2024-07-18 19:15:32 UTC
The trunk branch has been updated by Marek Polacek <mpolacek@gcc.gnu.org>:

https://gcc.gnu.org/g:9690fb3a43e5cf26a5fb853283d4200df312a640

commit r15-2146-g9690fb3a43e5cf26a5fb853283d4200df312a640
Author: Marek Polacek <polacek@redhat.com>
Date:   Tue Jun 18 16:49:24 2024 -0400

    c++: implement DR1363 and DR1496 for __is_trivial [PR85723]
    
    is_trivial was introduced in
    <https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2230.html>
    which split POD into is_trivial and is_standard_layout.
    
    Later came CWG 1363.  Since
    
      struct A {
        A() = default;
        A(int = 42) {}
      };
    
    cannot be default-initialized, it should not be trivial, so the definition
    of what is a trivial class changed.
    
    Similarly, CWG 1496 concluded that
    
      struct B {
        B() = delete;
      }:
    
    should not be trivial either.
    
    P0848 adjusted the definition further to say "eligible".  That means
    that
    
      template<typename T>
      struct C {
        C() requires false = default;
      };
    
    should not be trivial, either, since C::C() is not eligible.
    
    Bug 85723 reports that we implement none of the CWGs.
    
    I chose to fix this by using type_has_non_deleted_trivial_default_ctor
    which uses locate_ctor which uses build_new_method_call, which would
    be used by default-initialization as well.  With that, all __is_trivial
    problems I could find in the Bugzilla are fixed, except for PR96288,
    which may need changes to trivially-copyable, so I'm not messing with
    that now.
    
    I hope this has no ABI implications.  There's effort undergoing to
    remove "trivial class" from the core language as it's not really
    meaningful.  So the impact of this change should be pretty low except
    to fix a few libstdc++ problems.
    
            PR c++/108769
            PR c++/58074
            PR c++/115522
            PR c++/85723
    
    gcc/cp/ChangeLog:
    
            * class.cc (type_has_non_deleted_trivial_default_ctor): Fix formatting.
            * tree.cc (trivial_type_p): Instead of TYPE_HAS_TRIVIAL_DFLT, use
            type_has_non_deleted_trivial_default_ctor.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/warn/Wclass-memaccess.C: Add dg-warning.
            * g++.dg/ext/is_trivial1.C: New test.
            * g++.dg/ext/is_trivial2.C: New test.
            * g++.dg/ext/is_trivial3.C: New test.
            * g++.dg/ext/is_trivial4.C: New test.
            * g++.dg/ext/is_trivial5.C: New test.
            * g++.dg/ext/is_trivial6.C: New test.
Comment 2 Marek Polacek 2024-07-18 19:19:43 UTC
Fixed for GCC 15; thanks for the bug report.