const int len = TREE_VEC_LENGTH (from);
if (CLASS_TYPE_P (to))
{
- if (ABSTRACT_CLASS_TYPE_P (to))
+ if (abstract_virtuals_error (NULL_TREE, to, complain))
return error_mark_node;
tree ctype = to;
vec<tree, va_gc> *args = NULL;
"class type %qT", type);
break;
default:
- error ("cannot allocate an object of abstract type %qT", type);
+ error ("cannot construct an object of abstract type %qT", type);
}
/* Only go through this once. */
tree fn;
inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
- " because the following virtual functions are pure within %qT:",
+ "because the following virtual functions are pure within %qT:",
type);
+ auto_diagnostic_nesting_level adnl;
FOR_EACH_VEC_ELT (*pure, ix, fn)
if (! DECL_CLONED_FUNCTION_P (fn)
|| DECL_COMPLETE_DESTRUCTOR_P (fn))
- inform (DECL_SOURCE_LOCATION (fn), " %#qD", fn);
+ inform (DECL_SOURCE_LOCATION (fn), "%#qD", fn);
/* Now truncate the vector. This leaves it non-null, so we know
there are pure virtuals, but empty so we don't list them out
// { dg-message "'A' is not constructible from 'int, int', because" "" { target *-*-* } .-1 }
// { dg-error "no matching function for call to" "" { target *-*-* } .-2 }
+struct V { // { dg-message "following virtual functions are pure" }
+ virtual void foo() = 0; // { dg-message "" }
+};
+static_assert(is_constructible<V>::value, ""); // { dg-error "assert" }
+// { dg-error "object of abstract type" "" { target *-*-* } .-1 }
+
template <typename T, typename... Args>
struct is_nothrow_constructible {
static constexpr bool value = __is_nothrow_constructible(T, Args...);