[Bug libstdc++/89118] Illegal memory access in codecvt::out()

2019-01-30 Thread vagran.ast at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89118

--- Comment #1 from vagran  ---
If using std::locale::classic() it additionally does not return valid result as
well. According to standard it should. See notes:
https://en.cppreference.com/w/cpp/locale/locale/classic.

[Bug libstdc++/89118] New: Illegal memory access in codecvt::out()

2019-01-30 Thread vagran.ast at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89118

Bug ID: 89118
   Summary: Illegal memory access in codecvt::out()
   Product: gcc
   Version: 8.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: libstdc++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: vagran.ast at gmail dot com
  Target Milestone: ---

On Ubuntu 18.04.1 I try to compile and run example from
https://en.cppreference.com/w/cpp/locale/codecvt/out under Valgrind.

#include 
#include 
#include 

int main()
{
std::locale::global(std::locale("en_US.utf8"));
auto& f = std::use_facet>(std::locale());
std::wstring internal = L"z\u00df\u6c34\U0001f34c"; // L"zß水"

// note that the following can be done with wstring_convert
std::mbstate_t mb{}; // initial shift state
std::string external(internal.size() * f.max_length(), '\0'); 
const wchar_t* from_next;
char* to_next;
f.out(mb, [0], [internal.size()], from_next,
  [0], [external.size()], to_next);
// error checking skipped for brevity
external.resize(to_next - [0]);

std::cout << "The string in narrow multibyte encoding: " << external <<
'\n';
}

g++ test.cpp
valgrind ./a.out
==2924== Memcheck, a memory error detector
==2924== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2924== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2924== Command: ./a.out
==2924== 
==2924== Invalid read of size 16
==2924==at 0x54AD98D: __wcsnlen_sse4_1 (strlen.S:117)
==2924==by 0x549B458: wcsnrtombs (wcsnrtombs.c:58)
==2924==by 0x4EEBD9D: std::codecvt::do_out(__mbstate_t&, wchar_t const*, wchar_t const*, wchar_t
const*&, char*, char*, char*&) const (in
/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2924==by 0x1095FF: std::__codecvt_abstract_base::out(__mbstate_t&, wchar_t const*, wchar_t const*, wchar_t
const*&, char*, char*, char*&) const (in /home/artyom/tmp/a.out)
==2924==by 0x1093EC: main (in /home/artyom/tmp/a.out)
==2924==  Address 0x5b84530 is 12 bytes after a block of size 20 alloc'd
==2924==at 0x4C3017F: operator new(unsigned long) (in
/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2924==by 0x4F7757C: void std::__cxx11::basic_string, std::allocator >::_M_construct(wchar_t const*, wchar_t const*, std::forward_iterator_tag) (in
/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2924==by 0x1092DE: main (in /home/artyom/tmp/a.out)
==2924== 
==2924== Invalid read of size 16
==2924==at 0x54AD992: __wcsnlen_sse4_1 (strlen.S:117)
==2924==by 0x549B458: wcsnrtombs (wcsnrtombs.c:58)
==2924==by 0x4EEBD9D: std::codecvt::do_out(__mbstate_t&, wchar_t const*, wchar_t const*, wchar_t
const*&, char*, char*, char*&) const (in
/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2924==by 0x1095FF: std::__codecvt_abstract_base::out(__mbstate_t&, wchar_t const*, wchar_t const*, wchar_t
const*&, char*, char*, char*&) const (in /home/artyom/tmp/a.out)
==2924==by 0x1093EC: main (in /home/artyom/tmp/a.out)
==2924==  Address 0x5b84540 is 16 bytes after a block of size 32 in arena
"client"
==2924== 
==2924== Conditional jump or move depends on uninitialised value(s)
==2924==at 0x54ADA61: __wcsnlen_sse4_1 (strlen.S:161)
==2924==by 0x549B458: wcsnrtombs (wcsnrtombs.c:58)
==2924==by 0x4EEBD9D: std::codecvt::do_out(__mbstate_t&, wchar_t const*, wchar_t const*, wchar_t
const*&, char*, char*, char*&) const (in
/usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25)
==2924==by 0x1095FF: std::__codecvt_abstract_base::out(__mbstate_t&, wchar_t const*, wchar_t const*, wchar_t
const*&, char*, char*, char*&) const (in /home/artyom/tmp/a.out)
==2924==by 0x1093EC: main (in /home/artyom/tmp/a.out)
==2924== 
The string in narrow multibyte encoding: zß水
==2924== 
==2924== HEAP SUMMARY:
==2924== in use at exit: 11,919 bytes in 113 blocks
==2924==   total heap usage: 149 allocs, 36 frees, 90,511 bytes allocated
==2924== 
==2924== LEAK SUMMARY:
==2924==definitely lost: 0 bytes in 0 blocks
==2924==indirectly lost: 0 bytes in 0 blocks
==2924==  possibly lost: 0 bytes in 0 blocks
==2924==still reachable: 11,919 bytes in 113 blocks
==2924== suppressed: 0 bytes in 0 blocks
==2924== Rerun with --leak-check=full to see details of leaked memory
==2924== 
==2924== For counts of detected and suppressed errors, rerun with: -v
==2924== Use --track-origins=yes to see where uninitialised values come from
==2924== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)

ldd a.out 
linux-vdso.so.1 (0x7ffd63be6000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(0x7f6494552000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1
(0x7f649433a000)
l

[Bug c++/60336] empty struct value is passed differently in C and C++

2014-08-12 Thread vagran.ast at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60336

--- Comment #24 from vagran vagran.ast at gmail dot com ---
Just to be on a safe side, please, also do not forget that empty struct (or
class) is really zero in the case when another structure (or class) is derived
from it. For example, such test would be useful after fix:

struct A {};

struct B: A {
int i;
};

assert(sizeof(B) == sizeof(int));

And something like this:

struct A {};
struct B: A {};
struct C: B {};
struct D: C {};

assert(sizeof(D) == 1);


[Bug target/60336] empty struct value is passed differently in C and C++

2014-02-26 Thread vagran.ast at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60336

--- Comment #9 from vagran vagran.ast at gmail dot com ---
(In reply to Andrew Pinski from comment #7)
 (In reply to H.J. Lu from comment #4)
  Is this test valid? BTW, clang works fine on x86.
 
 No this testcase is not valid at all.  See
 http://gcc.gnu.org/onlinedocs/gcc-4.8.2/gcc/Empty-Structures.html#Empty-
 Structures where it is documented it is not valid.

How it proves that the test case is invalid? Independently on what size has
empty structure the called function absolutely legally can expect it receives
the values which were passed by the caller. A compiler should care it works for
both C and C++. Am I wrong?

Also as I remember in C++ size of empty structure is sizeof(char) except the
case some class is derived from the empty structure. In this case it adds no
overhead to the size of the derived class itself (thus virtually has zero size
in this case).


[Bug c++/54137] New: expected primary-expression error when accessing template method

2012-07-31 Thread vagran.ast at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54137

 Bug #: 54137
   Summary: expected primary-expression error when accessing
template method
Classification: Unclassified
   Product: gcc
   Version: 4.7.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: vagran@gmail.com


Created attachment 27905
  -- http://gcc.gnu.org/bugzilla/attachment.cgi?id=27905
Source, preprocessed source, compilation log.

When compiling the code snippet below (preprocessed source is also attached) I
have the following errors:

test.cpp: In member function ‘DerivedObjectT::Item*
DerivedObjectT::CreateItem()’:
test.cpp:41:53: error: expected primary-expression before ‘’ token
test.cpp:41:55: error: expected primary-expression before ‘)’ token

The main reason I suspect it is a bug is the fact that after replacing line 41
 return GetFabric().CreateObjectItem();
=== by
 Fabric f = GetFabric();
 return f.CreateObjectItem();
it compiles and works as expected.

I have tried to minimize the code to just reflect inheritance graph in the
place where the problem was found.

#include utility

class Fabric {
public:
template class T, typename... Args
T *
CreateObject(Args... args)
{
return new T(std::forwardArgs(args)...);
}

template class T
T *
CreateObject()
{
return new T;
}
};

class Object {
public:
Fabric f;

Fabric 
GetFabric()
{
return f;
}
};

template class T
class DerivedObject: public Object {
public:
class Item: public Object {
T item;
};

Item *
CreateItem()
{
return GetFabric().CreateObjectItem();
// The commented lines below do not produce any errors:
// Fabric f = GetFabric();
// return f.CreateObjectItem();
}
};

int 
main()
{
DerivedObjectint d;
d.CreateItem();
return 0;
}


[Bug c++/54137] expected primary-expression error when accessing template method

2012-07-31 Thread vagran.ast at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54137

--- Comment #2 from vagran vagran.ast at gmail dot com 2012-07-31 11:46:02 
UTC ---
Thanks!
Would be fine if the error message could contain the probable cause hint for
this kind of error (if technically possible).


[Bug inline-asm/50772] New: Inline assembler A constrain works non-expectedly on 64-bits target

2011-10-18 Thread vagran.ast at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50772

 Bug #: 50772
   Summary: Inline assembler A constrain works non-expectedly on
64-bits target
Classification: Unclassified
   Product: gcc
   Version: 4.6.1
Status: UNCONFIRMED
  Severity: minor
  Priority: P3
 Component: inline-asm
AssignedTo: unassig...@gcc.gnu.org
ReportedBy: vagran@gmail.com


As per documentation A constrain of inline assembler should accept/return
64-bits value in eax:edx registers pair. However it doesn't work on 64-bits
target, the value of just %rdx register is used instead.
Use case example:
rdmsr and wrmsr x86 instruction use eax:edx pair in both 32 and 64 bits mode.
The following code will not work on 64-bits target:

static inline u64
rdmsr(u32 msr)
{
u64 rc;
ASM (
rdmsr
: =A(rc)
: c(msr)
);
return rc;
}
Value in %rdx will be used as the result, %rax value will be discarded. The
same situation when A constrain is used as input. It is not a major problem,
it can be easily worked around by additional instructions in inline assembler
block. But IMHO it should be fixed either in the compiler code (preferably) or
in documentation (mention that it is not supported on 64-bits target).