aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2004-06-28 11:07:23 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2004-06-28 11:07:23 +0000
commit644d195145f7e535d426494e1f6a8a68aa0cb7a8 (patch)
tree394b2c49cada83d43d85f498c43b298287f0e424 /gcc
parenta301e965cca8ec15a361fc5e3dd6886b9161a20c (diff)
downloadgcc-644d195145f7e535d426494e1f6a8a68aa0cb7a8.zip
gcc-644d195145f7e535d426494e1f6a8a68aa0cb7a8.tar.gz
gcc-644d195145f7e535d426494e1f6a8a68aa0cb7a8.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/call.c45
-rw-r--r--gcc/cp/cp-tree.h27
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/template/ctor4.C39
5 files changed, 91 insertions, 35 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 500567b..74d8457 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 5cbf808..207d758 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 c2a943e..23e660e 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 e655ebf..2f8653e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/template/ctor4.C b/gcc/testsuite/g++.dg/template/ctor4.C
new file mode 100644
index 0000000..18ed628
--- /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 <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>();
+}