From 644d195145f7e535d426494e1f6a8a68aa0cb7a8 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 28 Jun 2004 11:07:23 +0000 Subject: [PATCH] re PR c++/16174 (deducing top-level consts) cp: PR C++/16174 * call.c (build_temp): Declare. (check_constructor_callable): New. (reference_binding): Only set CHECK_COPY_CONSTRUCTOR if not for CONSTRUCTOR_CALLABLE. (convert_like_real, initialize_reference): Use check_constructor_callable. * cp-tree.h (LOOKUP_CONSTRUCTOR_CALLABLE): New. (LOOKUP_*): Renumber. testsuite: * PR C++/16174 * g++.dg/template/ctor4.C: New. From-SVN: r83775 --- gcc/cp/ChangeLog | 10 ++++++ gcc/cp/call.c | 45 ++++++++++++++------------- gcc/cp/cp-tree.h | 27 ++++++++-------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/template/ctor4.C | 39 +++++++++++++++++++++++ 5 files changed, 91 insertions(+), 35 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/ctor4.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 500567b8896..74d845710ac 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,15 @@ 2004-06-28 Nathan Sidwell + PR C++/16174 + * call.c (build_temp): Declare. + (check_constructor_callable): New. + (reference_binding): Only set CHECK_COPY_CONSTRUCTOR if not for + CONSTRUCTOR_CALLABLE. + (convert_like_real, initialize_reference): Use + check_constructor_callable. + * cp-tree.h (LOOKUP_CONSTRUCTOR_CALLABLE): New. + (LOOKUP_*): Renumber. + * friend.c (add_friend): Only perform access checks when context is a class. * lex.c (cxx_make_type): Only create a binfo for aggregate types. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 5cbf808d8ec..207d7585f88 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -188,6 +188,8 @@ static void add_candidates (tree, tree, tree, bool, tree, tree, int, struct z_candidate **); static conversion *merge_conversion_sequences (conversion *, conversion *); static bool magic_varargs_p (tree); +static tree build_temp (tree, tree, int, void (**)(const char *, ...)); +static void check_constructor_callable (tree, tree); tree build_vfield_ref (tree datum, tree type) @@ -1190,7 +1192,8 @@ reference_binding (tree rto, tree rfrom, tree expr, int flags) { conv = build_identity_conv (from, expr); conv = direct_reference_binding (rto, conv); - conv->u.next->check_copy_constructor_p = true; + if (!(flags & LOOKUP_CONSTRUCTOR_CALLABLE)) + conv->u.next->check_copy_constructor_p = true; return conv; } @@ -4063,6 +4066,20 @@ enforce_access (tree basetype_path, tree decl) return true; } +/* Check that a callable constructor to initialize a temporary of + TYPE from an EXPR exists. */ + +static void +check_constructor_callable (tree type, tree expr) +{ + build_special_member_call (NULL_TREE, + complete_ctor_identifier, + build_tree_list (NULL_TREE, expr), + TYPE_BINFO (type), + LOOKUP_NORMAL | LOOKUP_ONLYCONVERTING + | LOOKUP_CONSTRUCTOR_CALLABLE); +} + /* Initialize a temporary of type TYPE with EXPR. The FLAGS are a bitwise or of LOOKUP_* values. If any errors are warnings are generated, set *DIAGNOSTIC_FN to "error" or "warning", @@ -4074,9 +4091,9 @@ build_temp (tree expr, tree type, int flags, void (**diagnostic_fn)(const char *, ...)) { int savew, savee; - + savew = warningcount, savee = errorcount; - expr = build_special_member_call (NULL_TREE, + expr = build_special_member_call (NULL_TREE, complete_ctor_identifier, build_tree_list (NULL_TREE, expr), TYPE_BINFO (type), @@ -4209,12 +4226,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, && TREE_CODE (TREE_TYPE (expr)) != ARRAY_TYPE) expr = decl_constant_value (expr); if (convs->check_copy_constructor_p) - /* Generate a temporary copy purely to generate the required - diagnostics. */ - build_temp - (build_dummy_object - (build_qualified_type (totype, TYPE_QUAL_CONST)), - totype, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING, &diagnostic_fn); + check_constructor_callable (totype, expr); return expr; case ck_ambig: /* Call build_user_type_conversion again for the error. */ @@ -4243,12 +4255,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, /* We are going to bind a reference directly to a base-class subobject of EXPR. */ if (convs->check_copy_constructor_p) - /* Generate a temporary copy purely to generate the required - diagnostics. */ - build_temp (build_dummy_object (TREE_TYPE (expr)), - TREE_TYPE (expr), - LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING, - &diagnostic_fn); + check_constructor_callable (TREE_TYPE (expr), expr); /* Build an expression for `*((base*) &expr)'. */ expr = build_unary_op (ADDR_EXPR, expr, 0); expr = perform_implicit_conversion (build_pointer_type (totype), @@ -6426,14 +6433,8 @@ initialize_reference (tree type, tree expr, tree decl, tree *cleanup) remember that the conversion was required. */ if (conv->kind == ck_base && conv->need_temporary_p) { - void (*diagnostic_fn) (const char *, ...); if (conv->check_copy_constructor_p) - /* Generate a temporary copy purely to generate the required - diagnostics. */ - build_temp (build_dummy_object (TREE_TYPE (expr)), - TREE_TYPE (expr), - LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING, - &diagnostic_fn); + check_constructor_callable (TREE_TYPE (expr), expr); base_conv_type = conv->type; conv = conv->u.next; } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c2a943e9066..23e660e0a4d 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3330,19 +3330,20 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG }; LOOKUP_PREFER_NAMESPACES means not to accept objects, and possibly types. LOOKUP_PREFER_BOTH means class-or-namespace-name. */ -#define LOOKUP_PROTECT (1) -#define LOOKUP_COMPLAIN (2) -#define LOOKUP_NORMAL (3) -#define LOOKUP_NONVIRTUAL (8) -#define LOOKUP_GLOBAL (16) -#define LOOKUP_ONLYCONVERTING (128) -#define DIRECT_BIND (256) -#define LOOKUP_NO_CONVERSION (512) -#define LOOKUP_DESTRUCTOR (512) -#define LOOKUP_NO_TEMP_BIND (1024) -#define LOOKUP_PREFER_TYPES (2048) -#define LOOKUP_PREFER_NAMESPACES (4096) -#define LOOKUP_PREFER_BOTH (6144) +#define LOOKUP_PROTECT (1 << 0) +#define LOOKUP_COMPLAIN (1 << 1) +#define LOOKUP_NORMAL (LOOKUP_PROTECT | LOOKUP_COMPLAIN) +#define LOOKUP_NONVIRTUAL (1 << 2) +#define LOOKUP_GLOBAL (1 << 3) +#define LOOKUP_ONLYCONVERTING (1 << 4) +#define DIRECT_BIND (1 << 5) +#define LOOKUP_NO_CONVERSION (1 << 6) +#define LOOKUP_DESTRUCTOR (1 << 7) +#define LOOKUP_NO_TEMP_BIND (1 << 8) +#define LOOKUP_PREFER_TYPES (1 << 9) +#define LOOKUP_PREFER_NAMESPACES (1 << 10) +#define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES) +#define LOOKUP_CONSTRUCTOR_CALLABLE (1 << 11) #define LOOKUP_NAMESPACES_ONLY(F) \ (((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e655ebf4214..2f8653e1009 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-06-28 Nathan Sidwell + + * PR C++/16174 + * g++.dg/template/ctor4.C: New. + 2004-06-27 Andrew Pinski PR c++/16205 diff --git a/gcc/testsuite/g++.dg/template/ctor4.C b/gcc/testsuite/g++.dg/template/ctor4.C new file mode 100644 index 00000000000..18ed628ee9b --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ctor4.C @@ -0,0 +1,39 @@ +// { dg-do compile } + +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 24 Jun 2004 + +// Origin Rani Sharoni via giovannibajo@libero.it +// Bug 16174, SFINAE failure. + +template struct K +{ + K(); + + K(K & rhs); + K(K const& rhs); + template K(K const& rhs); + +private: + template struct A; + template struct A< K const> + { typedef typename K::compile_time_error type; }; + + // This is used to reject calls to the copy constructor + // with objects which are top-level const. If they are + // const, the specialization of A is instantiated and + // causes a compile time error. Otherwise, the general + // template is picked up, it misses definition, so this + // ctor declaration is rejected by SFINAE and everybody + // is happy. + // GCC 3.4.1pre and 3.5.0 always matches A's specialization + // when instantiating from foo(), and this causes the error. + template + K(U& rhs, typename A::type = 0); +}; + + +K foo(void) +{ + return K(); +} -- 2.30.2