In an extern "C" region the lambda member fns were getting C linkage.
and triggering an assert I added. I'm not sure why just the generic
case was being triggered, but the fix is to just force the language to
be C++ -- this is what we do in finish_member_declaration.
We were also not copying the linkage into the template header. Mostly
that was ok, because we then ignored it. But sometimes, like this,
things went wrong.
applying to trunk.
nathan
--
Nathan Sidwell
2018-03-19 Nathan Sidwell <nat...@acm.org>
PR c++/84835
* lambda.c (maybe_add_lambda_conv_op): Force C++ linkage.
* pt.c (build_template_decl): Propagate language linkage.
PR c++/84835
* g++.dg/cpp1y/pr84835.C: New.
Index: cp/lambda.c
===================================================================
--- cp/lambda.c (revision 258642)
+++ cp/lambda.c (working copy)
@@ -1176,6 +1176,7 @@ maybe_add_lambda_conv_op (tree type)
tree thistype = cp_build_qualified_type (type, TYPE_QUAL_CONST);
tree fntype = build_method_type_directly (thistype, rettype, void_list_node);
tree convfn = build_lang_decl (FUNCTION_DECL, name, fntype);
+ SET_DECL_LANGUAGE (convfn, lang_cplusplus);
tree fn = convfn;
DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
SET_DECL_ALIGN (fn, MINIMUM_METHOD_BOUNDARY);
@@ -1208,6 +1209,7 @@ maybe_add_lambda_conv_op (tree type)
name = get_identifier ("_FUN");
tree statfn = build_lang_decl (FUNCTION_DECL, name, stattype);
+ SET_DECL_LANGUAGE (statfn, lang_cplusplus);
fn = statfn;
DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (callop);
grokclassfn (type, fn, NO_SPECIAL);
Index: cp/pt.c
===================================================================
--- cp/pt.c (revision 258642)
+++ cp/pt.c (working copy)
@@ -4677,6 +4677,7 @@ tree
build_template_decl (tree decl, tree parms, bool member_template_p)
{
tree tmpl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), NULL_TREE);
+ SET_DECL_LANGUAGE (tmpl, DECL_LANGUAGE (decl));
DECL_TEMPLATE_PARMS (tmpl) = parms;
DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl);
DECL_SOURCE_LOCATION (tmpl) = DECL_SOURCE_LOCATION (decl);
Index: testsuite/g++.dg/cpp1y/pr84835.C
===================================================================
--- testsuite/g++.dg/cpp1y/pr84835.C (revision 0)
+++ testsuite/g++.dg/cpp1y/pr84835.C (working copy)
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++14 } }
+// PR c++/84835
+// ICE with generic lambda inside extern "C"
+
+extern "C"
+{
+ auto r = [] (auto x)
+ {
+ void baz (); // extern "C"
+ baz ();
+ };
+
+}
+
+void g ()
+{
+ r (0);
+}
+
+// { dg-final { scan-assembler "\[^0-9\]baz" } }