Microsoft KB Archive/114074

{|
 * width="100%"|

FIX: Setting Bitfields with /Oe Overwrites Stored BP

 * }

Q114074

6.00 6.00a 7.00 | 6.00 6.00a | 1.00 MS-DOS | OS/2 | WINDOWS kbtool kbfixlist kbbuglist -- The information in this article applies to: - The Microsoft C/C++ Compiler (CL.EXE), included with: - Microsoft C for MS-DOS, versions 6.0, 6.0a, and 6.0ax - Microsoft C for OS/2, versions 6.0 and 6.0a - Microsoft C/C++ for MS-DOS, version 7.0 - Microsoft Visual C++ for Windows, version 1.0 -- SYMPTOMS ======== Returning from a function which modifies bitfields of a global structure causes the system to hang, crash with a memory violation, or execute an invalid instruction. CAUSE ===== Incorrect code can be generated when bitfields of a global structure are modified and /Oe (global register allocation) optimization is used. For the problem to be reproduced, /Gt (data size threshold) must be specified with n less than the size of the global struct. This incorrect code overwrites the value of BP pushed onto the stack on entry into the function. The sample code at the end of this article demonstrates the problem. RESOLUTION ========== There are a few possible ways to work around this problem. - Compile without the /Oe (global register allocation) optimization. Similarly, use #pragma optimize ( "e", off) to turn /Oe optimization off just for the one function. - Compile with /Gt (data size threshold) where n is greater than or equal to the size of the global structure. - Rebuild with Visual C++ 1.5 or later, which corrects this problem. STATUS ====== Microsoft has confirmed this to be a problem in the Microsoft products listed above. This is not a problem in Visual C++, 32-bit Edition. This problem was corrected in Visual C++ version 1.5. Sample Code --- /* Compile options needed: /AL /Oe /Fc /Gt14 Description: This code, when compiled with Microsoft C/C++ compilers previous to version 8.0c and with /Oe, overwrite a stored BP on the line indicated. Without /Oe, the problem does not occur. The printf's do not demonstrate the problem, it is the failure to return from the function call, or examination of the .COD listing, which demonstrates this. */ #include struct test_struct { char *text; int iTest; unsigned unsigned_1:1; unsigned unsigned_2:1; unsigned unsigned_3:1; unsigned unsigned_4:1; unsigned unsigned_5:1; unsigned unsigned_6:1; unsigned unsigned_7:1; unsigned unsigned_8:1; unsigned unsigned_9:1; }; static struct test_struct tst_strct[2]; void oe_error( int iX, char *text, int iTest, int test_1, int test_2, int test_3, int test_4, int test_5, int test_6, int test_7, int test_8, int test_9); void test(void); void main(int argc, char *argv) { int iTest_1; iTest_1 = 10; // The following is needed for creation of a stackframe in main: if(iTest_1+argc < 10) { // will never be reached. test; } test; printf("It should be: iTest_1 = 10\n" ); printf(" It is: iTest_1 = %d\n", iTest_1); } // Take comment off following line to work around problem // #pragma optimize ( "e", off) void test(void) { int iX = 1; oe_error( iX, "TEXT", 5, 1, 1, 1, 1, 0, 0, 0, 0, 0); } void oe_error( int iX, char *text, int iTest, int test_1, int test_2, int test_3, int test_4, int test_5, int test_6, int test_7, int test_8, int test_9) { tst_strct[iX].text = text; tst_strct[iX].iTest = iTest; tst_strct[iX].unsigned_1 = test_1; tst_strct[iX].unsigned_2 = test_2; tst_strct[iX].unsigned_3 = test_3; tst_strct[iX].unsigned_4 = test_4; tst_strct[iX].unsigned_5 = test_5; tst_strct[iX].unsigned_6 = test_6; tst_strct[iX].unsigned_7 = test_7; tst_strct[iX].unsigned_8 = test_8; tst_strct[iX].unsigned_9 = test_9; /* The stored BP is overwritten here */ } // Uncomment for work around // #pragma optimize ("", on) /* The code which causes BP to be overwritten comes immediately after the line tst_strct[iX].unsigned_9 = test_9; in the .COD listing. The problem is that this code does *** 000099 81 c3 06 00 add bx,OFFSET $S175_tst_strct+6 *** 00009d 89 5e fe mov WORD PTR [bp-2],bx >> *** 0000a0 8c 5e 00 mov WORD PTR [bp],ds >> This will overwrite the stored BP, so that BP is not correctly >> retrieved at the end of this function. See the .COD listing produced when compiling for more information. */ Additional reference words: 8.00 1.00 KBCategory: kbtool kbfixlist kbbuglist KBSubcategory: CLIss

Keywords : kb16bitonly kbCompiler

Issue type :

Technology : kbVCsearch kbAudDeveloper kbCVCComp