{"id":808811,"url":"http://patchwork.ozlabs.org/api/patches/808811/?format=json","web_url":"http://patchwork.ozlabs.org/project/gcc/patch/dfe99a4b-4bbe-4b3c-6839-0b66bc32bb16@acm.org/","project":{"id":17,"url":"http://patchwork.ozlabs.org/api/projects/17/?format=json","name":"GNU Compiler Collection","link_name":"gcc","list_id":"gcc-patches.gcc.gnu.org","list_email":"gcc-patches@gcc.gnu.org","web_url":null,"scm_url":null,"webscm_url":null,"list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<dfe99a4b-4bbe-4b3c-6839-0b66bc32bb16@acm.org>","list_archive_url":null,"date":"2017-09-01T16:38:33","name":"[C++] METHOD_VEC cleanup","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"b1801e13295da7ed5cf2ccf81cf3cd42d772d14b","submitter":{"id":9970,"url":"http://patchwork.ozlabs.org/api/people/9970/?format=json","name":"Nathan Sidwell","email":"nathan@acm.org"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/gcc/patch/dfe99a4b-4bbe-4b3c-6839-0b66bc32bb16@acm.org/mbox/","series":[{"id":1073,"url":"http://patchwork.ozlabs.org/api/series/1073/?format=json","web_url":"http://patchwork.ozlabs.org/project/gcc/list/?series=1073","date":"2017-09-01T16:38:33","name":"[C++] METHOD_VEC cleanup","version":1,"mbox":"http://patchwork.ozlabs.org/series/1073/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/808811/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/808811/checks/","tags":{},"related":[],"headers":{"Return-Path":"<gcc-patches-return-461307-incoming=patchwork.ozlabs.org@gcc.gnu.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":["patchwork-incoming@bilbo.ozlabs.org","mailing list gcc-patches@gcc.gnu.org"],"Authentication-Results":["ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org\n\t(client-ip=209.132.180.131; helo=sourceware.org;\n\tenvelope-from=gcc-patches-return-461307-incoming=patchwork.ozlabs.org@gcc.gnu.org;\n\treceiver=<UNKNOWN>)","ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org\n\theader.b=\"HtGpE5td\"; dkim-atps=neutral","sourceware.org; auth=none"],"Received":["from sourceware.org (server1.sourceware.org [209.132.180.131])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xkQ151JZnz9t2x\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSat,  2 Sep 2017 02:38:47 +1000 (AEST)","(qmail 85456 invoked by alias); 1 Sep 2017 16:38:39 -0000","(qmail 85406 invoked by uid 89); 1 Sep 2017 16:38:39 -0000","from mail-yw0-f178.google.com (HELO mail-yw0-f178.google.com)\n\t(209.85.161.178) by sourceware.org\n\t(qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP;\n\tFri, 01 Sep 2017 16:38:37 +0000","by mail-yw0-f178.google.com with SMTP id t188so3581596ywb.1 for\n\t<gcc-patches@gcc.gnu.org>; Fri, 01 Sep 2017 09:38:37 -0700 (PDT)","from ?IPv6:2620:10d:c0a3:20fb:7500:e7fb:4a6f:2254?\n\t([2620:10d:c091:200::1:d19a]) by smtp.googlemail.com with\n\tESMTPSA id a81sm215530ywc.2.2017.09.01.09.38.34\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256\n\tbits=128/128); Fri, 01 Sep 2017 09:38:34 -0700 (PDT)"],"DomainKey-Signature":"a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id\n\t:list-unsubscribe:list-archive:list-post:list-help:sender:to\n\t:from:subject:message-id:date:mime-version:content-type; q=dns;\n\ts=default; b=TsDjSIvf+qdAA8+bIGVduiJGExK9vsm5MXnJQDERkBlar7V0Q9\n\toBQQhdySJ34hOfjELnIGT4K19NWomB2Z3Pfi4vvMx1YnPwxpZlEFia17pQFhWlca\n\tmIbCw3GqZytms+sCZiYSDfROK+P9TnWsA7tNGXrU87bjQErqcSZ/w79Ak=","DKIM-Signature":"v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id\n\t:list-unsubscribe:list-archive:list-post:list-help:sender:to\n\t:from:subject:message-id:date:mime-version:content-type; s=\n\tdefault; bh=BM+TrATd12c8L0zhpaxnp1fhfjU=; b=HtGpE5td2nlUM4D1Rah7\n\tBf1MjvgVqgSr7BmUWY9B0xkFw9jgUwMQaLCKPYfUUF39liQKEKzv2/ExQR4+6hpA\n\tDHfHWPDfalRiS3dXVUt7ZYKePP0rUmIHeZv54MoWB8hmZeOnQCF9Gb2F0J4ut9w/\n\ttJafgPRRm9kTf83c43A2VkQ=","Mailing-List":"contact gcc-patches-help@gcc.gnu.org; run by ezmlm","Precedence":"bulk","List-Id":"<gcc-patches.gcc.gnu.org>","List-Unsubscribe":"<mailto:gcc-patches-unsubscribe-incoming=patchwork.ozlabs.org@gcc.gnu.org>","List-Archive":"<http://gcc.gnu.org/ml/gcc-patches/>","List-Post":"<mailto:gcc-patches@gcc.gnu.org>","List-Help":"<mailto:gcc-patches-help@gcc.gnu.org>","Sender":"gcc-patches-owner@gcc.gnu.org","X-Virus-Found":"No","X-Spam-SWARE-Status":"No, score=-11.4 required=5.0 tests=BAYES_00,\n\tFREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE,\n\tRCVD_IN_SORBS_SPAM,\n\tSPF_PASS autolearn=ham version=3.3.2 spammy=","X-HELO":"mail-yw0-f178.google.com","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net;\n\ts=20161025;\n\th=x-gm-message-state:sender:to:from:subject:message-id:date\n\t:user-agent:mime-version:content-language;\n\tbh=HJ5UfBVA75Z9gLRkrb7BgX4JWaeCIh/92NxnanBVDMI=;\n\tb=j7rK9db2FDJVov/9jo3btQSacQNDBhuqKayexVuKUpzYRFXv/5kXLoWXJM27oCs8ov\n\tGBDl14tYo+vhKlpN0/s9AMnTWC1cno1Rr10wyQYRBR12JPqf3BGYFDl5bC2IbS/M4z9D\n\tpFIKAN0AvstirMioZIvhGhrYVoKpMKtBpjrvcBQvJo154D4C8vynlRFumpAergstAhMu\n\t9wCuIB2Rr3nm4k/yJIOddHPJdDBaOEoIwGy2M6CjMMYB+fXnCco75WmHLO2Dn1sICuVM\n\tVFVk2PP7FdXiFGFZa0J8gv5WS3kL1QAbbRkYQ4jeL84t7e2NR7i0KuXIWnIn/m/lTcvo\n\tPAVA==","X-Gm-Message-State":"AHPjjUjqwC1OlwpUb6zhfznXovo43hplxNxceYADyA4VfP3H/c/3sH1p\t3wZeETQ268GrKQ==","X-Google-Smtp-Source":"ADKCNb4HQTlCoam5HqSoU3ixl+esGlr+soIBPj4UIbJ70r2aYNVZhad3yt/se9D7ywGQXwd13Cm17A==","X-Received":"by 10.37.162.6 with SMTP id b6mr2234562ybi.139.1504283915353;\n\tFri, 01 Sep 2017 09:38:35 -0700 (PDT)","To":"GCC Patches <gcc-patches@gcc.gnu.org>","From":"Nathan Sidwell <nathan@acm.org>","Subject":"[C++ PATCH] METHOD_VEC cleanup","Message-ID":"<dfe99a4b-4bbe-4b3c-6839-0b66bc32bb16@acm.org>","Date":"Fri, 1 Sep 2017 12:38:33 -0400","User-Agent":"Mozilla/5.0 (X11; Linux x86_64;\n\trv:52.0) Gecko/20100101 Thunderbird/52.2.1","MIME-Version":"1.0","Content-Type":"multipart/mixed;\n\tboundary=\"------------67EBEB0C2EC594EAD9303882\""},"content":"This patch reorganizes the processing of METHOD_VEC during class \ndefinition.  I remove a bunch of places where we check for non-NULL \nMETHOD_VEC -- now there are no magic slots, it doesn't matter if the \nvector is NULL.  Some processing moves out of finish_struct_methods, \nleaving it to just sort the method vector.\n\nWith this change a glaring inconsistency between template and \nnon-template or instantiation class defintions.  The former never calls \nset_class_bindings, so field search will always be the slow TYPE_FIELDS \niteration.  I have a patch for that and I'm curious about whether it'll \nmake a change in practice (if there are fewer than 8 fields, we never \ncreate the FIELD_VEC).\n\napplied to trunk.\n\nnathan","diff":"2017-09-01  Nathan Sidwell  <nathan@acm.org>\n\n\t* class.c (finish_struct_methods): Done clear DECL_IN_AGGR_P here.\n\tDon't call maybe_warn_about_overly_private_class here.\n\t(warn_hidden): Cleanup declarations and comments.\n\t(type_has_user_provided_constructor): No need to check\n\tCLASSTYPE_METHOD_VEC.\n\t(type_has_user_provided_or_explicit_constructor): Likewise.\n\t(classtype_has_move_assign_or_move_ctor_p): Likewise.\n\t(check_bases_and_members): Don't call finish_struct_methods here.\n\t(finish_struct_1): Call finish_struct_methods and\n\tset_class_bindings immediately after layout.  Clear DECL_IN_AGGR_P\n\there.\n\t(finish_struct): For templates process USING_DECLS and clear\n\tDECL_IN_AGGR_P before calling finish_struct_methods. Call\n\tmaybe_warn_about_overly_private_class here.\n\nIndex: class.c\n===================================================================\n--- class.c\t(revision 251592)\n+++ class.c\t(working copy)\n@@ -2313,15 +2313,6 @@ finish_struct_methods (tree t)\n   if (!method_vec)\n     return;\n \n-  /* Clear DECL_IN_AGGR_P for all functions.  */\n-  for (tree fn = TYPE_FIELDS (t); fn; fn = DECL_CHAIN (fn))\n-    if (DECL_DECLARES_FUNCTION_P (fn))\n-      DECL_IN_AGGR_P (fn) = false;\n-\n-  /* Issue warnings about private constructors and such.  If there are\n-     no methods, then some public defaults are generated.  */\n-  maybe_warn_about_overly_private_class (t);\n-\n   qsort (method_vec->address (), method_vec->length (),\n \t sizeof (tree), method_name_cmp);\n }\n@@ -2976,16 +2967,12 @@ warn_hidden (tree t)\n   /* We go through each separately named virtual function.  */\n   for (int i = 0; vec_safe_iterate (method_vec, i, &fns); ++i)\n     {\n-      tree fndecl;\n+      tree name = OVL_NAME (fns);\n+      auto_vec<tree, 20> base_fndecls;\n       tree base_binfo;\n       tree binfo;\n       int j;\n \n-      /* All functions in this slot in the CLASSTYPE_METHOD_VEC will\n-\t have the same name.  Figure out what name that is.  */\n-      tree name = OVL_NAME (fns);\n-      /* There are no possibly hidden functions yet.  */\n-      auto_vec<tree, 20> base_fndecls;\n       /* Iterate through all of the base classes looking for possibly\n \t hidden functions.  */\n       for (binfo = TYPE_BINFO (t), j = 0;\n@@ -3002,14 +2989,14 @@ warn_hidden (tree t)\n       /* Remove any overridden functions.  */\n       for (ovl_iterator iter (fns); iter; ++iter)\n \t{\n-\t  fndecl = *iter;\n+\t  tree fndecl = *iter;\n \t  if (TREE_CODE (fndecl) == FUNCTION_DECL\n \t      && DECL_VINDEX (fndecl))\n \t    {\n-\t\t/* If the method from the base class has the same\n-\t\t   signature as the method from the derived class, it\n-\t\t   has been overridden.  */\n-\t\tfor (size_t k = 0; k < base_fndecls.length (); k++)\n+\t      /* If the method from the base class has the same\n+\t\t signature as the method from the derived class, it\n+\t\t has been overridden.  */\n+\t      for (size_t k = 0; k < base_fndecls.length (); k++)\n \t\tif (base_fndecls[k]\n \t\t    && same_signature_p (fndecl, base_fndecls[k]))\n \t\t  base_fndecls[k] = NULL_TREE;\n@@ -4892,11 +4879,6 @@ adjust_clone_args (tree decl)\n static void\n clone_constructors_and_destructors (tree t)\n {\n-  /* If for some reason we don't have a CLASSTYPE_METHOD_VEC, we bail\n-     out now.  */\n-  if (!CLASSTYPE_METHOD_VEC (t))\n-    return;\n-\n   /* While constructors can be via a using declaration, at this point\n      we no longer need to know that.  */\n   for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)\n@@ -5134,10 +5116,6 @@ type_has_user_provided_constructor (tree\n   if (!TYPE_HAS_USER_CONSTRUCTOR (t))\n     return false;\n \n-  /* This can happen in error cases; avoid crashing.  */\n-  if (!CLASSTYPE_METHOD_VEC (t))\n-    return false;\n-\n   for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)\n     if (user_provided_p (*iter))\n       return true;\n@@ -5156,10 +5134,6 @@ type_has_user_provided_or_explicit_const\n   if (!TYPE_HAS_USER_CONSTRUCTOR (t))\n     return false;\n \n-  /* This can happen in error cases; avoid crashing.  */\n-  if (!CLASSTYPE_METHOD_VEC (t))\n-    return false;\n-\n   for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)\n     {\n       tree fn = *iter;\n@@ -5348,9 +5322,6 @@ classtype_has_move_assign_or_move_ctor_p\n \t      || (!CLASSTYPE_LAZY_MOVE_CTOR (t)\n \t\t  && !CLASSTYPE_LAZY_MOVE_ASSIGN (t)));\n \n-  if (!CLASSTYPE_METHOD_VEC (t))\n-    return false;\n-\n   if (!CLASSTYPE_LAZY_MOVE_CTOR (t))\n     for (ovl_iterator iter (lookup_fnfields_slot_nolazy (t, ctor_identifier));\n \t iter; ++iter)\n@@ -5840,9 +5811,6 @@ check_bases_and_members (tree t)\n   for (; access_decls; access_decls = TREE_CHAIN (access_decls))\n     handle_using_decl (TREE_VALUE (access_decls), t);\n \n-  /* Build and sort the CLASSTYPE_METHOD_VEC.  */\n-  finish_struct_methods (t);\n-\n   /* Figure out whether or not we will need a cookie when dynamically\n      allocating an array of this type.  */\n   LANG_TYPE_CLASS_CHECK (t)->vec_new_uses_cookie\n@@ -6996,6 +6964,11 @@ finish_struct_1 (tree t)\n \n   /* Layout the class itself.  */\n   layout_class_type (t, &virtuals);\n+  /* COMPLETE_TYPE_P is now true.  */\n+\n+  finish_struct_methods (t);\n+  set_class_bindings (t, TYPE_FIELDS (t));\n+\n   if (CLASSTYPE_AS_BASE (t) != t)\n     /* We use the base type for trivial assignments, and hence it\n        needs a mode.  */\n@@ -7060,20 +7033,21 @@ finish_struct_1 (tree t)\n     }\n \n   finish_struct_bits (t);\n+\n   set_method_tm_attributes (t);\n   if (flag_openmp || flag_openmp_simd)\n     finish_omp_declare_simd_methods (t);\n \n-  /* Complete the rtl for any static member objects of the type we're\n-     working on.  */\n+  /* Clear DECL_IN_AGGR_P for all member functions.  Complete the rtl\n+     for any static member objects of the type we're working on.  */\n   for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))\n-    if (VAR_P (x) && TREE_STATIC (x)\n-        && TREE_TYPE (x) != error_mark_node\n-\t&& same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t))\n+    if (DECL_DECLARES_FUNCTION_P (x))\n+      DECL_IN_AGGR_P (x) = false;\n+    else if (VAR_P (x) && TREE_STATIC (x)\n+\t     && TREE_TYPE (x) != error_mark_node\n+\t     && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (x)), t))\n       SET_DECL_MODE (x, TYPE_MODE (t));\n \n-  set_class_bindings (t, TYPE_FIELDS (t));\n-\n   /* Complain if one of the field types requires lower visibility.  */\n   constrain_class_visibility (t);\n \n@@ -7195,9 +7169,25 @@ finish_struct (tree t, tree attributes)\n     {\n       tree x;\n \n-      finish_struct_methods (t);\n+      /* We need to add the target functions of USING_DECLS, so that\n+\t they can be found when the using declaration is not\n+\t instantiated yet.  */\n+      for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))\n+\tif (TREE_CODE (x) == USING_DECL)\n+\t  {\n+\t    tree fn = strip_using_decl (x);\n+  \t    if (OVL_P (fn))\n+\t      for (lkp_iterator iter (fn); iter; ++iter)\n+\t\tadd_method (t, *iter, true);\n+\t  }\n+\telse if (DECL_DECLARES_FUNCTION_P (x))\n+\t  DECL_IN_AGGR_P (x) = false;\n+\n       TYPE_SIZE (t) = bitsize_zero_node;\n       TYPE_SIZE_UNIT (t) = size_zero_node;\n+      /* COMPLETE_TYPE_P is now true.  */\n+\n+      finish_struct_methods (t);\n \n       /* We need to emit an error message if this type was used as a parameter\n \t and it is an abstract type, even if it is a template. We construct\n@@ -7211,18 +7201,6 @@ finish_struct (tree t, tree attributes)\n \tif (TREE_CODE (x) == FUNCTION_DECL && DECL_PURE_VIRTUAL_P (x))\n \t  vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x);\n       complete_vars (t);\n-      /* We need to add the target functions to the CLASSTYPE_METHOD_VEC if\n-\t an enclosing scope is a template class, so that this function be\n-\t found by lookup_fnfields_1 when the using declaration is not\n-\t instantiated yet.  */\n-      for (x = TYPE_FIELDS (t); x; x = DECL_CHAIN (x))\n-\tif (TREE_CODE (x) == USING_DECL)\n-\t  {\n-\t    tree fn = strip_using_decl (x);\n-  \t    if (OVL_P (fn))\n-\t      for (lkp_iterator iter (fn); iter; ++iter)\n-\t\tadd_method (t, *iter, true);\n-\t  }\n \n       /* Remember current #pragma pack value.  */\n       TYPE_PRECISION (t) = maximum_field_alignment;\n@@ -7237,7 +7215,10 @@ finish_struct (tree t, tree attributes)\n     }\n   else\n     finish_struct_1 (t);\n+  /* COMPLETE_TYPE_P is now true.  */\n \n+  maybe_warn_about_overly_private_class (t);\n+  \n   if (is_std_init_list (t))\n     {\n       /* People keep complaining that the compiler crashes on an invalid\n","prefixes":["C++"]}