User account creation filtered due to spam.

Bug 48570 - [4.6/4.7 Regression] wrong subscription with -std=c++0x
Summary: [4.6/4.7 Regression] wrong subscription with -std=c++0x
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: regression (show other bugs)
Version: 4.6.1
: P3 normal
Target Milestone: 4.6.1
Assignee: Jakub Jelinek
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-04-12 11:58 UTC by Holger Hopp
Modified: 2011-04-13 15:58 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2011-04-12 12:16:25


Attachments
gcc46-pr48570.patch (1.04 KB, patch)
2011-04-12 14:01 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Holger Hopp 2011-04-12 11:58:08 UTC
gcc-4.6 and trunk produce wrong results here.
I expect return 1 (==), but gcc-4.6 and trunk return 0 (!=).

$ g++ -std=c++0x t.c && ./a.out

gcc-4.5 and gcc-4.6 without -std=c++0x work correctly,
char type works correctly, but not wchar_t, char16_t, char32_t.


int main()
{
  wchar_t z = (L"01234")[1];
  return (z == L'1');
}
Comment 1 Jakub Jelinek 2011-04-12 12:16:25 UTC
Confirmed, though better would be to test for != so that the correct exit value is 0:

// PR c++/48570
// { dg-do run }
// { dg-options "-std=c++0x" }

int
main ()
{
  wchar_t z = L"01234"[1];
  return z != L'1';
}

This started failing with http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=170488
Comment 2 Jonathan Wakely 2011-04-12 12:21:48 UTC
Breakpoint 1, main () at sub.cc:4
4         const wchar_t& z0 = (L"01234")[0];
(gdb) n
5         const wchar_t& z1 = (L"01234")[1];
(gdb)
6         const wchar_t& z2 = (L"01234")[2];
(gdb)
7         const wchar_t& z3 = (L"01234")[3];
(gdb)
8         return (z1 == L'1');
(gdb) p z0
$1 = (const wchar_t &) @0x7fffffffe590: 48 L'0'
(gdb) p z1
$2 = (const wchar_t &) @0x7fffffffe594: 0 L'\000'
(gdb) p z2
$3 = (const wchar_t &) @0x7fffffffe598: 0 L'\000'
(gdb) p z3
$4 = (const wchar_t &) @0x7fffffffe59c: 0 L'\000'

The string literal contains zeroes past the first character
Comment 3 Jakub Jelinek 2011-04-12 12:30:54 UTC
Yeah, cxx_eval_array_reference doesn't expect to have sizeof (x) > 1 accesses to STRING_CSTs.  Unfortunately, fold_read_from_constant_string doesn't handle those either, and as for C++0x I fear it must always succeed, it will need to handle all the endianity fun.
Comment 4 joseph@codesourcery.com 2011-04-12 12:44:03 UTC
There are lots of optimizations that are only present for narrow strings 
but logically make sense for wide strings as well (for example, some str* 
and mem* built-in functions should logically have wcs* and wmem* analogues 
... it was while looking at that some time ago that I found glibc's 
wmemcmp was wrongly comparing wide characters as type wint_t instead of 
wchar_t).  Hopefully not many cases need addressing to fix this wrong-code 
bug, but the infrastructure for extracting values from wide string 
constants could be of use in future for dealing with the more general 
missing optimizations.
Comment 5 Jakub Jelinek 2011-04-12 14:01:38 UTC
Created attachment 23962 [details]
gcc46-pr48570.patch

Untested fix (tested just on the new testcase, both on x86_64 and with powerpc cross to deal with endianity).
Comment 6 Jakub Jelinek 2011-04-13 15:38:53 UTC
Author: jakub
Date: Wed Apr 13 15:38:50 2011
New Revision: 172377

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172377
Log:
	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.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-wstring1.C
    trunk/gcc/testsuite/g++.dg/cpp0x/constexpr-wstring2.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/semantics.c
    trunk/gcc/testsuite/ChangeLog
Comment 7 Jakub Jelinek 2011-04-13 15:47:44 UTC
Author: jakub
Date: Wed Apr 13 15:47:40 2011
New Revision: 172378

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172378
Log:
	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.

Added:
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/cpp0x/constexpr-wstring1.C
    branches/gcc-4_6-branch/gcc/testsuite/g++.dg/cpp0x/constexpr-wstring2.C
Modified:
    branches/gcc-4_6-branch/gcc/cp/ChangeLog
    branches/gcc-4_6-branch/gcc/cp/semantics.c
    branches/gcc-4_6-branch/gcc/testsuite/ChangeLog
Comment 8 Jakub Jelinek 2011-04-13 15:58:46 UTC
Fixed.