From patchwork Fri Oct 7 11:18:52 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 118301 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]) by ozlabs.org (Postfix) with SMTP id 0C713B70FF for ; Fri, 7 Oct 2011 22:20:57 +1100 (EST) Received: (qmail 6279 invoked by alias); 7 Oct 2011 11:20:55 -0000 Received: (qmail 6269 invoked by uid 22791); 7 Oct 2011 11:20:53 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from acsinet15.oracle.com (HELO acsinet15.oracle.com) (141.146.126.227) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 07 Oct 2011 11:20:39 +0000 Received: from ucsinet24.oracle.com (ucsinet24.oracle.com [156.151.31.67]) by acsinet15.oracle.com (Switch-3.4.4/Switch-3.4.4) with ESMTP id p97BKaDv001363 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 7 Oct 2011 11:20:37 GMT Received: from acsmt356.oracle.com (acsmt356.oracle.com [141.146.40.156]) by ucsinet24.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id p97BEi15012441 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 7 Oct 2011 11:14:45 GMT Received: from abhmt111.oracle.com (abhmt111.oracle.com [141.146.116.63]) by acsmt356.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id p97BKTem020183; Fri, 7 Oct 2011 06:20:29 -0500 Received: from [192.168.1.4] (/79.56.218.26) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 07 Oct 2011 04:20:29 -0700 Message-ID: <4E8EE01C.7000500@oracle.com> Date: Fri, 07 Oct 2011 13:18:52 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:7.0) Gecko/20110922 Thunderbird/7.0 MIME-Version: 1.0 To: Jason Merrill CC: "gcc-patches@gcc.gnu.org" Subject: Re: [C++ Patch] PR 38980 References: <4E8C3C26.9030809@oracle.com> <4E8EAFB7.3050003@redhat.com> In-Reply-To: <4E8EAFB7.3050003@redhat.com> X-IsSubscribed: yes 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 Hi, > Instead of adding the parameter, let's have the C++ front end call a > different function that doesn't try to pull out the value from > aggregate variables, like C has decl_constant_value_for_optimization. Ok. The below lives entirely inside the C++ front-end (actually I had already experimented with something similar) Note I'm using the name decl_constant_value_safe, thus I'm not overloading the name decl_constant_value_for_optimization, because the latter is only used by the C front-end but still exported by c-family. I could move back that decl_constant_value_for_optimization currently in c-common.c to the C front-end, but callers, also C front-end only, would remain in c-family. I'd rather not fiddle further with all of that (looks like long term people would like to have more shared code in c-common.c, seems indeed an excellent idea, but at the moment large chunks are actually used by the C front-end only...). Tested x86_64-linux. Paolo. ///////////////////// /cp 2011-10-07 Paolo Carlini PR c++/38980 * init.c (constant_value_1): Add bool parameter. (decl_constant_value_safe): Add. (integral_constant_value): Adjust. (decl_constant_value): Adjust. * cp-tree.h (decl_constant_value_safe): Declare. * typeck.c (decay_conversion): Use decl_constant_value_safe. * call.c (convert_like_real): Likewise. /testsuite 2011-10-07 Paolo Carlini PR c++/38980 * g++.dg/warn/format5.C: New. Index: testsuite/g++.dg/warn/format5.C =================================================================== --- testsuite/g++.dg/warn/format5.C (revision 0) +++ testsuite/g++.dg/warn/format5.C (revision 0) @@ -0,0 +1,12 @@ +// PR c++/38980 +// { dg-options "-Wformat" } + +extern "C" +int printf(const char *format, ...) __attribute__((format(printf, 1, 2) )); + +const char fmt1[] = "Hello, %s"; + +void f() +{ + printf(fmt1, 3); // { dg-warning "expects argument" } +} Index: cp/typeck.c =================================================================== --- cp/typeck.c (revision 179649) +++ cp/typeck.c (working copy) @@ -1827,7 +1827,7 @@ decay_conversion (tree exp) /* FIXME remove? at least need to remember that this isn't really a constant expression if EXP isn't decl_constant_var_p, like with C_MAYBE_CONST_EXPR. */ - exp = decl_constant_value (exp); + exp = decl_constant_value_safe (exp); if (error_operand_p (exp)) return error_mark_node; Index: cp/init.c =================================================================== --- cp/init.c (revision 179649) +++ cp/init.c (working copy) @@ -1794,10 +1794,11 @@ build_offset_ref (tree type, tree member, bool add constant initializer, return the initializer (or, its initializers, recursively); otherwise, return DECL. If INTEGRAL_P, the initializer is only returned if DECL is an integral - constant-expression. */ + constant-expression. If RETURN_AGGREGATE_CST_OK_P, it is ok to + return an aggregate constant. */ static tree -constant_value_1 (tree decl, bool integral_p) +constant_value_1 (tree decl, bool integral_p, bool return_aggregate_cst_ok_p) { while (TREE_CODE (decl) == CONST_DECL || (integral_p @@ -1834,12 +1835,13 @@ static tree if (!init || !TREE_TYPE (init) || !TREE_CONSTANT (init) - || (!integral_p - /* Do not return an aggregate constant (of which - string literals are a special case), as we do not - want to make inadvertent copies of such entities, - and we must be sure that their addresses are the - same everywhere. */ + || (!integral_p && !return_aggregate_cst_ok_p + /* Unless RETURN_AGGREGATE_CST_OK_P is true, do not + return an aggregate constant (of which string + literals are a special case), as we do not want + to make inadvertent copies of such entities, and + we must be sure that their addresses are the + same everywhere. */ && (TREE_CODE (init) == CONSTRUCTOR || TREE_CODE (init) == STRING_CST))) break; @@ -1856,19 +1858,29 @@ static tree tree integral_constant_value (tree decl) { - return constant_value_1 (decl, /*integral_p=*/true); + return constant_value_1 (decl, /*integral_p=*/true, + /*return_aggregate_cst_ok_p=*/false); } /* A more relaxed version of integral_constant_value, used by the - common C/C++ code and by the C++ front end for optimization - purposes. */ + common C/C++ code. */ tree decl_constant_value (tree decl) { - return constant_value_1 (decl, - /*integral_p=*/processing_template_decl); + return constant_value_1 (decl, /*integral_p=*/processing_template_decl, + /*return_aggregate_cst_ok_p=*/true); } + +/* A version of integral_constant_value used by the C++ front end for + optimization purposes. */ + +tree +decl_constant_value_safe (tree decl) +{ + return constant_value_1 (decl, /*integral_p=*/processing_template_decl, + /*return_aggregate_cst_ok_p=*/false); +} /* Common subroutines of build_new and build_vec_delete. */ Index: cp/call.c =================================================================== --- cp/call.c (revision 179649) +++ cp/call.c (working copy) @@ -5703,7 +5703,7 @@ convert_like_real (conversion *convs, tree expr, t leave it as an lvalue. */ if (inner >= 0) { - expr = decl_constant_value (expr); + expr = decl_constant_value_safe (expr); if (expr == null_node && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (totype)) /* If __null has been converted to an integer type, we do not want to warn about uses of EXPR as an integer, rather than Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 179649) +++ cp/cp-tree.h (working copy) @@ -5097,6 +5097,7 @@ extern tree create_temporary_var (tree); extern void initialize_vtbl_ptrs (tree); extern tree build_java_class_ref (tree); extern tree integral_constant_value (tree); +extern tree decl_constant_value_safe (tree); extern int diagnose_uninitialized_cst_or_ref_member (tree, bool, bool); /* in lex.c */