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
This commit is contained in:
parent
a301e965cc
commit
644d195145
5 changed files with 91 additions and 35 deletions
|
@ -1,5 +1,15 @@
|
|||
2004-06-28 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2004-06-28 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* PR C++/16174
|
||||
* g++.dg/template/ctor4.C: New.
|
||||
|
||||
2004-06-27 Andrew Pinski <pinskia@physics.uc.edu>
|
||||
|
||||
PR c++/16205
|
||||
|
|
39
gcc/testsuite/g++.dg/template/ctor4.C
Normal file
39
gcc/testsuite/g++.dg/template/ctor4.C
Normal file
|
@ -0,0 +1,39 @@
|
|||
// { dg-do compile }
|
||||
|
||||
// Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
// Contributed by Nathan Sidwell 24 Jun 2004 <nathan@codesourcery.com>
|
||||
|
||||
// Origin Rani Sharoni via giovannibajo@libero.it
|
||||
// Bug 16174, SFINAE failure.
|
||||
|
||||
template <class T> struct K
|
||||
{
|
||||
K();
|
||||
|
||||
K(K<T> & rhs);
|
||||
K(K<T> const& rhs);
|
||||
template <class U> K(K<U> const& rhs);
|
||||
|
||||
private:
|
||||
template <class U> struct A;
|
||||
template <class U> struct A< K<U> const>
|
||||
{ typedef typename K<U>::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 <class U>
|
||||
K(U& rhs, typename A<U>::type = 0);
|
||||
};
|
||||
|
||||
|
||||
K<int> foo(void)
|
||||
{
|
||||
return K<int>();
|
||||
}
|
Loading…
Add table
Reference in a new issue