gcc_assert (COMPLETE_TYPE_P (basetype));
+ if (CLASSTYPE_FINAL (basetype))
+ error ("cannot derive from %<final%> base %qT in derived type %qT",
+ basetype, t);
+
/* If any base class is non-literal, so is the derived class. */
if (!CLASSTYPE_LITERAL_P (basetype))
CLASSTYPE_LITERAL_P (t) = false;
void
check_for_override (tree decl, tree ctype)
{
+ bool overrides_found = false;
if (TREE_CODE (decl) == TEMPLATE_DECL)
/* In [temp.mem] we have:
/* Set DECL_VINDEX to a value that is neither an INTEGER_CST nor
the error_mark_node so that we know it is an overriding
function. */
- DECL_VINDEX (decl) = decl;
+ {
+ DECL_VINDEX (decl) = decl;
+ overrides_found = true;
+ }
if (DECL_VIRTUAL_P (decl))
{
if (DECL_DESTRUCTOR_P (decl))
TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype) = true;
}
- else if (DECL_OVERRIDE_P (decl))
- {
- DECL_VINDEX (decl) = error_mark_node;
- error ("%q+#D marked override, but does not override", decl);
- }
+ else if (DECL_FINAL_P (decl))
+ error ("%q+#D marked final, but is not virtual", decl);
+ if (DECL_OVERRIDE_P (decl) && !overrides_found)
+ error ("%q+#D marked override, but does not override", decl);
}
/* Warn about hidden virtual functions that are not overridden in t.
return false;
}
+/* Nonzero if we need to build up a constructor call when initializing an
+ object of this class, either because it has a user-provided constructor
+ or because it doesn't have a default constructor (so we need to give an
+ error if no initializer is provided). Use TYPE_NEEDS_CONSTRUCTING when
+ what you care about is whether or not an object can be produced by a
+ constructor (e.g. so we don't set TREE_READONLY on const variables of
+ such type); use this function when what you care about is whether or not
+ to try to call a constructor to create an object. The latter case is
+ the former plus some cases of constructors that cannot be called. */
+
+bool
+type_build_ctor_call (tree t)
+{
+ tree inner;
+ if (TYPE_NEEDS_CONSTRUCTING (t))
+ return true;
+ inner = strip_array_types (t);
+ return (CLASS_TYPE_P (inner) && !TYPE_HAS_DEFAULT_CONSTRUCTOR (inner)
+ && !ANON_AGGR_TYPE_P (inner));
+}
+
/* Remove all zero-width bit-fields from T. */
static void
&& !TYPE_HAS_CONSTEXPR_CTOR (t))
CLASSTYPE_LITERAL_P (t) = false;
- for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
- if (DECL_DECLARED_CONSTEXPR_P (fn)
- && TREE_CODE (fn) != TEMPLATE_DECL)
- validate_constexpr_fundecl (fn);
+ if (!CLASSTYPE_LITERAL_P (t))
+ for (fn = TYPE_METHODS (t); fn; fn = DECL_CHAIN (fn))
+ if (DECL_DECLARED_CONSTEXPR_P (fn)
+ && TREE_CODE (fn) != TEMPLATE_DECL
+ && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+ && !DECL_CONSTRUCTOR_P (fn))
+ {
+ DECL_DECLARED_CONSTEXPR_P (fn) = false;
+ if (!DECL_TEMPLATE_INFO (fn))
+ error ("enclosing class of %q+#D is not a literal type", fn);
+ }
}
/* Check the validity of the bases and members declared in T. Add any