-
Bug
-
Resolution: Fixed
-
P4
-
11, 17, 19, 20
-
b05
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8313748 | 17.0.10-oracle | Tobias Hartmann | P4 | Resolved | Fixed | b01 |
JDK-8312129 | 17.0.9 | Ben Taylor | P4 | Resolved | Fixed | b01 |
GCC 12 warns about output buffer size:
```
/shared/projects/openjdk/jdk-jdk/source/src/hotspot/share/adlc/output_c.cpp: In function 'int pipeline_res_mask_initializer(FILE*, PipelineForm*, NameList&, NameList&, PipeClassForm*)':
/shared/projects/openjdk/jdk-jdk/source/src/hotspot/share/adlc/output_c.cpp:529:36: error: '%*d' directive writing between 1 and 2147483647 bytes into a region of size between 0 and 2147483637 [-Werror=format-overflow=]
529 | sprintf(args, "0x%0*x, 0x%0*x, %*d",
| ^~~
```
GCC complains that the output buffer for sprintf is too short. We allocate a buffer fitting the fixed parts of the format string, the terminating zero, and the variable widths, then print into it:
```
char* args = new char [9 + 2*masklen + maskdigit];
sprintf(args, "0x%0*x, 0x%0*x, %*d",
masklen, resources_used,
masklen, resources_used_exclusively,
maskdigit, element_count);
```
masklen is a constant and known to the compiler. maskdigit is not. For all the compiler knows, it could be 0. Format specified is "%*s", which we feed maskdigit as width, element_count as argument to print.
If maskdigit is too small, sprintf will not truncate. The result is that for all the compiler knows, the output array could be 10 characters too small (since element_count is unsigned 32bit, 10 digits).
There are similar errors like that:
```
/shared/projects/openjdk/jdk-jdk/source/src/hotspot/share/adlc/output_c.cpp: In function 'void check_peepconstraints(FILE*, FormDict&, PeepMatch*, PeepConstraint*)':
/shared/projects/openjdk/jdk-jdk/source/src/hotspot/share/adlc/output_c.cpp:1171:42: error: '_idx' directive writing 4 bytes into a region of size between 2 and 12 [-Werror=format-overflow=]
1171 | sprintf(left_reg_index,",inst%d_idx%d", (int)left_index, left_op_index);
/shared/projects/openjdk/jdk-jdk/source/src/hotspot/share/adlc/output_c.cpp:1184:45: error: '_idx' directive writing 4 bytes into a region of size between 2 and 12 [-Werror=format-overflow=]
1184 | sprintf(right_reg_index,",inst%d_idx%d", (int)right_index, right_op_index);
```
these are a bit simpler, since they don't have variable sized widths. The compiler just complains about the buffer. Buffer does not allow the parameters to be beyond 9999, which is asserted, but the GCC does not understand this.
```
/shared/projects/openjdk/jdk-jdk/source/src/hotspot/share/adlc/output_c.cpp: In function 'int pipeline_res_mask_initializer(FILE*, PipelineForm*, NameList&, NameList&, PipeClassForm*)':
/shared/projects/openjdk/jdk-jdk/source/src/hotspot/share/adlc/output_c.cpp:529:36: error: '%*d' directive writing between 1 and 2147483647 bytes into a region of size between 0 and 2147483637 [-Werror=format-overflow=]
529 | sprintf(args, "0x%0*x, 0x%0*x, %*d",
| ^~~
```
GCC complains that the output buffer for sprintf is too short. We allocate a buffer fitting the fixed parts of the format string, the terminating zero, and the variable widths, then print into it:
```
char* args = new char [9 + 2*masklen + maskdigit];
sprintf(args, "0x%0*x, 0x%0*x, %*d",
masklen, resources_used,
masklen, resources_used_exclusively,
maskdigit, element_count);
```
masklen is a constant and known to the compiler. maskdigit is not. For all the compiler knows, it could be 0. Format specified is "%*s", which we feed maskdigit as width, element_count as argument to print.
If maskdigit is too small, sprintf will not truncate. The result is that for all the compiler knows, the output array could be 10 characters too small (since element_count is unsigned 32bit, 10 digits).
There are similar errors like that:
```
/shared/projects/openjdk/jdk-jdk/source/src/hotspot/share/adlc/output_c.cpp: In function 'void check_peepconstraints(FILE*, FormDict&, PeepMatch*, PeepConstraint*)':
/shared/projects/openjdk/jdk-jdk/source/src/hotspot/share/adlc/output_c.cpp:1171:42: error: '_idx' directive writing 4 bytes into a region of size between 2 and 12 [-Werror=format-overflow=]
1171 | sprintf(left_reg_index,",inst%d_idx%d", (int)left_index, left_op_index);
/shared/projects/openjdk/jdk-jdk/source/src/hotspot/share/adlc/output_c.cpp:1184:45: error: '_idx' directive writing 4 bytes into a region of size between 2 and 12 [-Werror=format-overflow=]
1184 | sprintf(right_reg_index,",inst%d_idx%d", (int)right_index, right_op_index);
```
these are a bit simpler, since they don't have variable sized widths. The compiler just complains about the buffer. Buffer does not allow the parameters to be beyond 9999, which is asserted, but the GCC does not understand this.
- backported by
-
JDK-8312129 Fix GCC 12 warnings for adlc output_c.cpp
- Resolved
-
JDK-8313748 Fix GCC 12 warnings for adlc output_c.cpp
- Resolved
- links to
-
Commit openjdk/jdk17u-dev/a19596d1
-
Commit openjdk/jdk/a8fe2d97
-
Review openjdk/jdk17u-dev/1574
-
Review openjdk/jdk/9335
(1 links to)