From patchwork Mon Feb 4 20:48:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 1036264 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-495271-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="S9cncOWJ"; dkim-atps=neutral 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 43tfv64X46z9sMl for ; Tue, 5 Feb 2019 07:48:47 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=KEhiVc7YutI5IDkDCEcWGwoVeCjv94c7paxxzbeRn7kqOZ7GDX+zm XHqDB8JU8ED+bPEfSIOGFSPf8GqxmLWCY1fPyaMO5gmx2iyZa+JtVrH4Faxh5pp1 ZKC0yDQJKysIH0bBGvxb7au8h0B27NVuUvBxLH3g/nCfaY3bf2xk4w= 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:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=96vIJ5WGCj812sI6wrpTb1//2FE=; b=S9cncOWJaeCJ4NJKeBl/ ksOWS+hPKDceSo3m+nM2/SdfkkQdXNImkgrhCfymmEdmqQc+iOCdCZu72nWrc5dJ biiGVTaoOnWU0OshrubNIUxZSs4WlnueON8TP3LWBY81s5l0dmv6RBT1hdGET5By vFZWKNW1wT7AxSdNafTrc4g= Received: (qmail 61117 invoked by alias); 4 Feb 2019 20:48:40 -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 61097 invoked by uid 89); 4 Feb 2019 20:48:40 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 04 Feb 2019 20:48:38 +0000 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 71B49356E5 for ; Mon, 4 Feb 2019 20:48:37 +0000 (UTC) Received: from redhat.com (unknown [10.20.4.51]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 14BEA75C6E; Mon, 4 Feb 2019 20:48:36 +0000 (UTC) Date: Mon, 4 Feb 2019 15:48:35 -0500 From: Marek Polacek To: GCC Patches , Jason Merrill Subject: C++ PATCH for c++/89158 - by-value capture of constexpr variable broken Message-ID: <20190204204835.GD3884@redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) In this test we have a user-defined conversion converting const int & to T, and we're binding a const int to const int & -- the parameter of the converting ctor. We call Func with "VIEW_CONVERT_EXPR(Val)" as an argument. I like to use a diagram for the conversion like this: ck_rvalue <- ck_user <- ck_identity T T const int V_C_E(Val) when processing the ck_user part we call __ct_comp, whose ICS for its argument is ck_ref_bind <- ck_identity const int & <- const int V_C_E(Val) this ICS comes from reference_binding, and at that time we still had "Val" so need_temporary_p is 0. But when processing the ck_user conversion before calling build_over_call for the __ct_comp, we call 7009 expr = mark_rvalue_use (expr); for the argument which turns the V_C_E to NON_LVALUE_EXPR<42>. Binding "42" to const int & is possible, but requires a temporary, which we don't create precisely because need_temporary_p is 0. I.e. the original expr of the conversion changed behind reference_binding's back. Now, the call to mark_rvalue_use was added in r159096 to handle -Wunused-but-set-variable. Since r261121, we're actually able to turn a V_C_E into an rvalue. But it seems we shouldn't be trying to turn the argument into an rvalue in the ck_user case; mark_lvalue_use should do the job (= mark is as used) without changing an lvalue into an rvalue, breaking the ICS as above. I'm not sure if I'm describing the issue clearly enough, but I hope this will do. Bootstrapped/regtested on x86_64-linux, ok for trunk/8? 2019-02-04 Marek Polacek PR c++/89158 - by-value capture of constexpr variable broken. * call.c (convert_like_real) : Call mark_lvalue_use instead of mark_rvalue_use. * g++.dg/cpp0x/lambda/lambda-89158.C: New test. diff --git gcc/cp/call.c gcc/cp/call.c index c74d1b4ebdf..68395503e1e 100644 --- gcc/cp/call.c +++ gcc/cp/call.c @@ -7006,7 +7006,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, return expr; } - expr = mark_rvalue_use (expr); + /* Calling mark_rvalue_use could turn a decl into a constant, breaking + e.g. the need_temporary_p assumption in the ICS. */ + mark_lvalue_use (expr); /* Pass LOOKUP_NO_CONVERSION so rvalue/base handling knows not to allow any more UDCs. */ diff --git gcc/testsuite/g++.dg/cpp0x/lambda/lambda-89158.C gcc/testsuite/g++.dg/cpp0x/lambda/lambda-89158.C new file mode 100644 index 00000000000..15f15b46875 --- /dev/null +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-89158.C @@ -0,0 +1,11 @@ +// PR c++/89158 +// { dg-do compile { target c++11 } } + +struct T { T(const int&); }; +void Func(T); + +void test() +{ + constexpr int Val = 42; + [Val]() { Func(Val); }; +}