===================================================================
@@ -5476,6 +5476,7 @@ extern tree get_copy_ctor (tree, tsubst_flags_t)
extern tree get_copy_assign (tree);
extern tree get_default_ctor (tree);
extern tree get_dtor (tree, tsubst_flags_t);
+extern tree get_inherited_ctor (tree);
extern tree locate_ctor (tree);
extern tree implicitly_declare_fn (special_function_kind, tree,
bool, tree, tree);
===================================================================
@@ -971,6 +971,25 @@ get_copy_assign (tree type)
return fn;
}
+/* Locate the inherited constructor of constructor CTOR. */
+
+tree
+get_inherited_ctor (tree ctor)
+{
+ gcc_assert (DECL_INHERITED_CTOR_BASE (ctor));
+
+ push_deferring_access_checks (dk_no_check);
+ tree fn = locate_fn_flags (DECL_INHERITED_CTOR_BASE (ctor),
+ complete_ctor_identifier,
+ FUNCTION_FIRST_USER_PARMTYPE (ctor),
+ LOOKUP_NORMAL|LOOKUP_SPECULATIVE,
+ tf_none);
+ pop_deferring_access_checks ();
+ if (fn == error_mark_node)
+ return NULL_TREE;
+ return fn;
+}
+
/* Subroutine of synthesized_method_walk. Update SPEC_P, TRIVIAL_P and
DELETED_P or give an error message MSG with argument ARG. */
===================================================================
@@ -7438,19 +7438,31 @@ retrieve_constexpr_fundef (tree fun)
static bool
is_valid_constexpr_fn (tree fun, bool complain)
{
- tree parm = FUNCTION_FIRST_USER_PARM (fun);
bool ret = true;
- for (; parm != NULL; parm = TREE_CHAIN (parm))
- if (!literal_type_p (TREE_TYPE (parm)))
- {
- ret = false;
- if (complain)
+
+ if (DECL_INHERITED_CTOR_BASE (fun)
+ && TREE_CODE (fun) == TEMPLATE_DECL)
+ {
+ ret = false;
+ if (complain)
+ error ("inherited constructor %qD is not constexpr",
+ get_inherited_ctor (fun));
+ }
+ else
+ {
+ for (tree parm = FUNCTION_FIRST_USER_PARM (fun);
+ parm != NULL_TREE; parm = TREE_CHAIN (parm))
+ if (!literal_type_p (TREE_TYPE (parm)))
{
- error ("invalid type for parameter %d of constexpr "
- "function %q+#D", DECL_PARM_INDEX (parm), fun);
- explain_non_literal_class (TREE_TYPE (parm));
+ ret = false;
+ if (complain)
+ {
+ error ("invalid type for parameter %d of constexpr "
+ "function %q+#D", DECL_PARM_INDEX (parm), fun);
+ explain_non_literal_class (TREE_TYPE (parm));
+ }
}
- }
+ }
if (!DECL_CONSTRUCTOR_P (fun))
{
===================================================================
@@ -0,0 +1,14 @@
+// PR c++/60389
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+ template<typename...T> A(T...) {}
+};
+
+struct B : A
+{
+ using A::A; // { dg-error "inherited" }
+};
+
+constexpr B b; // { dg-error "literal" }