diff mbox

[C++,Patch/RFC] PR 60047

Message ID 52F0D44C.1010106@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Feb. 4, 2014, 11:51 a.m. UTC
Hi,

thus I tried to have a look to this issue, while experiencing some weird 
problems with the debugger, which slowed me down a lot. I have been able 
to figure out that we don't seem to actively set constexpr_p to true 
anywhere in implicitly_declare_fn (besides the unrelated case of 
inheriting constructors), thus I'm wondering if it would make sense to 
simply do the below?!? (and revert my recent tweak)

Otherwise, Jason, if you suspect something deeper is going on, I would 
rather ask you to take over, today the debugger is still misbehaving on 
me :(

Thanks!
Paolo.

//////////////////////////

Comments

Paolo Carlini Feb. 5, 2014, 4:19 p.m. UTC | #1
Hi,

On 02/04/2014 12:51 PM, Paolo Carlini wrote:
> Hi,
>
> thus I tried to have a look to this issue, while experiencing some 
> weird problems with the debugger, which slowed me down a lot. I have 
> been able to figure out that we don't seem to actively set constexpr_p 
> to true anywhere in implicitly_declare_fn (besides the unrelated case 
> of inheriting constructors), thus I'm wondering if it would make sense 
> to simply do the below?!? (and revert my recent tweak)
I spent a little more time on this. Outside the case of inheriting 
constructors and the special case of expected_trivial default 
constructors (which are handled in a special conditional), we are 
normally assigning true to constexpr_p only in one place, that is close 
to the beginning of synthesized_method_walk:

   /* If that user-written default constructor would satisfy the
      requirements of a constexpr constructor (7.1.5), the
      implicitly-defined default constructor is constexpr.  */
   if (constexpr_p)
     *constexpr_p = ctor_p;

then, for the testcase at issue it becomes false in the place which we 
already discussed for the ICE:

   if (vec_safe_is_empty (vbases))
     /* No virtual bases to worry about.  */;
   else if (!assign_p)
     {
       if (constexpr_p)
     *constexpr_p = false;

Then it doesn't gets a chance to return true. Thus, given the more 
accurate analysis, I think that we either do what I quickly proposed 
yesterday, or alternately, the only option I can see, we change 
process_subob_fn to set it to true in some cases (but I note that it 
does never set to true trivial_p).

Thanks,
Paolo.
Jason Merrill Feb. 5, 2014, 9:28 p.m. UTC | #2
On 02/05/2014 11:19 AM, Paolo Carlini wrote:
>    if (vec_safe_is_empty (vbases))
>      /* No virtual bases to worry about.  */;
>    else if (!assign_p)
>      {
>        if (constexpr_p)
>      *constexpr_p = false;

*constexpr_p should be false for a constructor of a class with virtual 
bases, according to the standard (7.1.5p4):

The definition of a constexpr constructor shall satisfy the following 
constraints:
— the class shall not have any virtual base classes;
...

So the assert in implicit_declare_fn is wrong.  I guess I would fix it 
by checking CLASSTYPE_VBASECLASSES.

Jason
diff mbox

Patch

Index: cp/method.c
===================================================================
--- cp/method.c	(revision 207457)
+++ cp/method.c	(working copy)
@@ -1366,7 +1366,7 @@  synthesized_method_walk (tree ctype, special_funct
     }
 
   vbases = CLASSTYPE_VBASECLASSES (ctype);
-  if (vec_safe_is_empty (vbases))
+  if (vbases == NULL)
     /* No virtual bases to worry about.  */;
   else if (!assign_p)
     {
@@ -1660,7 +1660,7 @@  implicitly_declare_fn (special_function_kind kind,
   else if (trivial_p && cxx_dialect >= cxx11
 	   && (kind == sfk_copy_constructor
 	       || kind == sfk_move_constructor))
-    gcc_assert (constexpr_p);
+    constexpr_p = true;
 
   if (!trivial_p && type_has_trivial_fn (type, kind))
     type_set_nontrivial_flag (type, kind);
Index: testsuite/g++.dg/cpp0x/pr60047.C
===================================================================
--- testsuite/g++.dg/cpp0x/pr60047.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/pr60047.C	(working copy)
@@ -0,0 +1,14 @@ 
+// PR c++/60047
+// { dg-do compile { target c++11 } }
+
+struct B { };
+
+template<typename T> struct A : virtual B
+{
+  A();
+  A(const A&);
+};
+
+template<typename T> A<T>::A(const A<T>&) = default;
+
+A<int> a = A<int>();