Bug 53036 - [c++11] trivial class fails std::is_trivial test
Summary: [c++11] trivial class fails std::is_trivial test
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2012-04-18 22:08 UTC by Eric Niebler
Modified: 2019-02-11 20:53 UTC (History)
7 users (show)

See Also:
Host:
Target:
Build:
Known to work: 6.3.0, 7.4.0, 8.2.0, 9.0
Known to fail: 4.7.4, 4.8.5, 4.9.4
Last reconfirmed: 2015-03-24 00:00:00


Attachments
basic patch (820 bytes, patch)
2012-04-19 12:14 UTC, Marc Glisse
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Eric Niebler 2012-04-18 22:08:34 UTC
In my understanding of the new C++ standard, the following code should compile. It does not.

  struct D
  {
      D() = default;
      D(D const &) = default;
      template<typename ...U>
      constexpr D(U ...u)
      {}
  };
  static_assert(std::is_trivial<D>::value, "here");

The problem is the variadic constexpr constructor. I'm guessing here that the problem is that it could also be used as a default constructor, making the type non-trivial. However, I have explicitly defaulted the default constructor, so the variadic constructr should never be considered for 0 arguments.

I base the above supposition on the fact that if I add a dummy argument to the variadic as below, it works:

  struct D
  {
      D() = default;
      D(D const &) = default;
      template<typename ...U>
      constexpr D(int, U ...u) // dummy arg, not default c'tor, ok.
      {}
  };
  static_assert(std::is_trivial<D>::value, "here");
Comment 1 Marc Glisse 2012-04-19 06:28:57 UTC
(In reply to comment #0)
> In my understanding of the new C++ standard, the following code should compile.
> It does not.
> 
>   struct D
>   {
>       D() = default;
>       D(D const &) = default;
>       template<typename ...U>
>       constexpr D(U ...u)
>       {}
>   };
>   static_assert(std::is_trivial<D>::value, "here");

With the declarations in this order, it seems easy to fix, in grok_special_member_properties, only set TYPE_HAS_COMPLEX_DFLT to 1 if we didn't already have TYPE_HAS_DEFAULT_CONSTRUCTOR (might have hidden issues, but they are not obvious to me).

Now if you put the defaulted constructor after the user-provided variadic one, it becomes much harder, and it looks like we'd have to remember one extra bit of information: the reason why we set TYPE_HAS_COMPLEX_DFLT.
Comment 2 Marc Glisse 2012-04-19 12:14:04 UTC
Created attachment 27189 [details]
basic patch

The patch detects D as trivial.

Sadly, on this case:
struct A {
  A()=default;
  A(int=2);
};
it says A is trivial whereas I guess the ambiguity makes it non-trivial. That could be solved for the traits by combining it with is_default_constructible, but it may be problematic to let g++ internally believe that the class is trivially default constructible. For some strange reason, in the case of an ellipsis:
struct A {
  A()=default;
  A(...);
};
it does say: non-trivial.

Maybe the whole dance should only be done if the constructor argument is a parameter pack (one that belongs to the function? or several packs?).
Comment 3 Daniel Krügler 2012-04-19 12:24:12 UTC
(In reply to comment #2)
> Sadly, on this case:
> struct A {
>   A()=default;
>   A(int=2);
> };
> it says A is trivial whereas I guess the ambiguity makes it non-trivial.

I agree. This is correct assuming

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1363

becomes accepted (There is little doubt for that, though).
Comment 4 Paolo Carlini 2012-04-19 12:32:57 UTC
Maybe we should be sending patches to the mailing list... But let's add Jason in CC.
Comment 5 Paolo Carlini 2015-03-24 20:33:54 UTC
We are still missing the implementation of DR1363 (CD3)
Comment 6 Martin Sebor 2019-02-11 18:13:29 UTC
This bug has been fixed since GCC 5.  If there are outstanding issues as comment #5 suggests that aren't being tracked by any open bugs let's open new issues for them.  I'm going to resolve this as fixed.

r215771 | jason | 2014-10-01 13:21:01 -0400 (Wed, 01 Oct 2014) | 11 lines

	PR c++/63362
	* class.c (type_has_non_user_provided_default_constructor): Rename
	from type_has_user_provided_default_constructor, reverse sense.
	(default_init_uninitialized_part, explain_non_literal_class): Adjust.
	(check_bases_and_members): Set TYPE_HAS_COMPLEX_DFLT.
	* call.c (build_new_method_call_1): Adjust.
	* cp-tree.h: Adjust.
	* decl.c (grok_special_member_properties): Don't set
	TYPE_HAS_COMPLEX_DFLT.
	* init.c (build_value_init_noctor): Don't use
	type_has_user_provided_default_constructor.
Comment 7 Jonathan Wakely 2019-02-11 20:53:27 UTC
Bug 85723 deals with the problem mentioned in comment 5.