diff options
author | Sirui Mu <msrlancern@gmail.com> | 2025-08-28 21:48:24 +0800 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2025-08-29 21:51:29 +0200 |
commit | 78d19ea3fea308a08d2844de88d43154465daa78 (patch) | |
tree | 6a560271ace9c3b765e9fda3dd461f467d136149 /libjava | |
parent | 9e98b37f32f8bff72885904fc66ea7ec8fefec58 (diff) | |
download | gcc-78d19ea3fea308a08d2844de88d43154465daa78.zip gcc-78d19ea3fea308a08d2844de88d43154465daa78.tar.gz gcc-78d19ea3fea308a08d2844de88d43154465daa78.tar.bz2 |
c++: array subscript with COND_EXPR as the array
The following minimum reproducer would miscompile with vanilla gcc:
extern int x[10], y[10];
bool g();
void f() { 0[g() ? x : y] = 1; }
gcc would mistakenly treat the subexpression (g() ? x : y) as a prvalue and
move that array to stack. The following assignment would then write to the
stack instead of to the global arrays. When optimizations are enabled, this
assignment is discarded by dse and gcc generates the following code for the
f function:
"_Z1fi":
jmp "_Z1gv"
The miscompilation requires all the following conditions to be met:
- The array subscription expression is written as idx[array], instead of
the usual form array[idx];
- The "array" part must be a ternary expression (COND_EXPR in gcc tree)
and it must be an lvalue.
- The code must be compiled with -fstrong-eval-order which is the default
for -std=c++17 or later.
The cause of the issue lies in cp_build_array_ref, where it mistakenly
generates a COND_EXPR with ARRAY_TYPE to the IL when all the criteria above
are met. This patch tries to resolve this issue. It moves the
canonicalization step that transforms idx[array] to array[idx] early in
cp_build_array_ref to ensure we handle these two forms of array subscription
consistently.
Tested on x86_64-linux.
gcc/cp/ChangeLog:
* typeck.cc (cp_build_array_ref): Handle 0[arr] earlier.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1z/array-condition-expr.C: New test.
Signed-off-by: Sirui Mu <msrlancern@gmail.com>
Diffstat (limited to 'libjava')
0 files changed, 0 insertions, 0 deletions