2011-04-07 Jason Merrill <jason@redhat.com>
+ PR c++/48449
+ * typeck2.c (build_functional_cast): Check complain consistently.
+ Use build_value_init and abstract_virtuals_error_sfinae.
+ (abstract_virtuals_error_sfinae): Split out.
+ * cp-tree.h: Declare it.
+ * init.c (build_new_1): Use it.
+ (build_value_init_noctor): Handle FUNCTION_TYPE.
+
* semantics.c (finish_decltype_type): Simplify handling of unknown
type.
extern void cxx_readonly_error (tree, enum lvalue_use);
extern void complete_type_check_abstract (tree);
extern int abstract_virtuals_error (tree, tree);
+extern int abstract_virtuals_error_sfinae (tree, tree, tsubst_flags_t);
extern tree store_init_value (tree, tree, int);
extern void check_narrowing (tree, tree);
/* Build a constructor to contain the initializations. */
return build_constructor (type, v);
}
+ else if (TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ if (complain & tf_error)
+ error ("value-initialization of function type %qT", type);
+ return error_mark_node;
+ }
return build_zero_init (type, NULL_TREE, /*static_storage_p=*/false);
}
return error_mark_node;
}
- if (abstract_virtuals_error (NULL_TREE, elt_type))
+ if (abstract_virtuals_error_sfinae (NULL_TREE, elt_type, complain))
return error_mark_node;
is_initialized = (TYPE_NEEDS_CONSTRUCTING (elt_type) || *init != NULL);
occurred; zero if all was well. */
int
-abstract_virtuals_error (tree decl, tree type)
+abstract_virtuals_error_sfinae (tree decl, tree type, tsubst_flags_t complain)
{
VEC(tree,gc) *pure;
if (!pure)
return 0;
+ if (decl && TREE_CODE (decl) == RESULT_DECL)
+ return 0;
+
+ if (!(complain & tf_error))
+ return 1;
+
if (decl)
{
- if (TREE_CODE (decl) == RESULT_DECL)
- return 0;
-
if (TREE_CODE (decl) == VAR_DECL)
error ("cannot declare variable %q+D to be of abstract "
"type %qT", decl, type);
return 1;
}
+/* Wrapper for the above function in the common case of wanting errors. */
+
+int
+abstract_virtuals_error (tree decl, tree type)
+{
+ return abstract_virtuals_error_sfinae (decl, type, tf_warning_or_error);
+}
+
/* Print an error message for invalid use of an incomplete type.
VALUE is the expression that was used (or 0 if that isn't known)
and TYPE is the type that was invalid. DIAG_KIND indicates the
if (TREE_CODE (type) == REFERENCE_TYPE && !parms)
{
- error ("invalid value-initialization of reference type");
+ if (complain & tf_error)
+ error ("invalid value-initialization of reference type");
return error_mark_node;
}
if (! MAYBE_CLASS_TYPE_P (type))
{
if (parms == NULL_TREE)
- return cp_convert (type, integer_zero_node);
+ return build_value_init (type, complain);
/* This must build a C cast. */
parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST, complain);
if (!complete_type_or_maybe_complain (type, NULL_TREE, complain))
return error_mark_node;
- if (abstract_virtuals_error (NULL_TREE, type))
+ if (abstract_virtuals_error_sfinae (NULL_TREE, type, complain))
return error_mark_node;
/* [expr.type.conv]
2011-04-07 Jason Merrill <jason@redhat.com>
+ * g++.dg/cpp0x/sfinae8.C: New.
+
* g++.dg/cpp0x/sfinae7.C: New.
* g++.dg/cpp0x/enum9.C: New.
--- /dev/null
+// PR c++/48449
+// { dg-options -std=c++0x }
+
+template<class T, class = decltype(T())>
+char f(int);
+
+template<class>
+char (&f(...))[2];
+
+struct A { virtual ~A() = 0; };
+
+static_assert(sizeof(f<int&>(0)) != 1, "Error");
+static_assert(sizeof(f<void()>(0)) != 1, "Error");
+static_assert(sizeof(f<A>(0)) != 1, "Error");