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)
{
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;
}
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",
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),
&& 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. */
/* 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),
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;
}
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))
--- /dev/null
+// { 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>();
+}