re PR c++/51424 ([C++11] G++ should diagnose self-delegating constructors)
/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
This commit is contained in:
parent
8f0e4d72f2
commit
a624d5fe08
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue