From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 45DB13858D20; Tue, 19 Sep 2023 22:48:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 45DB13858D20 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1695163731; bh=PmOO32cJGWUEdMCLbdYP6ptmWexUNEwfKwXgfmCNcEI=; h=From:To:Subject:Date:From; b=IFpcro+FrGJym/tMwCTQ1DgE2rDKxvCvnT131QMbE2KsHoBKpyjFqsjdIy5Aoysrx KQfhncrN4hUm+cqjFzu/i0xb38fC2YXA0bktQhYwqyGpnEeK9H/TytZIb+73kp67aK Gps9Gdod9HqofczwnSe2oLcB39UKZtWDePzGiO8A= From: "jonathan.leffler at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug c/111489] New: Incorrect "-Wmaybe-uninitialized" warning from GCC 13.2.0 Date: Tue, 19 Sep 2023 22:48:25 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c X-Bugzilla-Version: 13.2.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: jonathan.leffler at gmail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D111489 Bug ID: 111489 Summary: Incorrect "-Wmaybe-uninitialized" warning from GCC 13.2.0 Product: gcc Version: 13.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: jonathan.leffler at gmail dot com Target Milestone: --- The problem occurs with GCC 13.2.0, and the submitted code also produces the warning in GCC 12.2.0, but minor variations on the code tested while reduci= ng the production code did not always reproduce with 12 even though it did with 13. I also tested versions 7.3.0, 8.2.0, 9.3.0, 10.3.0, 11.2.0; none of them produced the warning for me. I'm not clear if this is a regression in 13 (= and 12), or whether the older versions are oblivious to the and 12 and 13 are trying to spot a problem but not recognizing why there isn't a problem in t= he code. The gist of the problem is that a variable is defined but not initialized immediately: uint16_t pg_version; =E2=80=A6 if (flags =3D=3D PGR_VERSION) pg_version =3D GET_PGVERS(pg_old); =E2=80=A6 for (=E2=80=A6) { =E2=80=A6 if (flags =3D=3D PGR_VERSION) { cur_rowid =3D ROWID(PAGE(sav_rowid), i, PT_BIGRID(cur_partp)); pg_expand(GET_SLOTPTR(pg_old, old_slot), row_data, pg_version); } } GCC complains that pg_version may be used uninitialized, but pg_value is on= ly used in the loop body if the condition that assigned it a value outside the loop applies inside the body too. The workaround is simple: initialize pg_version to 0 when it is defined. Compiler information: Using built-in specs. COLLECT_GCC=3Dgcc Target: x86_64-pc-linux-gnu Configured with: ../gcc-13.2.0/configure --prefix=3D/usr/gcc/v13.2.0 CC=3D/usr/gcc/v12.2.0/bin/gcc CXX=3D/usr/gcc/v12.2.0/bin/g++ Thread model: posix Supported LTO compression algorithms: zlib gcc version 13.2.0 (GCC)=20 Command line: gcc -std=3Dc18 -O3 -Wall -Wextra -Werror -save-temps -v -c -o gcc-bug.o gcc= -bug.c Compilation output: Using built-in specs. COLLECT_GCC=3Dgcc Target: x86_64-pc-linux-gnu Configured with: ../gcc-13.2.0/configure --prefix=3D/usr/gcc/v13.2.0 CC=3D/usr/gcc/v12.2.0/bin/gcc CXX=3D/usr/gcc/v12.2.0/bin/g++ Thread model: posix Supported LTO compression algorithms: zlib gcc version 13.2.0 (GCC)=20 COLLECT_GCC_OPTIONS=3D'-std=3Dc17' '-O3' '-Wall' '-Wextra' '-Werror' '-save= -temps' '-v' '-c' '-o' 'gcc-bug.o' '-mtune=3Dgeneric' '-march=3Dx86-64' /work1/gcc/v13.2.0/bin/../libexec/gcc/x86_64-pc-linux-gnu/13.2.0/cc1 -E -q= uiet -v -iprefix /work1/gcc/v13.2.0/bin/../lib/gcc/x86_64-pc-linux-gnu/13.2.0/ gcc-bug.c -mtune=3Dgeneric -march=3Dx86-64 -std=3Dc17 -Wall -Wextra -Werror= -O3 -fpch-preprocess -o gcc-bug.i ignoring nonexistent directory "/work1/gcc/v13.2.0/bin/../lib/gcc/x86_64-pc-linux-gnu/13.2.0/../../../../x= 86_64-pc-linux-gnu/include" ignoring duplicate directory "/work1/gcc/v13.2.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/13.2.0= /include" ignoring duplicate directory "/work1/gcc/v13.2.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/13.2.0= /include-fixed" ignoring nonexistent directory "/work1/gcc/v13.2.0/bin/../lib/gcc/../../lib/gcc/x86_64-pc-linux-gnu/13.2.0= /../../../../x86_64-pc-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /work1/gcc/v13.2.0/bin/../lib/gcc/x86_64-pc-linux-gnu/13.2.0/include /work1/gcc/v13.2.0/bin/../lib/gcc/x86_64-pc-linux-gnu/13.2.0/include-fixed /usr/local/include /work1/gcc/v13.2.0/bin/../lib/gcc/../../include /usr/include End of search list. COLLECT_GCC_OPTIONS=3D'-std=3Dc17' '-O3' '-Wall' '-Wextra' '-Werror' '-save= -temps' '-v' '-c' '-o' 'gcc-bug.o' '-mtune=3Dgeneric' '-march=3Dx86-64' /work1/gcc/v13.2.0/bin/../libexec/gcc/x86_64-pc-linux-gnu/13.2.0/cc1 -fpreprocessed gcc-bug.i -quiet -dumpbase gcc-bug.c -dumpbase-ext .c -mtune=3Dgeneric -march=3Dx86-64 -O3 -Wall -Wextra -Werror -std=3Dc17 -vers= ion -o gcc-bug.s GNU C17 (GCC) version 13.2.0 (x86_64-pc-linux-gnu) compiled by GNU C version 13.2.0, GMP version 6.3.0, MPFR version 4.2.0, MPC version 1.3.1, isl version isl-0.24-GMP GGC heuristics: --param ggc-min-expand=3D100 --param ggc-min-heapsize=3D131= 072 Compiler executable checksum: 76c675c9da56a319124364c69f2f4d48 gcc-bug.c: In function =E2=80=98pg_reorg=E2=80=99: gcc-bug.c:186:13: error: =E2=80=98pg_version=E2=80=99 may be used uninitial= ized [-Werror=3Dmaybe-uninitialized] 186 | pg_expand(GET_SLOTPTR(pg_old, old_slot), row_data, pg_version); |=20=20=20=20=20=20=20=20=20=20=20=20 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~=20=20=20=20= =20=20=20=20=20=20=20=20=20=20=20=20=20 gcc-bug.c:141:14: note: =E2=80=98pg_version=E2=80=99 was declared here 141 | uint16_t pg_version; | ^~~~~~~~~~ cc1: all warnings being treated as errors The code is as reduced as I could make it, but not as minimal as I'd like. = It does not use any headers; I copied definitions for size_t and [u]intN_t from and to the top of the file (before it was compiled).= =20 There is a horrendous collection of macros building up the expressions. # 0 "gcc-bug.c" # 0 "" # 0 "" # 1 "/usr/include/stdc-predef.h" 1 3 4 # 0 "" 2 # 1 "gcc-bug.c" typedef long unsigned int size_t; typedef short int int16_t; typedef int int32_t; typedef long int int64_t; typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; typedef unsigned long int uint64_t; typedef struct { uint16_t pgv1_size; uint16_t pgv1_flags1; uint16_t pgv1_flags2; uint16_t pgv1_flags3; uint16_t pgv1_nslots; uint32_t pgv1_generic; } page_v1_t; typedef struct { page_v1_t pgv2_hdr; int64_t pgv2_next; int64_t pgv2_prev; } page_v2_t; typedef struct { union { struct { uint16_t pgv0_size; uint16_t pgv0_flags; }; uint32_t pgv0_nslots; }; uint32_t pgv0_mode; uint32_t pgv0_next; } page_v0_t; typedef struct { uint16_t sl4_off; uint16_t sl4_len; } slot4_t; typedef struct { uint32_t sl8_off; uint32_t sl8_len; } slot8_t; # 132 "gcc-bug.c" extern int64_t cur_rowid; extern uint8_t *pg_alloc(size_t pg_size); extern void mem_move(void *dst, const void *src, size_t len); extern void pg_expand(uint8_t *row_in, uint8_t *row_out, uint16_t pg_versio= n); extern void pg_reorg(uint32_t flags, uint8_t *pg_old, uint16_t slotnum, uin= t8_t *row_data, uint64_t cur_partp); void pg_reorg(uint32_t flags, uint8_t *pg_old, uint16_t slotnum, uint8_t *row_data, uint64_t cur_partp) { uint16_t pg_version; size_t pg_size =3D ((((page_v1_t *)(pg_old))->pgv1_flags3 =3D=3D 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))); uint8_t *pg_new =3D pg_alloc(pg_size); uint8_t *old_slot =3D ((((((page_v1_t *)(pg_old))->pgv1_flags3 =3D=3D 3= ) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? (&(pg_old)[((((page_v1_t *)(pg_old))->pgv1_flags3 =3D=3D 3) ? (((page_v1_t *)(pg_old))->pgv1_size*10= 24) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) - sizeof(int64_t) - (1*sizeof(slot8_t))]) : ((((page_v0_t *)(pg_old))->pgv0_m= ode & 1) ? (&(pg_old)[((((page_v1_t *)(pg_old))->pgv1_flags3 =3D=3D 3) ? (((pag= e_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) - sizeof(int64_t) - (1*sizeof(slot4_t))]= ) : (&(pg_old)[((((page_v1_t *)(pg_old))->pgv1_flags3 =3D=3D 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) - sizeof(int32_t) - (1*sizeof(slot4_t))]= ))); uint8_t *new_slot =3D ((((((page_v1_t *)(pg_new))->pgv1_flags3 =3D=3D 3= ) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (&(pg_new)[((((page_v1_t *)(pg_new))->pgv1_flags3 =3D=3D 3) ? (((page_v1_t *)(pg_new))->pgv1_size*10= 24) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) - sizeof(int64_t) - (1*sizeof(slot8_t))]) : ((((page_v0_t *)(pg_new))->pgv0_m= ode & 1) ? (&(pg_new)[((((page_v1_t *)(pg_new))->pgv1_flags3 =3D=3D 3) ? (((pag= e_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) - sizeof(int64_t) - (1*sizeof(slot4_t))]= ) : (&(pg_new)[((((page_v1_t *)(pg_new))->pgv1_flags3 =3D=3D 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) - sizeof(int32_t) - (1*sizeof(slot4_t))]= ))); if (flags =3D=3D 2) { pg_version =3D ((((page_v1_t *)(pg_old))->pgv1_flags3 =3D=3D 3) ? (((page_v1_t *)(pg_old))->pgv1_generic >> 24) : ((uint32_t)((page_v0_t *)(pg_old))->pgv0_next >> 24)); } int64_t sav_rowid =3D cur_rowid; for (uint16_t i =3D 1; i <=3D ((((page_v1_t *)(pg_old))->pgv1_flags3 = =3D=3D 3) ? (((page_v1_t *)(pg_old))->pgv1_nslots) : (((page_v0_t *)(pg_old))->pgv0_nslots)); i++, (old_slot -=3D ((((((page_v1_t *)(pg_old))->pgv1_flags3 =3D=3D 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? sizeof(slot8_t) : sizeof(slot4_t))), (new_slot -=3D ((((((page_v1_t *)(pg_new))->pgv1_flags3 = =3D=3D 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v= 0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? sizeof(slot8_t) : sizeof(slot4_t)))) { size_t length; if (flags =3D=3D 1 && (slotnum =3D=3D 0 || i =3D=3D slotnum)) { uint16_t slotlen =3D ((((((page_v1_t *)(pg_old))->pgv1_flags3 = =3D=3D 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(old_slot))->sl8_len & 0x000FFFFF) : (((slot4_t *)(old_slot))->sl4_len & 0x3FFF)); ((((((page_v1_t *)(pg_new))->pgv1_flags3 =3D=3D 3) ? (((page_v1= _t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(new_slot))->sl8_len =3D (((((((page_v1_t *)(pg_new))->pgv1_flags3 =3D=3D= 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(new_slot))->sl8_len & 0xFFF00000) : (((slot4_t *)(new_slot))->sl4_len & 0xC000)) | ((slotlen) & 0x000FFFFF))) : (((slot4_t *)(new_slot))->sl4_len = =3D (((((((page_v1_t *)(pg_new))->pgv1_flags3 =3D=3D 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(new_slot))->sl8_len & 0xFFF00000) : (((slot4_t *)(new_slot))->sl4_len & 0xC000)) | ((slotlen) & 0x3FFF)))); length =3D ((((((page_v1_t *)(pg_old))->pgv1_flags3 =3D=3D 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(old_slot))->sl8_len & 0x000FFFFF) : (((slot4_t *)(old_slot))->sl4_len & 0x3FFF)); } else { length =3D ((((((page_v1_t *)(pg_old))->pgv1_flags3 =3D=3D 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(old_slot))->sl8_len & 0x000FFFFF) : (((slot4_t *)(old_slot))->sl4_len & 0x3FFF)); ((((((page_v1_t *)(pg_new))->pgv1_flags3 =3D=3D 3) ? (((page_v1= _t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(new_slot))->sl8_len =3D (((((((page_v1_t *)(pg_new))->pgv1_flags3 =3D=3D= 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(new_slot))->sl8_len & 0xFFF00000) : (((slot4_t *)(new_slot))->sl4_len & 0xC000)) | ((length) & 0x000FFFFF))) : (((slot4_t *)(new_slot))->sl4_len =3D (((((((page_v1_t *)(pg_new))->pgv1_flags3 =3D=3D 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)(new_slot))->sl8_len & 0xFFF00000) : (((slot4_t *)(new_slot))->sl4_len & 0xC000)) | ((length) & 0x3FFF)))); } if (((((((page_v1_t *)(pg_old))->pgv1_flags3 =3D=3D 3) ? (((page_v1= _t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)old_slot)->sl8_= off) : (((slot4_t *)old_slot)->sl4_off)) =3D=3D 0) { ((((((page_v1_t *)(pg_new))->pgv1_flags3 =3D=3D 3) ? (((page_v1= _t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)new_slot)->sl8_= off =3D (0)) : (((slot4_t *)new_slot)->sl4_off =3D (0))); continue; } ((((((page_v1_t *)(pg_new))->pgv1_flags3 =3D=3D 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((slot8_t *)new_slot)->sl8_= off =3D (0)) : (((slot4_t *)new_slot)->sl4_off =3D (0))); if (flags =3D=3D 2) { cur_rowid =3D (((((cur_partp) & 0x400000000) ? 1 : 0)) ? (uint64_t)(((((int64_t)((((uint64_t)(sav_rowid) & ((uint64_t)1 << 63)) ? (int64_t)(((sav_rowid) & 0x7FFFFFFFFFFF0000) >> 16) : (int64_t)(((sav_rowid= ) & 0xFFFFFF00) >> 8)))) << 16) + (i)) | ((uint64_t)1 << 63)) : (uint64_t)((((int32_t)((((uint64_t)(sav_rowid) & ((uint64_t)1 << 63)) ? (int64_t)(((sav_rowid) & 0x7FFFFFFFFFFF0000) >> 16) : (int64_t)(((sav_rowid= ) & 0xFFFFFF00) >> 8)))) << 8) + (i))); pg_expand(((((((page_v1_t *)(pg_old))->pgv1_flags3 =3D=3D 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? (((uint8_t*)(pg_old)) + ((slot8_t *)old_slot)->sl8_off) : (((uint8_t*)(pg_old)) + ((slot4_t *)old_slot)->sl4_off)), row_data, pg_version); } else { mem_move(((((((page_v1_t *)(pg_new))->pgv1_flags3 =3D=3D 3) ? (((page_v1_t *)(pg_new))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_new))->pgv0_size & 0xF800))) > 0x4000) ? (((uint8_t*)(pg_new)) + ((slot8_t *)new_slot)->sl8_off) : (((uint8_t*)(pg_new)) + ((slot4_t *)new_slot)->sl4_off)), ((((((page_v1_t *)(pg_old))->pgv1_flags3 =3D=3D 3) ? (((page_v1_t *)(pg_old))->pgv1_size*1024) : (uint16_t)(0x0800 + (((page_v0_t *)(pg_old))->pgv0_size & 0xF800))) > 0x4000) ? (((uint8_t*)(pg_old)) + ((slot8_t *)old_slot)->sl8_off) : (((uint8_t*)(pg_old)) + ((slot4_t *)old_slot)->sl4_off)), length); } } } This is the unpreprocessed source code. It contains some comments about wh= at cannot be removed without the warning going away. /* Relevant parts of and */ typedef long unsigned int size_t; typedef short int int16_t; typedef int int32_t; typedef long int int64_t; typedef unsigned char uint8_t; typedef unsigned short int uint16_t; typedef unsigned int uint32_t; typedef unsigned long int uint64_t; typedef struct { uint16_t pgv1_size; uint16_t pgv1_flags1; uint16_t pgv1_flags2; uint16_t pgv1_flags3; uint16_t pgv1_nslots; uint32_t pgv1_generic; } page_v1_t; typedef struct { page_v1_t pgv2_hdr; int64_t pgv2_next; int64_t pgv2_prev; } page_v2_t; typedef struct { union { struct { uint16_t pgv0_size; uint16_t pgv0_flags; }; uint32_t pgv0_nslots; }; uint32_t pgv0_mode; uint32_t pgv0_next; } page_v0_t; typedef struct { uint16_t sl4_off; uint16_t sl4_len; } slot4_t; typedef struct { uint32_t sl8_off; uint32_t sl8_len; } slot8_t; #define PG_EXTENDED 0x10000 #define PGMD_8BTS 1 #define SL4_MASK 0xC000 #define SL4_LENG 0x3FFF #define SL8_MASK 0xFFF00000 #define SL8_LENG 0x000FFFFF #define PGR_SLOTSZ 1 #define PGR_VERSION 2 #define BIGRID_BIT ((uint64_t)1 << 63) #define TST_PGTHREE(p) (((page_v1_t *)(p))->pgv1_flags3 =3D=3D 3) #define GET_PGSIZE(pg) (TST_PGTHREE(pg) ? \ (((page_v1_t *)(pg))->pgv1_size*1024) : \ (uint16_t)(0x0800 + (((page_v0_t *)(pg))->pgv0_si= ze & 0xF800))) #define GET_PGFLAGS(pg) (TST_PGTHREE(pg) ? \ ((uint32_t)(((page_v1_t *)(pg))->pgv1_flags1) | \ (uint32_t)(((page_v1_t *)(pg))->pgv1_flags2 << 16)= ) : \ (uint32_t)(((page_v0_t *)(pg))->pgv0_flags)) #define GET_PGNSLOTS(pg) (TST_PGTHREE(pg) ? \ (((page_v1_t *)(pg))->pgv1_nslots) : \ (((page_v0_t *)(pg))->pgv0_nslots)) #define GET_PGVERS(pg) (TST_PGTHREE(pg) ? \ (((page_v1_t *)(pg))->pgv1_generic >> 24) : \ ((uint32_t)((page_v0_t *)(pg))->pgv0_next >> 24)) #define PG_LRGSLTS(p) (GET_PGSIZE(p) > 0x4000) #define GET_SLOT_T_SIZE(p) \ (PG_LRGSLTS(p) ? sizeof(slot8_t) : sizeof(slot4_t)) #define GET_SLOTLEN(p, s) (PG_LRGSLTS(p) ? \ (((slot8_t *)(s))->sl8_len & SL8_LENG) : \ (((slot4_t *)(s))->sl4_len & SL4_LENG)) #define GET_SLOTFLGS(p, s) (PG_LRGSLTS(p) ? \ (((slot8_t *)(s))->sl8_len & SL8_MASK) : \ (((slot4_t *)(s))->sl4_len & SL4_MASK)) #define SET_SLOTLEN(p, s, l) \ (PG_LRGSLTS(p) ? \ (((slot8_t *)(s))->sl8_len =3D (GET_SLOTFLGS(p, s) | ((l) & SL8_LE= NG))) : \ (((slot4_t *)(s))->sl4_len =3D (GET_SLOTFLGS(p, s) | ((l) & SL4_LE= NG)))) #define GET_SLOTTAB(p, i) (PG_LRGSLTS(p) ? \ (&(p)[GET_PGSIZE(p) - sizeof(int64_t) - (i*sizeof(slot8_t))]) : \ ((((page_v0_t *)(p))->pgv0_mode & PGMD_8BTS) ? \ (&(p)[GET_PGSIZE(p) - sizeof(int64_t) - (i*sizeof(slot4_t))]) : \ (&(p)[GET_PGSIZE(p) - sizeof(int32_t) - (i*sizeof(slot4_t))]))) #define DEC_SLOTTAB(p, s) (s -=3D GET_SLOT_T_SIZE(p)) #define GET_SLOTPTR(p, s) (PG_LRGSLTS(p) ? \ (((uint8_t*)(p)) + ((slot8_t *)s)->sl8_off) : \ (((uint8_t*)(p)) + ((slot4_t *)s)->sl4_off)) #define GET_SLOTOFF(p, s) (PG_LRGSLTS(p) ? \ (((slot8_t *)s)->sl8_off) : \ (((slot4_t *)s)->sl4_off)) #define SET_SLOTOFF(p, s, n) (PG_LRGSLTS(p) ? \ (((slot8_t *)s)->sl8_off =3D (n)) : \ (((slot4_t *)s)->sl4_off =3D (n))) #define PAGE(r) \ (((uint64_t)(r) & BIGRID_BIT) ? (int64_t)(((r) & 0x7FFFFFFFFFFF0000) >>= 16) : \ (int64_t)(((r) & 0xFFFFFF00) >> 8)) #define ROWID(p, s, br) \ ((br) ? (uint64_t)(((((int64_t)(p)) << 16) + (s)) | BIGRID_BIT) : \ (uint64_t)((((int32_t)(p)) << 8) + (s))) #define PT_BIGRID(pt) (((pt) & 0x400000000) ? 1 : 0) extern int64_t cur_rowid; extern uint8_t *pg_alloc(size_t pg_size); extern void mem_move(void *dst, const void *src, size_t len); extern void pg_expand(uint8_t *row_in, uint8_t *row_out, uint16_t pg_versio= n); extern void pg_reorg(uint32_t flags, uint8_t *pg_old, uint16_t slotnum, uin= t8_t *row_data, uint64_t cur_partp); void pg_reorg(uint32_t flags, uint8_t *pg_old, uint16_t slotnum, uint8_t *row_data, uint64_t cur_partp) { uint16_t pg_version; size_t pg_size =3D GET_PGSIZE(pg_old); uint8_t *pg_new =3D pg_alloc(pg_size); uint8_t *old_slot =3D GET_SLOTTAB(pg_old, 1); uint8_t *new_slot =3D GET_SLOTTAB(pg_new, 1); if (flags =3D=3D PGR_VERSION) { /* This invocation of GET_PGVERS is needed */ pg_version =3D GET_PGVERS(pg_old); } int64_t sav_rowid =3D cur_rowid; /* The invocations of DEC_SLOTTAB are needed */ for (uint16_t i =3D 1; i <=3D GET_PGNSLOTS(pg_old); i++, DEC_SLOTTAB(pg_old, old_slot), DEC_SLOTTAB(pg_new, new_slot)) { size_t length; /* Some of this paragraph is needed */ if (flags =3D=3D PGR_SLOTSZ && (slotnum =3D=3D 0 || i =3D=3D slotnu= m)) { uint16_t slotlen =3D GET_SLOTLEN(pg_old, old_slot); SET_SLOTLEN(pg_new, new_slot, slotlen); length =3D GET_SLOTLEN(pg_old, old_slot); } else { length =3D GET_SLOTLEN(pg_old, old_slot); SET_SLOTLEN(pg_new, new_slot, length); } /* Both the GET and the SET are needed */ if (GET_SLOTOFF(pg_old, old_slot) =3D=3D 0) { SET_SLOTOFF(pg_new, new_slot, 0); continue; } /* This SET is needed */ SET_SLOTOFF(pg_new, new_slot, 0); if (flags =3D=3D PGR_VERSION) { cur_rowid =3D ROWID(PAGE(sav_rowid), i, PT_BIGRID(cur_partp)); pg_expand(GET_SLOTPTR(pg_old, old_slot), row_data, pg_version); } else { /* This else clause and a call using the macros is needed */ mem_move(GET_SLOTPTR(pg_new, new_slot), GET_SLOTPTR(pg_old, old_slot), length); } } } I was presented with bugs 60350, 64717, 69537, 86058, 102801, 107140, 11224= 0 as possible duplicates. 60350 is not relevant (the line numbers are reported correctly in this code); the other 5-digit bugs are 'resolved fixed', as is 102801. Neither 107140 nor 111240 seems relevant.=