From patchwork Wed Apr 13 08:48:54 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 90969 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 635A4B6F3A for ; Wed, 13 Apr 2011 18:49:12 +1000 (EST) Received: (qmail 31781 invoked by alias); 13 Apr 2011 08:49:09 -0000 Received: (qmail 31768 invoked by uid 22791); 13 Apr 2011 08:49:07 -0000 X-SWARE-Spam-Status: No, hits=-6.4 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 13 Apr 2011 08:48:57 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p3D8mvBF009003 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 13 Apr 2011 04:48:57 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [10.16.42.4]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p3D8muFm000997 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 13 Apr 2011 04:48:56 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (localhost.localdomain [127.0.0.1]) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4) with ESMTP id p3D8mtaZ004060; Wed, 13 Apr 2011 10:48:55 +0200 Received: (from jakub@localhost) by tyan-ft48-01.lab.bos.redhat.com (8.14.4/8.14.4/Submit) id p3D8mtUj004058; Wed, 13 Apr 2011 10:48:55 +0200 Date: Wed, 13 Apr 2011 10:48:54 +0200 From: Jakub Jelinek To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: Re: [C++ PATCH] Handle correctly ARRAY_REFs from STRING_CST for wchar_t/char{16, 32}_t (PR c++/48570) Message-ID: <20110413084854.GJ17079@tyan-ft48-01.lab.bos.redhat.com> Reply-To: Jakub Jelinek References: <20110412170643.GF17079@tyan-ft48-01.lab.bos.redhat.com> <4DA4DCAF.5040905@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <4DA4DCAF.5040905@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) 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 On Tue, Apr 12, 2011 at 07:13:51PM -0400, Jason Merrill wrote: > On 04/12/2011 01:06 PM, Jakub Jelinek wrote: > >+ : (unsigned)TREE_STRING_LENGTH (ary) > >+ * (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (ary))) > >+ / TYPE_PRECISION (char_type_node))); > > Don't you mean / instead of * here? You're right, thanks for catching it. I've added a testcase for the out of bounds case too. > Let's also calculate the size > of the element once rather than here and again later. Like this? Bootstrapped/regtested on x86_64-linux and i686-linux: 2011-04-13 Jakub Jelinek PR c++/48570 * semantics.c (cxx_eval_array_reference): Handle reading from wchar_t, char16_t and char32_t STRING_CST. * g++.dg/cpp0x/constexpr-wstring1.C: New test. * g++.dg/cpp0x/constexpr-wstring2.C: New test. Jakub --- gcc/cp/semantics.c.jj 2011-04-12 19:43:49.433483082 +0200 +++ gcc/cp/semantics.c 2011-04-13 08:25:07.904796653 +0200 @@ -6279,7 +6279,7 @@ cxx_eval_array_reference (const constexp non_constant_p); tree index, oldidx; HOST_WIDE_INT i; - unsigned len; + unsigned len, elem_nchars = 1; if (*non_constant_p) return t; oldidx = TREE_OPERAND (t, 1); @@ -6291,9 +6291,14 @@ cxx_eval_array_reference (const constexp return t; else if (addr) return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL); - len = (TREE_CODE (ary) == CONSTRUCTOR - ? CONSTRUCTOR_NELTS (ary) - : (unsigned)TREE_STRING_LENGTH (ary)); + if (TREE_CODE (ary) == CONSTRUCTOR) + len = CONSTRUCTOR_NELTS (ary); + else + { + elem_nchars = (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (ary))) + / TYPE_PRECISION (char_type_node)); + len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars; + } if (compare_tree_int (index, len) >= 0) { if (!allow_non_constant) @@ -6304,9 +6309,16 @@ cxx_eval_array_reference (const constexp i = tree_low_cst (index, 0); if (TREE_CODE (ary) == CONSTRUCTOR) return VEC_index (constructor_elt, CONSTRUCTOR_ELTS (ary), i)->value; - else + else if (elem_nchars == 1) return build_int_cst (cv_unqualified (TREE_TYPE (TREE_TYPE (ary))), TREE_STRING_POINTER (ary)[i]); + else + { + tree type = cv_unqualified (TREE_TYPE (TREE_TYPE (ary))); + return native_interpret_expr (type, (const unsigned char *) + TREE_STRING_POINTER (ary) + + i * elem_nchars, elem_nchars); + } /* Don't VERIFY_CONSTANT here. */ } --- gcc/testsuite/g++.dg/cpp0x/constexpr-wstring1.C.jj 2011-04-13 08:21:23.079513403 +0200 +++ gcc/testsuite/g++.dg/cpp0x/constexpr-wstring1.C 2011-04-13 08:21:23.079513403 +0200 @@ -0,0 +1,34 @@ +// PR c++/48570 +// { dg-do run } +// { dg-options "-std=c++0x" } + +extern "C" void abort (); +constexpr wchar_t foo (int i) { return L"0123"[i]; } +constexpr char16_t bar (int i) { return u"0123"[i]; } +constexpr char32_t baz (int i) { return U"0123"[i]; } +const wchar_t foo0 = foo (0); +const wchar_t foo1 = foo (1); +const wchar_t foo2 = foo (2); +const wchar_t foo3 = foo (3); +const wchar_t foo4 = foo (4); +const char16_t bar0 = bar (0); +const char16_t bar1 = bar (1); +const char16_t bar2 = bar (2); +const char16_t bar3 = bar (3); +const char16_t bar4 = bar (4); +const char32_t baz0 = baz (0); +const char32_t baz1 = baz (1); +const char32_t baz2 = baz (2); +const char32_t baz3 = baz (3); +const char32_t baz4 = baz (4); + +int +main () +{ + if (foo0 != L'0' || foo1 != L'1' || foo2 != L'2' || foo3 != L'3' || foo4 != L'\0') + abort (); + if (bar0 != u'0' || bar1 != u'1' || bar2 != u'2' || bar3 != u'3' || bar4 != u'\0') + abort (); + if (baz0 != U'0' || baz1 != U'1' || baz2 != U'2' || baz3 != U'3' || baz4 != U'\0') + abort (); +} --- gcc/testsuite/g++.dg/cpp0x/constexpr-wstring2.C.jj 2011-04-13 08:26:01.158764728 +0200 +++ gcc/testsuite/g++.dg/cpp0x/constexpr-wstring2.C 2011-04-13 08:29:31.321808236 +0200 @@ -0,0 +1,7 @@ +// PR c++/48570 +// { dg-do compile } +// { dg-options -std=c++0x } + +constexpr wchar_t c1 = L"hi"[3]; // { dg-error "out of bound" } +constexpr char16_t c2 = u"hi"[3]; // { dg-error "out of bound" } +constexpr char32_t c3 = U"hi"[3]; // { dg-error "out of bound" }