From patchwork Fri Jun 30 13:20:40 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 782860 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wzcbr14NRz9sNc for ; Fri, 30 Jun 2017 23:20:55 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="YTssWMrG"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=LObFH7tqrKs+kkfhJX0l6tiimknI5AoJg7w/BKfevzQwIVk5ns vSVUSAWeUIuunZuXrIhyWG/qM6r65ZSw/D4rXAR3BbwxscbQcP/2eglhuVWLyJ+d 3rsg1vjBwMehD1vlALowMl84rjNSAQFWFnw0dsk5PcVwWP6Y48Q+Lv0wE= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=jdRuir/TJvQHz2DX41UdxAc80Ew=; b=YTssWMrGCpqR5620bdvr JLNArjTwXUm9XhLZlC/bXEXRef0WPUo+9sueXZPrl83dXzh/3bjaF8k8BjvJgd9h VVIOo5Lr1jMNNFBiWoQJ8HcvgxZ7MnoYr1Te2FALnaowJHGFxv7zllzTG2zMIxpg v3YqnHF19WQMyEXNwwhWfC0= Received: (qmail 126104 invoked by alias); 30 Jun 2017 13:20:47 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 125742 invoked by uid 89); 30 Jun 2017 13:20:46 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, RCVD_IN_SORBS_SPAM, SPF_PASS autolearn=ham version=3.3.2 spammy=90046 X-HELO: mail-yb0-f169.google.com Received: from mail-yb0-f169.google.com (HELO mail-yb0-f169.google.com) (209.85.213.169) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 30 Jun 2017 13:20:44 +0000 Received: by mail-yb0-f169.google.com with SMTP id e201so38124531ybb.1 for ; Fri, 30 Jun 2017 06:20:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:from:subject:message-id:date :user-agent:mime-version:content-language; bh=T1itiEq3pm3X9RAWgHFO5j6KK5Unz1HVl8/Dzu3ZVK4=; b=IzF8eeTcykg4tD+fU1RyMdytbHC8S00Q+cIsdaqJmB8KCD5qI2pOns8C5Uaup2qTdH Y58UxYcazJbaZ3SsllJslypjitFQodw8xGIsmfil8/fHWo4hIa56idrvd9AV5PeLDACK KSpvII65iEXOqFs/N+nb3tJyq/BcmBuUxa5KspZMiRcCCJBwCeyl3zqKnAPBaxZS20nT CyH/03gYDVV22OEaza6FfqTk1k6X1YkQtAoHRhEWxCVH9GFFizm8bg0XWCbABroH4QtX K/vkYjuHiJECh8SGS7+yt6aKS1hd/Z48N9UeFJTVnuJd1jppX2HEh8ZQ9fsKGTv/4EGP yWSw== X-Gm-Message-State: AKS2vOw8f6kVN0aO2/5klL1k+0HmsCiLdaMo694g4MReUIlQC1pUUaDD R0Exf2+nS0ggaw== X-Received: by 10.37.161.227 with SMTP id a90mr15515193ybi.128.1498828842743; Fri, 30 Jun 2017 06:20:42 -0700 (PDT) Received: from ?IPv6:2620:10d:c0a3:20fb:7500:e7fb:4a6f:2254? ([2620:10d:c091:200::1:9018]) by smtp.googlemail.com with ESMTPSA id l14sm3333010ywl.7.2017.06.30.06.20.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 30 Jun 2017 06:20:42 -0700 (PDT) To: GCC Patches From: Nathan Sidwell Subject: [C++ PATCH] cdtor naming Message-ID: <2cb4fef2-452a-276d-110d-2eedfeb674d3@acm.org> Date: Fri, 30 Jun 2017 09:20:40 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.2.0 MIME-Version: 1.0 This patch changes the way we name cdtors internally. Currently both in-charge ctor and dtor get the DECL_NAME naming the class they are a member of. That's the same DECL_NAME as the class's self-reference TYPE_DECL. (The specialized base/complete/deleting cdtors get special names already.) Not only is this confusing when looking inside the compiler, but we end up having to frob the name in a few places when trying to do lookups. We already check for cdtorness when emitting a user-readable name (except in one place, which this patch addresses). This patch changes things so that ctors use ctor_identifer and dtors use dtor_identifier. This makes it clearer when debugging the compiler and avoids the need to frob the name. We do now have two ways to check cdtorness -- look at the DECL_CONSTRUCTOR_P of the DECL, or look at the IDENTIFIER_CTOR_P flag of the IDENTIFIER. The former is used by the language-agnostic middle-end, and the latter is used by the C++ FE to determine if we lazily need to synthesize things. It doesn't seem useful, (at the moment), to just have one mechanism. The testcase change is in the introspection plugin, where the plugin prints the raw name. It now sees the special name, rather than the class name (which was only 'right' for the ctor anyway). This seems better to me. nathan 2017-06-30 Nathan Sidwell * call.c (build_new_method_call_1): Use constructo_name to get ctor name. Move argument processing earlier to merge cdtor handling blocks. * decl.c (grokfndecl): Cdtors have special names. * method.c (implicitly_declare_fn): Likewise. Simplify flag setting. * pt.c (check_explicit_specialization): Cdtor name is already special. * search.c (class_method_index_for_fn): Likewise. * g++.dg/plugin/decl-plugin-test.C: Expect special ctor name. Index: cp/call.c =================================================================== --- cp/call.c (revision 249835) +++ cp/call.c (working copy) @@ -8994,6 +8994,7 @@ build_new_method_call_1 (tree instance, if (! (complain & tf_error)) return error_mark_node; + name = constructor_name (basetype); if (permerror (input_location, "cannot call constructor %<%T::%D%> directly", basetype, name)) @@ -9004,6 +9005,19 @@ build_new_method_call_1 (tree instance, return call; } + /* Process the argument list. */ + if (args != NULL && *args != NULL) + { + *args = resolve_args (*args, complain); + if (*args == NULL) + return error_mark_node; + } + + /* Consider the object argument to be used even if we end up selecting a + static member function. */ + instance = mark_type_use (instance); + + /* Figure out whether to skip the first argument for the error message we will display to users if an error occurs. We don't want to display any compiler-generated arguments. The "this" @@ -9013,35 +9027,18 @@ build_new_method_call_1 (tree instance, skip_first_for_error = false; if (IDENTIFIER_CDTOR_P (name)) { - /* Callers should explicitly indicate whether they want to construct + /* Callers should explicitly indicate whether they want to ctor the complete object or just the part without virtual bases. */ gcc_assert (name != ctor_identifier); - /* Similarly for destructors. */ - gcc_assert (name != dtor_identifier); + /* Remove the VTT pointer, if present. */ if ((name == base_ctor_identifier || name == base_dtor_identifier) && CLASSTYPE_VBASECLASSES (basetype)) skip_first_for_error = true; - } - - /* Process the argument list. */ - if (args != NULL && *args != NULL) - { - *args = resolve_args (*args, complain); - if (*args == NULL) - return error_mark_node; - } - /* Consider the object argument to be used even if we end up selecting a - static member function. */ - instance = mark_type_use (instance); - - /* It's OK to call destructors and constructors on cv-qualified objects. - Therefore, convert the INSTANCE to the unqualified type, if - necessary. */ - if (DECL_DESTRUCTOR_P (fn) - || DECL_CONSTRUCTOR_P (fn)) - { + /* It's OK to call destructors and constructors on cv-qualified + objects. Therefore, convert the INSTANCE to the unqualified + type, if necessary. */ if (!same_type_p (basetype, TREE_TYPE (instance))) { instance = build_this (instance); @@ -9049,8 +9046,8 @@ build_new_method_call_1 (tree instance, instance = build_fold_indirect_ref (instance); } } - if (DECL_DESTRUCTOR_P (fn)) - name = complete_dtor_identifier; + else + gcc_assert (!DECL_DESTRUCTOR_P (fn) && !DECL_CONSTRUCTOR_P (fn)); /* For the overload resolution we need to find the actual `this` that would be captured if the call turns out to be to a Index: cp/decl.c =================================================================== --- cp/decl.c (revision 249835) +++ cp/decl.c (working copy) @@ -8518,9 +8518,11 @@ grokfndecl (tree ctype, case sfk_copy_constructor: case sfk_move_constructor: DECL_CONSTRUCTOR_P (decl) = 1; + DECL_NAME (decl) = ctor_identifier; break; case sfk_destructor: DECL_DESTRUCTOR_P (decl) = 1; + DECL_NAME (decl) = dtor_identifier; break; default: break; Index: cp/method.c =================================================================== --- cp/method.c (revision 249835) +++ cp/method.c (working copy) @@ -1968,12 +1968,12 @@ implicitly_declare_fn (special_function_ { case sfk_destructor: /* Destructor. */ - name = constructor_name (type); + name = dtor_identifier; break; case sfk_constructor: /* Default constructor. */ - name = constructor_name (type); + name = ctor_identifier; break; case sfk_copy_constructor: @@ -1989,7 +1989,7 @@ implicitly_declare_fn (special_function_ name = cp_assignment_operator_id (NOP_EXPR); } else - name = constructor_name (type); + name = ctor_identifier; if (kind == sfk_inheriting_constructor) parameter_types = inherited_parms; @@ -2053,13 +2053,14 @@ implicitly_declare_fn (special_function_ fn = build_lang_decl (FUNCTION_DECL, name, fn_type); if (kind != sfk_inheriting_constructor) DECL_SOURCE_LOCATION (fn) = DECL_SOURCE_LOCATION (TYPE_NAME (type)); - if (kind == sfk_constructor || kind == sfk_copy_constructor - || kind == sfk_move_constructor || kind == sfk_inheriting_constructor) - DECL_CONSTRUCTOR_P (fn) = 1; - else if (kind == sfk_destructor) - DECL_DESTRUCTOR_P (fn) = 1; - else + + if (!IDENTIFIER_CDTOR_P (name)) + /* Assignment operator. */ SET_OVERLOADED_OPERATOR_CODE (fn, NOP_EXPR); + else if (IDENTIFIER_CTOR_P (name)) + DECL_CONSTRUCTOR_P (fn) = true; + else + DECL_DESTRUCTOR_P (fn) = true; SET_DECL_ALIGN (fn, MINIMUM_METHOD_BOUNDARY); Index: cp/pt.c =================================================================== --- cp/pt.c (revision 249835) +++ cp/pt.c (working copy) @@ -2881,9 +2881,8 @@ check_explicit_specialization (tree decl if (constructor_name_p (name, ctype)) { - int is_constructor = DECL_CONSTRUCTOR_P (decl); - - if (is_constructor ? !TYPE_HAS_USER_CONSTRUCTOR (ctype) + if (DECL_CONSTRUCTOR_P (decl) + ? !TYPE_HAS_USER_CONSTRUCTOR (ctype) : !CLASSTYPE_DESTRUCTOR (ctype)) { /* From [temp.expl.spec]: @@ -2898,7 +2897,7 @@ check_explicit_specialization (tree decl return error_mark_node; } - name = is_constructor ? ctor_identifier : dtor_identifier; + name = DECL_NAME (decl); } if (!DECL_CONV_FN_P (decl)) Index: cp/search.c =================================================================== --- cp/search.c (revision 249835) +++ cp/search.c (working copy) @@ -1713,10 +1713,7 @@ class_method_index_for_fn (tree class_ty { gcc_assert (DECL_DECLARES_FUNCTION_P (function)); - return lookup_fnfields_1 (class_type, - DECL_CONSTRUCTOR_P (function) ? ctor_identifier : - DECL_DESTRUCTOR_P (function) ? dtor_identifier : - DECL_NAME (function)); + return lookup_fnfields_1 (class_type, DECL_NAME (function)); } Index: testsuite/g++.dg/plugin/decl-plugin-test.C =================================================================== --- testsuite/g++.dg/plugin/decl-plugin-test.C (revision 249835) +++ testsuite/g++.dg/plugin/decl-plugin-test.C (working copy) @@ -17,7 +17,7 @@ class test_class { int class_field1; // { dg-warning "Decl Field class_field1" } int class_field2; // { dg-warning "Decl Field class_field2" } - test_class() // { dg-warning "Decl Function test_class" } + test_class() // { dg-warning "Decl Function __ct" } : class_field1(0), class_field2(0) {}