From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 6EE2B3858D28 for ; Tue, 12 Apr 2022 18:38:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 6EE2B3858D28 Received: from mail-qv1-f70.google.com (mail-qv1-f70.google.com [209.85.219.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-338-2PqAuc-cNZCE30RbTI5uFw-1; Tue, 12 Apr 2022 14:38:18 -0400 X-MC-Unique: 2PqAuc-cNZCE30RbTI5uFw-1 Received: by mail-qv1-f70.google.com with SMTP id 7-20020a0562140dc700b004442d23d2d8so9716144qvt.2 for ; Tue, 12 Apr 2022 11:38:18 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=K7fjaVLGfSns08kCtVpZQ4C3VYpg1KQ7+Z5+8CpePkA=; b=OQAJNaDB91DFJeOFKzUkhh9xq7AN5gT9sWIVRFtOhenTAFXFNfw8GZCKphXWuukVoq QmsWpDMXqm+V2T14s8D2dsyQ2zi8MS0JdPPGCM7Co6ff6KRgbQlJgh7H1N7FbeI/59WC 7IETmDV4Encdxhs8KR5xZj7tcqgyH0XnvONoFgkUNhzKeJWd3d/8ar8twG/WpYLzRkr1 ch7EPAJf8ZPcmavk1X+ULV3s/YTJ6zNd2Y0I8brrCl4uKVO1i5njmwTFT7C1y9DA76bi 33rUAt50MEQtvXpj4DA9LfTF+13BISSsxwPVGmqVHixemg9BN/j14x7NkaiotgDSaDUp VFew== X-Gm-Message-State: AOAM532R03UqFexQwtES0TvWfcYgCukyggfwQUSw8zpDzRYFi0NZ+zPw uPMEYaot44DIfLoc/uMP7QztPiibd/2VVOuwkguEXDIc4eKa32UO/jmneeWjfeop7qRvajZaEPp EpKtjG6B7Enyc9CyFPw== X-Received: by 2002:a37:a0c3:0:b0:69b:db2c:a857 with SMTP id j186-20020a37a0c3000000b0069bdb2ca857mr4069753qke.325.1649788697151; Tue, 12 Apr 2022 11:38:17 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwlUliiUOv9VRw2eGBCIpYhu0tZxnMiq98WwEyCq/CJWM2tqszmGg+lfZr68VI2hbWrNFwkfw== X-Received: by 2002:a37:a0c3:0:b0:69b:db2c:a857 with SMTP id j186-20020a37a0c3000000b0069bdb2ca857mr4069733qke.325.1649788696780; Tue, 12 Apr 2022 11:38:16 -0700 (PDT) Received: from redhat.com ([2601:184:4780:4310::d1bb]) by smtp.gmail.com with ESMTPSA id c15-20020a05620a164f00b0069c4d8b6335sm472652qko.95.2022.04.12.11.38.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Apr 2022 11:38:16 -0700 (PDT) Date: Tue, 12 Apr 2022 14:38:14 -0400 From: Marek Polacek To: Jason Merrill Cc: Joseph Myers , GCC Patches Subject: Re: [PATCH] c, c++: attribute format on a ctor with a vbase [PR101833, PR47634] Message-ID: References: <20220401191454.464924-1-polacek@redhat.com> MIME-Version: 1.0 In-Reply-To: User-Agent: Mutt/2.1.5 (2021-12-30) X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Spam-Status: No, score=-13.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Apr 2022 18:38:21 -0000 On Mon, Apr 11, 2022 at 04:39:22PM -0400, Jason Merrill wrote: > On 4/8/22 15:21, Marek Polacek wrote: > > On Wed, Apr 06, 2022 at 04:55:54PM -0400, Jason Merrill wrote: > > > On 4/1/22 15:14, Marek Polacek wrote: > > > > Attribute format takes three arguments: archetype, string-index, and > > > > first-to-check. The last two specify the position in the function > > > > parameter list. r63030 clarified that "Since non-static C++ methods have > > > > an implicit this argument, the arguments of such methods should be counted > > > > from two, not one, when giving values for string-index and first-to-check." > > > > Therefore one has to write > > > > > > > > struct D { > > > > D(const char *, ...) __attribute__((format(printf, 2, 3))); > > > > }; > > > > > > > > However -- and this is the problem in this PR -- ctors with virtual > > > > bases also get two additional parameters: the in-charge parameter and > > > > the VTT parameter (added in maybe_retrofit_in_chrg). In fact we'll end up > > > > with two clones of the ctor: an in-charge and a not-in-charge version (see > > > > build_cdtor_clones). That means that the argument position the user > > > > specified in the attribute argument will refer to different arguments, > > > > depending on which constructor we're currently dealing with. This can > > > > cause a range of problems: wrong errors, confusing warnings, or crashes. > > > > > > > > This patch corrects that; for C we don't have to do anything, and in C++ > > > > we can use num_artificial_parms_for. It would be wrong to rewrite the > > > > attributes the user supplied, so I've added an extra parameter called > > > > adjust_pos. > > > > > > > > Attribute format_arg is not affected, because it requires that the > > > > function returns "const char *" which will never be the case for cdtors. > > > > > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? > > > > > > > > PR c++/101833 > > > > PR c++/47634 > > > > > > > > gcc/c-family/ChangeLog: > > > > > > > > * c-attribs.cc (positional_argument): Add new argument adjust_pos, > > > > use it. > > > > * c-common.cc (check_function_arguments): Pass fndecl to > > > > check_function_format. > > > > * c-common.h (check_function_format): Adjust declaration. > > > > (maybe_adjust_arg_pos_for_attribute): Add. > > > > (positional_argument): Adjust declaration. > > > > * c-format.cc (decode_format_attr): Add fndecl argument. Pass it to > > > > maybe_adjust_arg_pos_for_attribute. Adjust calls to get_constant. > > > > > > I wonder about, instead of adding another parameter, allowing the current > > > fntype parameter to be the fndecl when we have one. > > > > > > And then that gets passed down into positional_argument, so we can call > > > maybe_adjust_arg_pos_for_attribute there, and adjust the return value > > > appropriately so we don't need the extra adjustment in get_constant? > > > > Unfortunately I can't do that. positional_argument can't return the > > adjusted position, because get_constant returns it and in decode_format_attr > > it's used to rewrite the arguments in the attribute list: > > > > tree *format_num_expr = &TREE_VALUE (TREE_CHAIN (args)); > > tree *first_arg_num_expr = &TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args))); > > ... > > if (tree val = get_constant (fntype, atname, *format_num_expr, > > 2, &info->format_num, 0, validated_p, > > adjust_pos)) > > *format_num_expr = val; > > Could we not do that? Currently isn't it just overwriting the value with > the same value after default_conversion? I think it is. > Maybe do that conversion directly in decode_format_attr instead? I'm afraid I can't move the default_conversion call out of positional_argument because positional_argument is called from a lot of handle_*_attribute functions, and each of those would have to call default_conversion, which we don't want to do. (Failure to call default_conversion would break e.g. g++.dg/cpp0x/constexpr-attribute2.C.) > > Replacing the arguments in the attribute list would lead to problems, because > > when we're processing the constructor clone without the additional parameters, > > the adjusted argument position would be out of whack at this point. > > > > I've attempted to reduce the number of parameters, but it hardly seemed like > > a win, here's the patch I came up with: > > > > diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc > > index 6e17847ec9e..972476fbdf4 100644 > > --- a/gcc/c-family/c-attribs.cc > > +++ b/gcc/c-family/c-attribs.cc > > @@ -594,7 +594,7 @@ attribute_takes_identifier_p (const_tree attr_id) > > } > > /* Verify that argument value POS at position ARGNO to attribute NAME > > - applied to function TYPE refers to a function parameter at position > > + applied to function FNTYPE refers to a function parameter at position > > POS and the expected type CODE. Treat CODE == INTEGER_TYPE as > > matching all C integral types except bool. If successful, return > > POS after default conversions, if any. Otherwise, issue appropriate > > diff --git a/gcc/c-family/c-common.cc b/gcc/c-family/c-common.cc > > index 6f08b55d4a7..ffa36673ec0 100644 > > --- a/gcc/c-family/c-common.cc > > +++ b/gcc/c-family/c-common.cc > > @@ -6069,7 +6069,7 @@ check_function_arguments (location_t loc, const_tree fndecl, const_tree fntype, > > /* Check for errors in format strings. */ > > if (warn_format || warn_suggest_attribute_format) > > - check_function_format (fntype, fndecl, TYPE_ATTRIBUTES (fntype), nargs, > > + check_function_format (fndecl, TYPE_ATTRIBUTES (fntype), nargs, > > argarray, arglocs); > > if (warn_format) > > diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h > > index db6ff07db37..b68dc8f7d69 100644 > > --- a/gcc/c-family/c-common.h > > +++ b/gcc/c-family/c-common.h > > @@ -857,7 +857,7 @@ extern void check_function_arguments_recurse (void (*) > > opt_code); > > extern bool check_builtin_function_arguments (location_t, vec, > > tree, tree, int, tree *); > > -extern void check_function_format (const_tree, const_tree, tree, int, tree *, > > +extern void check_function_format (const_tree, tree, int, tree *, > > vec *); > > extern bool attribute_fallthrough_p (tree); > > extern tree handle_format_attribute (tree *, tree, tree, int, bool *); > > diff --git a/gcc/c-family/c-format.cc b/gcc/c-family/c-format.cc > > index 87ae7bb73b0..6f0199dfcff 100644 > > --- a/gcc/c-family/c-format.cc > > +++ b/gcc/c-family/c-format.cc > > @@ -70,7 +70,7 @@ static GTY(()) tree local_gimple_ptr_node; > > static GTY(()) tree local_cgraph_node_ptr_node; > > static GTY(()) tree locus; > > -static bool decode_format_attr (const_tree, const_tree, tree, tree, > > +static bool decode_format_attr (const_tree, tree, tree, > > function_format_info *, bool); > > static format_type decode_format_type (const char *, bool * = NULL); > > @@ -330,17 +330,19 @@ get_constant (const_tree fntype, const_tree atname, tree expr, int argno, > > return NULL_TREE; > > } > > -/* Decode the arguments to a "format" attribute into a > > - function_format_info structure. It is already known that the list > > - is of the right length. If VALIDATED_P is true, then these > > - attributes have already been validated and must not be erroneous; > > - if false, it will give an error message. Returns true if the > > - attributes are successfully decoded, false otherwise. */ > > +/* Decode the arguments to a "format" attribute into a function_format_info > > + structure. It is already known that the list is of the right length. If > > + VALIDATED_P is true, then these attributes have already been validated and > > + must not be erroneous; if false, it will give an error message. FN is > > + either a FUNCTION_TYPE or a FUNCTION_DECL. Returns true if the attributes > > + are successfully decoded, false otherwise. */ > > static bool > > -decode_format_attr (const_tree fntype, const_tree fndecl, tree atname, > > - tree args, function_format_info *info, bool validated_p) > > +decode_format_attr (const_tree fn, tree atname, tree args, > > + function_format_info *info, bool validated_p) > > { > > + const_tree fndecl = TYPE_P (fn) ? NULL_TREE : fn; > > + const_tree fntype = TYPE_P (fn) ? fn : TREE_TYPE (fn); > > tree format_type_id = TREE_VALUE (args); > > /* Note that TREE_VALUE (args) is changed in place below. Ditto > > for the value of the next element on the list. */ > > @@ -1170,7 +1172,7 @@ decode_format_type (const char *s, bool *is_raw /* = NULL */) > > attribute themselves. */ > > void > > -check_function_format (const_tree fntype, const_tree fndecl, tree attrs, > > +check_function_format (const_tree fndecl, tree attrs, > > int nargs, tree *argarray, vec *arglocs) > > { > > tree a; > > @@ -1184,7 +1186,7 @@ check_function_format (const_tree fntype, const_tree fndecl, tree attrs, > > { > > /* Yup; check it. */ > > function_format_info info; > > - decode_format_attr (fntype, fndecl, atname, TREE_VALUE (a), &info, > > + decode_format_attr (fndecl, atname, TREE_VALUE (a), &info, > > /*validated=*/true); > > if (warn_format) > > { > > @@ -5190,7 +5192,7 @@ handle_format_attribute (tree node[3], tree atname, tree args, > > if (TREE_CODE (TREE_VALUE (args)) == IDENTIFIER_NODE) > > TREE_VALUE (args) = canonicalize_attr_name (TREE_VALUE (args)); > > - if (!decode_format_attr (type, fndecl, atname, args, &info, > > + if (!decode_format_attr (fndecl ? fndecl : type, atname, args, &info, > > /* validated_p = */false)) > > { > > *no_add_attrs = true; > > Marek