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:
Nathan Sidwell 2004-06-28 11:07:23 +00:00 committed by Nathan Sidwell
parent a301e965cc
commit 644d195145
5 changed files with 91 additions and 35 deletions

View file

@ -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.

View file

@ -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;
}

View file

@ -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))

View file

@ -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

View 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>();
}