From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 55309 invoked by alias); 11 Dec 2018 18:53:49 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 55287 invoked by uid 89); 11 Dec 2018 18:53:49 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.9 required=5.0 tests=BAYES_00,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=OBJ_TYPE_REF, obj_type_ref, H*RU:209.85.222.193, Hx-spam-relays-external:209.85.222.193 X-HELO: mail-qk1-f193.google.com Received: from mail-qk1-f193.google.com (HELO mail-qk1-f193.google.com) (209.85.222.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 11 Dec 2018 18:53:46 +0000 Received: by mail-qk1-f193.google.com with SMTP id y78so9218592qka.12 for ; Tue, 11 Dec 2018 10:53:45 -0800 (PST) Return-Path: Received: from [192.168.1.149] (209-6-216-142.s141.c3-0.smr-cbr1.sbo-smr.ma.cable.rcncustomer.com. [209.6.216.142]) by smtp.gmail.com with ESMTPSA id v50sm9116588qtc.7.2018.12.11.10.53.42 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 11 Dec 2018 10:53:42 -0800 (PST) Subject: Re: [C++ PATCH] FIx constexpr virtual function call handling on ia64 (PR c++/87861) To: Jakub Jelinek Cc: Andreas Schwab , Marek Polacek , GCC Patches References: <20180918185534.GR16755@redhat.com> <20180919140518.GN5587@redhat.com> <20180919151023.GO5587@redhat.com> <20180920092059.GE8250@tucnak> <20181208090715.GS12380@tucnak> From: Jason Merrill Message-ID: Date: Tue, 11 Dec 2018 18:53:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.1 MIME-Version: 1.0 In-Reply-To: <20181208090715.GS12380@tucnak> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2018-12/txt/msg00732.txt.bz2 On 12/8/18 4:07 AM, Jakub Jelinek wrote: > On Thu, Sep 27, 2018 at 01:15:46AM -0400, Jason Merrill wrote: >>>> /usr/local/gcc/gcc-20180920/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual2.C:33:26: error: non-constant condition for static assertion >>>> /usr/local/gcc/gcc-20180920/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual2.C:33:23: error: expression '((& X2::_ZTV2X2) + 16)' does not designate a 'constexpr' function >>>> /usr/local/gcc/gcc-20180920/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual2.C:37:27: error: non-constant condition for static assertion >>>> /usr/local/gcc/gcc-20180920/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual2.C:37:24: error: expression '((& X2::_ZTV2X2) + 16)' does not designate a 'constexpr' function >>>> /usr/local/gcc/gcc-20180920/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual2.C:41:26: error: non-constant condition for static assertion >>>> /usr/local/gcc/gcc-20180920/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual2.C:41:23: error: expression '((& X4::_ZTV2X4) + 16)' does not designate a 'constexpr' function >>>> /usr/local/gcc/gcc-20180920/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual2.C:45:26: error: non-constant condition for static assertion >>>> /usr/local/gcc/gcc-20180920/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual2.C:45:23: error: expression '((& X4::_ZTV2X4) + 16)' does not designate a 'constexpr' function >>>> /usr/local/gcc/gcc-20180920/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual2.C:49:27: error: non-constant condition for static assertion >>>> /usr/local/gcc/gcc-20180920/gcc/testsuite/g++.dg/cpp2a/constexpr-virtual2.C:49:24: error: expression '((& X4::_ZTV2X4) + 16)' does not designate a 'constexpr' function >>>> compiler exited with status 1 >>>> FAIL: g++.dg/cpp2a/constexpr-virtual2.C (test for excess errors) >>> >>> I think the primary problem here is: >>> /* When using function descriptors, the address of the >>> vtable entry is treated as a function pointer. */ >>> if (TARGET_VTABLE_USES_DESCRIPTORS) >>> e2 = build1 (NOP_EXPR, TREE_TYPE (e2), >>> cp_build_addr_expr (e2, complain)); >>> in typeck.c, on non-descriptor targets we have an INDIRECT_REF where we >>> read the vtable function pointer. On ia64, the above optimizes the >>> INDIRECT_REF away, so what the cxx_eval_call_expression actually gets >>> after constexpr evaluating the CALL_FN is not ADDR_EXPR of a function, >>> but the address of the function descriptor (e.g. &_ZTV2X2 + 16 ). >>> >>> So, perhaps in cxx_eval_call_expression we need: >>> if (TREE_CODE (fun) == ADDR_EXPR) >>> fun = TREE_OPERAND (fun, 0); >>> + else if (TARGET_VTABLE_USES_DESCRIPTORS >>> + && TREE_CODE (fun) == POINTER_PLUS_EXPR >>> + && ...) >>> where we verify that p+ first argument is ADDR_EXPR of a virtual table, >>> second arg is INTEGER_CST and just walk the DECL_INITIAL of that, finding >>> the FDESC_EXPR at the right offset (therefore, I believe you need following >>> rather than the patch you've posted, so that you can actually find it) and >>> finally pick the function from the FDESC_EXPR entry. >>> Makes me wonder what happens with indirect calls in constexpr evaluation, >>> e.g. if I do: >>> constexpr int bar () { return 42; } >>> constexpr int foo () { int (*fn) () = bar; return fn (); } >>> static_assert (foo () == 42); >>> but apparently this works. >>> >>> --- gcc/cp/class.c.jj 2018-09-20 09:56:59.229751895 +0200 >>> +++ gcc/cp/class.c 2018-09-20 10:12:17.447370890 +0200 >>> @@ -9266,7 +9266,6 @@ build_vtbl_initializer (tree binfo, >>> tree vcall_index; >>> tree fn, fn_original; >>> tree init = NULL_TREE; >>> - tree idx = size_int (jx++); >>> >>> fn = BV_FN (v); >>> fn_original = fn; >>> @@ -9370,7 +9369,7 @@ build_vtbl_initializer (tree binfo, >>> int i; >>> if (init == size_zero_node) >>> for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i) >>> - CONSTRUCTOR_APPEND_ELT (*inits, idx, init); >>> + CONSTRUCTOR_APPEND_ELT (*inits, size_int (jx++), init); >>> else >>> for (i = 0; i < TARGET_VTABLE_USES_DESCRIPTORS; ++i) >>> { >>> @@ -9378,11 +9377,11 @@ build_vtbl_initializer (tree binfo, >>> fn, build_int_cst (NULL_TREE, i)); >>> TREE_CONSTANT (fdesc) = 1; >>> >>> - CONSTRUCTOR_APPEND_ELT (*inits, idx, fdesc); >>> + CONSTRUCTOR_APPEND_ELT (*inits, size_int (jx++), fdesc); >>> } >>> } >>> else >>> - CONSTRUCTOR_APPEND_ELT (*inits, idx, init); >>> + CONSTRUCTOR_APPEND_ELT (*inits, size_int (jx++), init); >>> } >>> } >> >> This patch is OK. And your suggestion for cxx_eval_call_expression >> sounds right, too. Marek, will you follow up on that? > > Here is the full patch. Besides the above already posted hunks and > proposed cxx_eval_call_expression changes I had to also divide token > in the OBJ_TYPE_REF handling by TARGET_VTABLE_USES_DESCRIPTORS, because > DECL_VINDEX of the second virtual table function is there 2 and of the third > 4 etc. > > Tested with a cross to ia64-linux on all the constexpr-virtual*.C testcases, > Jeff tested it on ia64-linux native and I've bootstrapped/regtested on > x86_64-linux and i686-linux. Ok for trunk? OK. Jason