Bug 1136738
| Summary: | optimization option(O2) of g++ work abnormally | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 7 | Reporter: | gary3710 <gary> | ||||
| Component: | gcc | Assignee: | Jakub Jelinek <jakub> | ||||
| Status: | CLOSED NOTABUG | QA Contact: | qe-baseos-tools-bugs | ||||
| Severity: | high | Docs Contact: | |||||
| Priority: | unspecified | ||||||
| Version: | 7.0 | CC: | mfranc, mpolacek | ||||
| Target Milestone: | rc | Keywords: | Reopened | ||||
| Target Release: | --- | ||||||
| Hardware: | x86_64 | ||||||
| OS: | Linux | ||||||
| Whiteboard: | |||||||
| Fixed In Version: | Doc Type: | Bug Fix | |||||
| Doc Text: | Story Points: | --- | |||||
| Clone Of: | Environment: | ||||||
| Last Closed: | 2014-09-03 09:14:34 UTC | Type: | Bug | ||||
| Regression: | --- | Mount Type: | --- | ||||
| Documentation: | --- | CRM: | |||||
| Verified Versions: | Category: | --- | |||||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |||||
| Cloudforms Team: | --- | Target Upstream Version: | |||||
| Embargoed: | |||||||
| Attachments: |
|
||||||
The testcase triggers undefined behavior, so the bug is in there, not on the compiler side.
...
unsigned int nodeIdList[1];
...
for(i=0; i<m_nodeCnt; i++)
{
pGroup->nodeIdList[i] = htonl(m_nodeId[i]);
printf("%d:%d\n", i, m_nodeCnt);
}
As m_nodeCnt is 2 in the first invocation and 8 in the second, the second iteration results in out of bounds access to the nodeIdList array, which only has a single element. Note, in the m_nodeCnt 8 case there is another out of bound array access, m_nodeId[2] can't be stored or read either. While in that case it is the last field in the structure and the compiler will treat it as an attempt for flexible array member, the tst2 variable doesn't have room for any further fields.
(In reply to Jakub Jelinek from comment #2) > The testcase triggers undefined behavior, so the bug is in there, not on the > compiler side. > ... > unsigned int nodeIdList[1]; > ... > for(i=0; i<m_nodeCnt; i++) > { > pGroup->nodeIdList[i] = htonl(m_nodeId[i]); > printf("%d:%d\n", i, m_nodeCnt); > } > > As m_nodeCnt is 2 in the first invocation and 8 in the second, the second > iteration results in out of bounds access to the nodeIdList array, which > only has a single element. Note, in the m_nodeCnt 8 case there is another > out of bound array access, m_nodeId[2] can't be stored or read either. > While in that case it is the last field in the structure and the compiler > will treat it as an attempt for flexible array member, the tst2 variable > doesn't have room for any further fields. unsigned int nodeIdList[1]; It's a buffer space,Not only a struct variable, pGroup convert from (void *buf) And work normaly in rhel6 m_nodeId[2] really a problem, chang count of this array to 8,Bug alread exist. There is another field after that, you can't do those out of bound accesses that way in C/C++. If you remove the name field after it, it will work, because it will be treated like flexible array member accesses in that case. The reason gcc only runs one iteration of the loop is that it finds out that in a valid C/C++, i can be at most 1 in the loop not to trigger undefined behavior, thus m_nodeCnt must be 0 or 1 in a valid program and the loop can be then optimized. In windows os,exist a lot of struct of system api defined like this;
example:
typedef struct _IP_UNIDIRECTIONAL_ADAPTER_ADDRESS {
ULONG NumAdapters;
IPAddr Address[1];
} IP_UNIDIRECTIONAL_ADAPTER_ADDRESS, *PIP_UNIDIRECTIONAL_ADAPTER_ADDRESS;
At same time, many code compile in more than one OS(Include windows、redhat、suse,etc.),it will work abnormally in rhel7.
must change code cater to rhel7?
Or
have a optional close this optimal function?
Thanks.
Sorry,my code has bug. I try move name array befor nodeIdList,And work normaly. Please close this bug. Thanks . See above, in that case Address field is the last in the structure, therefore it is treated similarly to C99 flexible array members (struct ... { ULONG NumAdapters; IPAddr Address[]; } ...; C++ and C89 don't have flexible array members, so as an extension this is allowed), where out of bounds accesses are permitted unless the structure is a static/automatic variable where it can be proven that there is no space for the extra elements.
Only the last field in the structure behaves that way though, that is not the case of your testcase, where you have some other field after it. In array fields other than the last one accessing the element with index equal or greater than number of array elements is invalid, and taking address of element with index greater than number of array elements is also invalid.
|
Created attachment 933966 [details] file.tar.gz include makefile and testloop.cpp Description of problem: For recirculation code, after being optimized by option 02, the generated executable binary file is wrong. Version-Release number of selected component (if applicable): g++ version: g++ (GCC) 4.8.2 20140120 (Red Hat 4.8.2-16) How reproducible: Execute “make release” once through the attached file, then execute the generated binary code; After that, execute “make debug” once and its generated binary code; at last, compare these two output results. Actual results: The output results are different. Expected results: The output results should be the same. Additional info: We have tried the optimization of O1, O2, O3 and O4, the bug will always exist.