[Bug c++/91774] New: Assignment from return value of function to reference returned by function occasionally produces wrong results

2019-09-15 Thread smartman1996 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91774

Bug ID: 91774
   Summary: Assignment from return value of function to reference
returned by function occasionally produces wrong
results
   Product: gcc
   Version: 7.4.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: smartman1996 at gmail dot com
  Target Milestone: ---

Created attachment 46885
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46885&action=edit
Original source file producing the bug.

PRIOR NOTIFICATION: this is a bug that has a temporary detouring solution with
an equivalent statement.
refer to number 7

ANOTHER NOTE: I am trying to minimize the source for reproducing the bug, but
the bug seems to show itself on very complex situations. I will report as soon
as possible.


2. System Environment Information

TestMachine #1

NAME="Ubuntu"
VERSION="18.04.3 LTS (Bionic Beaver)"
PRETTY_NAME="Ubuntu 18.04.3 LTS"
VERSION_ID="18.04"

4.15.0-1048-aws

TestMachine #2

OS 이름: Microsoft Windows 7 Home Premium K 
OS 버전: 6.1.7601 Service Pack 1 빌드 7601
OS 제조업체: Microsoft Corporation
OS 구성: 독립 실행형 워크스테이션
OS 빌드 종류:Multiprocessor Free
시스템 제조업체: SAMSUNG ELECTRONICS CO.,LTD
시스템 모델: Samsung Desktop System
시스템 종류: x64-based PC
프로세서:프로세서 1개 설치됨
 [01]: Intel64 Family 6 Model 42 Stepping 7
GenuineIntel ~3101Mhz

//Sorry for the locale and language of the local pc

3. Options for reproduction of bug

build was performed by using make

contents of the Makefile:

main: main.o
g++ -std=c++14 -Wall -O2 -g -o bin/main bin/main.o

main.o:
g++ -std=c++14 -Wall -O2 -g -c -o bin/main.o src/main.cpp

clear:
rm -f *.o bin/*.o bin/main

//end of contents of the Makefile

note: the bugs were also reproduced with -std=c++11, or without -O2

4. Complete commandline that triggers the bug

The source file was developed as a university undergraduate project.
The content is a Scheme Interpreter, yet a prototype.
It only does parsing, and does not do anything further.

providing the given testcase "testinput.txt" produces the bug

5. Compiler Output such error messages, warnings, etc.

Error Messages and Warnings were fully eliminated in the process of debugging

Therefore, no messages were produced with -Wall -Wextra

6. Test Case for Reproduction (as input)

content of testinput:

((dvo) wji (qbr) (ndo) qbr (kfh) (dvp) pzo (oos) (rmy) xuk xug fiv cks wjj zhn
(wjh) uwa lql kfe (ckk) lqm ckp ooq uwc pzt xul xun fis qbz )

EXIT

//end of content of testinput

7. description of bug (on the perspective of the user)

using language C++14
this is a broad description

suppose there are two classes A, B, and a struct type SAMPLETYPE

typedef struct{
CHILDTYPE x, y;
} SAMPLETYPE; 

class A{
SAMPLETYPE * data;

SAMPLETYPE & operator [] (size_t index){
return data[index];
}
}

class B{
_TYPE CalcFunc(){

while(){
// some while loop triggered on some condition
}

return (some calculation result);
}
}

The statement that triggers the bug:

A a;
B b;
auto index = (something);

a[index].x = b.CalcFunc();

The equivalent statement that avoids the bug:

A a;
B b;
auto index = (something);

{
auto temp = b.CalcFunc();
a[index].x = temp;
}


summary:
if the left operand is a reference returned by operator []
and if the right operand is a calculation
and if the calculation by the calcfunc got the while loop triggered
previously

then the return value is stored in the reference with a difference of -1

Note that the return value is correct if printed out.

The bug is suspected to be related with the assignment and reference.

Though this could be avoided if we detour through a temporary local
variable as above.

8. additional note

as a student, I tested on MSVC and it did not represent a bug.

information about the test version of MSVC:

Microsoft Visual Studio Community 2019
Version 16.2.3

_MSC_VER has value 1922
_MSC_FULL_VER has value 192227905

System Environment Information of that ran MSVC:

OS 이름: Microsoft Windows 10 Education
OS 버전: 10.0.17134 N/A 빌드 17134
OS 제조업체: Microsoft Corporation
OS 구성: 독립 실행형 워크스테이션
OS 빌드 종류:Multiprocessor Free
시스템 제조업체: TRIGEM COMPUTER
시스템 모델: TG DESKTOP PC
시스템 종류: x64-based PC
프로세서:프로세서 1개 설치됨
 [01]: Intel64 Family 6 Model 158 Stepping 10
GenuineIntel ~3000Mhz
BIOS 버전:   

[Bug c++/91774] Assignment from return value of function to reference returned by function occasionally produces wrong results

2019-09-16 Thread smartman1996 at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91774

--- Comment #3 from 이경룡  ---
Oops. Sorry for the unclear explanation on the core. Forgive me.

the throw statement is not the bug itself but acted as a detector for the bug

line 28868 ~ 28925: Definition of Interpreter::Read()

line 28901 has statement:

ListManager[probe].rchild = ListManager.Alloc();

which corresponds to the statement in the prior explanation:

a[index].x = b.CalcFunc();

line 28557 ~ 28587: Definition of ListPocket::Alloc();

{
while(true){
//something
}

//some calculation

return allocIndex;
}


Observing the bug with the testcase:

among many times the ListPocket::Alloc() is invoked via
"ListManager.Alloc()"
when the if statement with a for loop inside is triggered, the return value
is expected to be 30
(sorry for mistaking it as a while loop in the prior
explanation)

the problem is that
the return value of "ListManager.Alloc()" is not properly assigned into the
reference "ListManager[probe].rchild"
In fact, the gdb shows that the return value is 30(even immediately after
the return)
and using std::cout to print out the value reports as 30 inside and outside
the function prints 30.

the cout part was disabled by the preprocessor and cannot be seen.

i.e. ListManager[probe].rchild remains 29 (it was formerly 29)

the equivalent statement that works well is:

{
auto temp = ListManager.Alloc();
ListManager[probe].rchild = temp;
}

Note: sorry for the source reduction being late.