http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51424

Paolo Carlini <paolo.carlini at oracle dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |ASSIGNED
   Last reconfirmed|                            |2013-08-29
           Assignee|unassigned at gcc dot gnu.org      |paolo.carlini at oracle 
dot com
   Target Milestone|---                         |4.9.0
     Ever confirmed|0                           |1

--- Comment #2 from Paolo Carlini <paolo.carlini at oracle dot com> ---
I have a very simple patch which appears to work fine (for the very simple
cases ;) but constexpr constructors, virtual inheritance, etc are included)

Index: init.c
===================================================================
--- init.c    (revision 202070)
+++ init.c    (working copy)
@@ -500,8 +500,9 @@ perform_target_ctor (tree init)
   tree decl = current_class_ref;
   tree type = current_class_type;

-  finish_expr_stmt (build_aggr_init (decl, init, LOOKUP_NORMAL,
-                                     tf_warning_or_error));
+  finish_expr_stmt (build_aggr_init (decl, init,
+                     LOOKUP_NORMAL|LOOKUP_DELEGATING_CONS,
+                     tf_warning_or_error));
   if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
     {
       tree expr = build_delete (type, decl, sfk_complete_destructor,
@@ -1667,6 +1668,13 @@ expand_default_init (tree binfo, tree true_exp, tr
   if (parms != NULL)
     release_tree_vector (parms);

+  if ((complain & tf_error)
+      && (flags & LOOKUP_DELEGATING_CONS)
+      && TREE_CODE (rval) == CALL_EXPR
+      && (DECL_ABSTRACT_ORIGIN (TREE_OPERAND (CALL_EXPR_FN (rval), 0))
+      == current_function_decl))
+    error ("constructor delegates to itself");
+
   if (exp == true_exp && TREE_CODE (rval) == CALL_EXPR)
     {
       tree fn = get_callee_fndecl (rval);
Index: cp-tree.h
===================================================================
--- cp-tree.h    (revision 202070)
+++ cp-tree.h    (working copy)
@@ -4509,6 +4509,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, T
 #define LOOKUP_NO_RVAL_BIND (LOOKUP_EXPLICIT_TMPL_ARGS << 1)
 /* Used by case_conversion to disregard non-integral conversions.  */
 #define LOOKUP_NO_NON_INTEGRAL (LOOKUP_NO_RVAL_BIND << 1)
+/* Used for delegating constructors in order to diagnose self-delegation.  */
+#define LOOKUP_DELEGATING_CONS (LOOKUP_NO_NON_INTEGRAL << 1)

 #define LOOKUP_NAMESPACES_ONLY(F)  \
   (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))

Reply via email to