re PR c++/51424 ([C++11] G++ should diagnose self-delegating constructors)
authorPaolo Carlini <paolo.carlini@oracle.com>
Fri, 30 Aug 2013 15:39:01 +0000 (15:39 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Fri, 30 Aug 2013 15:39:01 +0000 (15:39 +0000)
/cp
2013-08-30  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/51424
* cp-tree.h (LOOKUP_DELEGATING_CONS): Add.
* init.c (perform_target_ctor): Use it.
* call.c (build_special_member_call): Diagnose self-delegating
constructors.

/testsuite
2013-08-30  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/51424
* g++.dg/cpp0x/dc8.C: New.
* g++.dg/template/meminit1.C: Adjust.

From-SVN: r202110

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/init.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/dc8.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/meminit1.C

index 1e6d62104f8bcea46cabef69aba242b327e112e7..e52dfa7c2c4ee4683e3d20aa346bced513148b87 100644 (file)
@@ -1,3 +1,11 @@
+2013-08-30  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/51424
+       * cp-tree.h (LOOKUP_DELEGATING_CONS): Add.
+       * init.c (perform_target_ctor): Use it.
+       * call.c (build_special_member_call): Diagnose self-delegating
+       constructors.
+
 2013-08-30  Gabriel Dos Reis  <gdr@integrable-solutions.net>
 
        * cxx-pretty-print.h (cxx_pretty_printer::declaration): Declare as
index f8fab0828132bc680a4c1b5c37cc8b6d9202be59..3ed73b803740ce16990eb3b62a0baaff68cd5709 100644 (file)
@@ -7442,6 +7442,14 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
   if (allocated != NULL)
     release_tree_vector (allocated);
 
+  if ((complain & tf_error)
+      && (flags & LOOKUP_DELEGATING_CONS)
+      && name == complete_ctor_identifier 
+      && TREE_CODE (ret) == CALL_EXPR
+      && (DECL_ABSTRACT_ORIGIN (TREE_OPERAND (CALL_EXPR_FN (ret), 0))
+         == current_function_decl))
+    error ("constructor delegates to itself");
+
   return ret;
 }
 
index 73f6a6ad43b227f66f059256d2aa770bd61ef0ea..3e4f188b93fb3a9d6ea7858cdc1f134936ad6da4 100644 (file)
@@ -4509,6 +4509,8 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
 #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))
index 156b4a1e082762d14b856af29694ea30f07c2b26..f261f99b82b5d3a7edaa9b7429f27263d7aaa7ca 100644 (file)
@@ -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,
index a46bb121a8ec5c0895959f323c74ba6572a35f41..f8a1f4964d24dacb6ab40f26f3122bc94ee340f6 100644 (file)
@@ -1,3 +1,9 @@
+2013-08-30  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/51424
+       * g++.dg/cpp0x/dc8.C: New.
+       * g++.dg/template/meminit1.C: Adjust.
+
 2013-08-30  Teresa Johnson  <tejohnson@google.com>
 
        * gcc.dg/inline-dump.c: Delete inadvertant commit.
diff --git a/gcc/testsuite/g++.dg/cpp0x/dc8.C b/gcc/testsuite/g++.dg/cpp0x/dc8.C
new file mode 100644 (file)
index 0000000..e483f3e
--- /dev/null
@@ -0,0 +1,66 @@
+// PR c++/51424
+// { dg-do compile { target c++11 } }
+
+template <class T >
+struct S
+{
+  S() : S() {}          // { dg-error "delegates to itself" }
+  S(int x) : S(x) {}    // { dg-error "delegates to itself" }
+};
+
+struct B1
+{
+  B1() : B1() {}        // { dg-error "delegates to itself" }
+  B1(int y) : B1(y) {}  // { dg-error "delegates to itself" }
+};
+
+struct V1 : virtual B1
+{
+  V1() : B1() {}
+  V1(int x) : B1(x) {}
+};
+
+struct B2
+{
+  B2() : B2() {}        // { dg-error "delegates to itself" }
+  B2(int y) : B2(y) {}  // { dg-error "delegates to itself" }
+};
+
+struct V2 : virtual B2
+{
+  V2() : V2() {}        // { dg-error "delegates to itself" }
+  V2(int x) : V2(x) {}  // { dg-error "delegates to itself" }
+};
+
+struct B3
+{
+  B3() {}
+  B3(int y) {}
+};
+
+struct V3 : virtual B3
+{
+  V3() : V3() {}        // { dg-error "delegates to itself" }
+  V3(int x) : V3(x) {}  // { dg-error "delegates to itself" }
+};
+
+struct CE1
+{
+  constexpr CE1() : CE1() {}        // { dg-error "delegates to itself" }
+  constexpr CE1(int x) : CE1(x) {}  // { dg-error "delegates to itself" }
+};
+
+struct CEB2
+{
+  constexpr CEB2() : CEB2() {}        // { dg-error "delegates to itself" }
+  constexpr CEB2(int x) : CEB2(x) {}  // { dg-error "delegates to itself" }
+};
+
+struct CE2 : CEB2
+{
+  constexpr CE2() : CEB2() {}
+  constexpr CE2(int x) : CEB2(x) {}
+};
+
+S<int> s1;
+S<int> s2(1);
index 19a1e546d525a32b548eec7e62d1a7faab1edd7b..1dc96c472ad5810f7ded9816a0542f647f7e9cd1 100644 (file)
@@ -3,6 +3,6 @@ template <class T >
 struct S
 {
   S() : S() {} // { dg-message "delegating constructors" }
-};
+}; // { dg-error "delegates to itself" "" { target *-*-* } 5 }
 
 S<int> s;