* VariablePolicy: Final Changes Thread 2 - ECC & UnitTest @ 2020-10-07 0:28 Bret Barkelew 2020-10-07 1:46 ` Michael D Kinney 0 siblings, 1 reply; 9+ messages in thread From: Bret Barkelew @ 2020-10-07 0:28 UTC (permalink / raw) To: devel@edk2.groups.io [-- Attachment #1: Type: text/plain, Size: 1162 bytes --] I’ve worked through all the ECC issues with Variable Policy (AND the UnitTests) on this branch: Commits · corthon/edk2 (github.com)<https://github.com/corthon/edk2/commits/var_policy_dev_submission_v8> I even wrote the Main() entry point lib that Laszlo suggested (it works rather nicely): TEMP: Staging for HostTest entry point · corthon/edk2@4ce5210 (github.com)<https://github.com/corthon/edk2/commit/4ce52108b3e1bcb2ba78995be94c3949fe647eda> However, there’s one that I just can’t get past and I would like to take it up with the community. I don’t think that UnitTests should have to deal with the “can’t initialize variables in declaration” check. Almost none of the solutions that I tested worked, and the ones that did were too cumbersome. They failed on two key points that are important for test writing: * They were annoying to write ===> fewer tests. * They moved even more of the test case data away from the test ===> harder to read tests. I would like to move for an exception for unit tests (or at least host-based unit tests), but I don’t know how to accomplish that from a technical standpoint. Thoughts? - Bret [-- Attachment #2: Type: text/html, Size: 5456 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: VariablePolicy: Final Changes Thread 2 - ECC & UnitTest 2020-10-07 0:28 VariablePolicy: Final Changes Thread 2 - ECC & UnitTest Bret Barkelew @ 2020-10-07 1:46 ` Michael D Kinney 2020-10-07 13:42 ` [edk2-devel] " Laszlo Ersek 0 siblings, 1 reply; 9+ messages in thread From: Michael D Kinney @ 2020-10-07 1:46 UTC (permalink / raw) To: devel@edk2.groups.io, bret.barkelew@microsoft.com, Kinney, Michael D [-- Attachment #1: Type: text/plain, Size: 2319 bytes --] Bret, Initializing variable in declaration for structures and arrays introduces use of intrinsics. Since it is possible for unit test sources to be used for both host and target tests, I recommend we continue to follow the EDK II coding style for unit tests to support maximum compatibility and code reuse. Using a module global variable with initializers instead of initializing a local declaration is the same amount of work, so I do not believe that will result in fewer tests. I agree it is useful to have the test data next to the test code. This can be accomplished by breaking up into more files so the test data is immediately above the test function the test data is used. Does ECC raise an error if a module global is placed between 2 functions? A 2nd approach to put the module global immediately above the test function the test data is used. Best regards, Mike From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bret Barkelew via groups.io Sent: Tuesday, October 6, 2020 5:28 PM To: devel@edk2.groups.io Subject: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest I’ve worked through all the ECC issues with Variable Policy (AND the UnitTests) on this branch: Commits · corthon/edk2 (github.com)<https://github.com/corthon/edk2/commits/var_policy_dev_submission_v8> I even wrote the Main() entry point lib that Laszlo suggested (it works rather nicely): TEMP: Staging for HostTest entry point · corthon/edk2@4ce5210 (github.com)<https://github.com/corthon/edk2/commit/4ce52108b3e1bcb2ba78995be94c3949fe647eda> However, there’s one that I just can’t get past and I would like to take it up with the community. I don’t think that UnitTests should have to deal with the “can’t initialize variables in declaration” check. Almost none of the solutions that I tested worked, and the ones that did were too cumbersome. They failed on two key points that are important for test writing: * They were annoying to write ===> fewer tests. * They moved even more of the test case data away from the test ===> harder to read tests. I would like to move for an exception for unit tests (or at least host-based unit tests), but I don’t know how to accomplish that from a technical standpoint. Thoughts? - Bret [-- Attachment #2: Type: text/html, Size: 47953 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest 2020-10-07 1:46 ` Michael D Kinney @ 2020-10-07 13:42 ` Laszlo Ersek 2020-10-07 14:27 ` Andrew Fish 2020-10-07 16:24 ` Michael D Kinney 0 siblings, 2 replies; 9+ messages in thread From: Laszlo Ersek @ 2020-10-07 13:42 UTC (permalink / raw) To: devel, michael.d.kinney, Bret Barkelew On 10/07/20 03:46, Michael D Kinney wrote: > > Bret, > > Initializing variable in declaration for structures and arrays > introduces use of intrinsics. Since it is possible for unit test > sources to be used for both host and target tests, I recommend we > continue to follow the EDK II coding style for unit tests to support > maximum compatibility and code reuse. > > Using a module global variable with initializers instead of > initializing a local declaration is the same amount of work, so I do > not believe that will result in fewer tests. > > I agree it is useful to have the test data next to the test code. This > can be accomplished by breaking up into more files so the test data is > immediately above the test function the test data is used. Does ECC > raise an error if a module global is placed between 2 functions? A > 2nd approach to put the module global immediately above the test > function the test data is used. Consider the following example structure type, for the sake of discussion: typedef struct { UINT32 Value; } TEST_DATA; * Case#1: block scope, automatic storage duration EFI_STATUS FoobarTest ( VOID ) { TEST_DATA TestData = { 42 }; // ... } Problem: uses intrinsics. * Case#2: file scope, static storage duration. STATIC CONST TEST_DATA mTestData = { 42 }; EFI_STATUS FoobarTest ( VOID ) { // ... } Problem: either "mTestData" is textually far from FoobarTest(), or -- if we keep them close to each other -- we mix variable definitions with function definitions, at file scope. * Case #3: block scope, static storage duration. EFI_STATUS FoobarTest ( VOID ) { STATIC CONST TEST_DATA TestData = { 42 }; // ... } Problem: there should be none. Does not involve intrinsics, and the object definition is part of the function's scope. If ECC does not recognize case#3 as valid, then that is an *ECC bug*. ECC has no reason to prevent case#3, as case#3 does not involve intrinsics, and is a generally valid and useful C language construct (it combines the life cycle of case#2 with the visibility of case#1). Again, if ECC rejects case#3, that's *definitely* a bug in ECC, and we should fix it first. Given that ECC includes a full-blown C language parser, the fix should not be too difficult -- check if the declaration has the "static" storage-class specifier. ... In fact, I think that purely CONST-qualifying TestData might suffice for shutting up ECC. See the following in "BaseTools/Source/Python/Ecc/c.py", method "CheckFuncLayoutLocalVariable": > for Result in ResultSet: > if len(Result[1]) > 0 and 'CONST' not in Result[3]: > PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2]) So case#3 should work through that avenue already, because case#3 has CONST *too*. Now, in case#3, if "TestData" needs to undergo modifications, and so CONST is not immediately desirable, that's solvable: EFI_STATUS FoobarTest ( VOID ) { STATIC CONST TEST_DATA TestDataTemplate = { 42 }; TEST_DATA TestData; CopyMem (&TestData, TestDataTemplate, sizeof (TEST_DATA)); // ... } Thanks Laszlo > > Best regards, > > Mike > > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bret Barkelew via groups.io > Sent: Tuesday, October 6, 2020 5:28 PM > To: devel@edk2.groups.io > Subject: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest > > I\x19ve worked through all the ECC issues with Variable Policy (AND the UnitTests) on this branch: > Commits · corthon/edk2 (github.com)<https://github.com/corthon/edk2/commits/var_policy_dev_submission_v8> > > I even wrote the Main() entry point lib that Laszlo suggested (it works rather nicely): > TEMP: Staging for HostTest entry point · corthon/edk2@4ce5210 (github.com)<https://github.com/corthon/edk2/commit/4ce52108b3e1bcb2ba78995be94c3949fe647eda> > > However, there\x19s one that I just can\x19t get past and I would like to take it up with the community. I don\x19t think that UnitTests should have to deal with the \x1ccan\x19t initialize variables in declaration\x1d check. Almost none of the solutions that I tested worked, and the ones that did were too cumbersome. They failed on two key points that are important for test writing: > > * They were annoying to write ===> fewer tests. > * They moved even more of the test case data away from the test ===> harder to read tests. > > I would like to move for an exception for unit tests (or at least host-based unit tests), but I don\x19t know how to accomplish that from a technical standpoint. > > Thoughts? > > - Bret > > > > > > > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest 2020-10-07 13:42 ` [edk2-devel] " Laszlo Ersek @ 2020-10-07 14:27 ` Andrew Fish 2020-10-07 15:50 ` Laszlo Ersek 2020-10-07 16:24 ` Michael D Kinney 1 sibling, 1 reply; 9+ messages in thread From: Andrew Fish @ 2020-10-07 14:27 UTC (permalink / raw) To: devel, lersek; +Cc: michael.d.kinney, Bret Barkelew For case 1 I thought the size had to be > 8 bytes, not just a struct? Maybe that is compiler specific? > On Oct 7, 2020, at 6:43 AM, Laszlo Ersek <lersek@redhat.com> wrote: > > On 10/07/20 03:46, Michael D Kinney wrote: >> >> Bret, >> >> Initializing variable in declaration for structures and arrays >> introduces use of intrinsics. Since it is possible for unit test >> sources to be used for both host and target tests, I recommend we >> continue to follow the EDK II coding style for unit tests to support >> maximum compatibility and code reuse. >> >> Using a module global variable with initializers instead of >> initializing a local declaration is the same amount of work, so I do >> not believe that will result in fewer tests. >> >> I agree it is useful to have the test data next to the test code. This >> can be accomplished by breaking up into more files so the test data is >> immediately above the test function the test data is used. Does ECC >> raise an error if a module global is placed between 2 functions? A >> 2nd approach to put the module global immediately above the test >> function the test data is used. > > Consider the following example structure type, for the sake of > discussion: > > typedef struct { > UINT32 Value; > } TEST_DATA; > > > * Case#1: block scope, automatic storage duration > > EFI_STATUS > FoobarTest ( > VOID > ) > { > TEST_DATA TestData = { 42 }; > // ... > } > > Problem: uses intrinsics. > > > * Case#2: file scope, static storage duration. > > STATIC CONST TEST_DATA mTestData = { 42 }; > > EFI_STATUS > FoobarTest ( > VOID > ) > { > // ... > } > > Problem: either "mTestData" is textually far from FoobarTest(), or -- if > we keep them close to each other -- we mix variable definitions with > function definitions, at file scope. > > > * Case #3: block scope, static storage duration. > > EFI_STATUS > FoobarTest ( > VOID > ) > { > STATIC CONST TEST_DATA TestData = { 42 }; > // ... > } > > Problem: there should be none. Does not involve intrinsics, and the > object definition is part of the function's scope. > > > If ECC does not recognize case#3 as valid, then that is an *ECC bug*. > > ECC has no reason to prevent case#3, as case#3 does not involve > intrinsics, and is a generally valid and useful C language construct (it > combines the life cycle of case#2 with the visibility of case#1). > > Again, if ECC rejects case#3, that's *definitely* a bug in ECC, and we > should fix it first. Given that ECC includes a full-blown C language > parser, the fix should not be too difficult -- check if the declaration > has the "static" storage-class specifier. > > ... In fact, I think that purely CONST-qualifying TestData might suffice > for shutting up ECC. See the following in > "BaseTools/Source/Python/Ecc/c.py", method > "CheckFuncLayoutLocalVariable": > >> for Result in ResultSet: >> if len(Result[1]) > 0 and 'CONST' not in Result[3]: >> PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2]) > > So case#3 should work through that avenue already, because case#3 has > CONST *too*. > > Now, in case#3, if "TestData" needs to undergo modifications, and so > CONST is not immediately desirable, that's solvable: > > EFI_STATUS > FoobarTest ( > VOID > ) > { > STATIC CONST TEST_DATA TestDataTemplate = { 42 }; > TEST_DATA TestData; > > CopyMem (&TestData, TestDataTemplate, sizeof (TEST_DATA)); > // ... > } > > Thanks > Laszlo > >> >> Best regards, >> >> Mike >> >> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bret Barkelew via groups.io >> Sent: Tuesday, October 6, 2020 5:28 PM >> To: devel@edk2.groups.io >> Subject: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest >> >> I\x19ve worked through all the ECC issues with Variable Policy (AND the UnitTests) on this branch: >> Commits · corthon/edk2 (github.com)<https://github.com/corthon/edk2/commits/var_policy_dev_submission_v8> >> >> I even wrote the Main() entry point lib that Laszlo suggested (it works rather nicely): >> TEMP: Staging for HostTest entry point · corthon/edk2@4ce5210 (github.com)<https://github.com/corthon/edk2/commit/4ce52108b3e1bcb2ba78995be94c3949fe647eda> >> >> However, there\x19s one that I just can\x19t get past and I would like to take it up with the community. I don\x19t think that UnitTests should have to deal with the \x1ccan\x19t initialize variables in declaration\x1d check. Almost none of the solutions that I tested worked, and the ones that did were too cumbersome. They failed on two key points that are important for test writing: >> >> * They were annoying to write ===> fewer tests. >> * They moved even more of the test case data away from the test ===> harder to read tests. >> >> I would like to move for an exception for unit tests (or at least host-based unit tests), but I don\x19t know how to accomplish that from a technical standpoint. >> >> Thoughts? >> >> - Bret >> >> >> >> >> >> >> > > > > > > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest 2020-10-07 14:27 ` Andrew Fish @ 2020-10-07 15:50 ` Laszlo Ersek 2020-10-07 16:44 ` [EXTERNAL] " Bret Barkelew 0 siblings, 1 reply; 9+ messages in thread From: Laszlo Ersek @ 2020-10-07 15:50 UTC (permalink / raw) To: Andrew Fish, devel; +Cc: michael.d.kinney, Bret Barkelew On 10/07/20 16:27, Andrew Fish wrote: > For case 1 I thought the size had to be > 8 bytes, not just a struct? Maybe that is compiler specific? Honestly, I've got no clue. I just remember we must avoid initializers for objects that do not have static storage duration. Laszlo > > Sent from my iPhone > >> On Oct 7, 2020, at 6:43 AM, Laszlo Ersek <lersek@redhat.com> wrote: >> >> On 10/07/20 03:46, Michael D Kinney wrote: >>> >>> Bret, >>> >>> Initializing variable in declaration for structures and arrays >>> introduces use of intrinsics. Since it is possible for unit test >>> sources to be used for both host and target tests, I recommend we >>> continue to follow the EDK II coding style for unit tests to support >>> maximum compatibility and code reuse. >>> >>> Using a module global variable with initializers instead of >>> initializing a local declaration is the same amount of work, so I do >>> not believe that will result in fewer tests. >>> >>> I agree it is useful to have the test data next to the test code. This >>> can be accomplished by breaking up into more files so the test data is >>> immediately above the test function the test data is used. Does ECC >>> raise an error if a module global is placed between 2 functions? A >>> 2nd approach to put the module global immediately above the test >>> function the test data is used. >> >> Consider the following example structure type, for the sake of >> discussion: >> >> typedef struct { >> UINT32 Value; >> } TEST_DATA; >> >> >> * Case#1: block scope, automatic storage duration >> >> EFI_STATUS >> FoobarTest ( >> VOID >> ) >> { >> TEST_DATA TestData = { 42 }; >> // ... >> } >> >> Problem: uses intrinsics. >> >> >> * Case#2: file scope, static storage duration. >> >> STATIC CONST TEST_DATA mTestData = { 42 }; >> >> EFI_STATUS >> FoobarTest ( >> VOID >> ) >> { >> // ... >> } >> >> Problem: either "mTestData" is textually far from FoobarTest(), or -- if >> we keep them close to each other -- we mix variable definitions with >> function definitions, at file scope. >> >> >> * Case #3: block scope, static storage duration. >> >> EFI_STATUS >> FoobarTest ( >> VOID >> ) >> { >> STATIC CONST TEST_DATA TestData = { 42 }; >> // ... >> } >> >> Problem: there should be none. Does not involve intrinsics, and the >> object definition is part of the function's scope. >> >> >> If ECC does not recognize case#3 as valid, then that is an *ECC bug*. >> >> ECC has no reason to prevent case#3, as case#3 does not involve >> intrinsics, and is a generally valid and useful C language construct (it >> combines the life cycle of case#2 with the visibility of case#1). >> >> Again, if ECC rejects case#3, that's *definitely* a bug in ECC, and we >> should fix it first. Given that ECC includes a full-blown C language >> parser, the fix should not be too difficult -- check if the declaration >> has the "static" storage-class specifier. >> >> ... In fact, I think that purely CONST-qualifying TestData might suffice >> for shutting up ECC. See the following in >> "BaseTools/Source/Python/Ecc/c.py", method >> "CheckFuncLayoutLocalVariable": >> >>> for Result in ResultSet: >>> if len(Result[1]) > 0 and 'CONST' not in Result[3]: >>> PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2]) >> >> So case#3 should work through that avenue already, because case#3 has >> CONST *too*. >> >> Now, in case#3, if "TestData" needs to undergo modifications, and so >> CONST is not immediately desirable, that's solvable: >> >> EFI_STATUS >> FoobarTest ( >> VOID >> ) >> { >> STATIC CONST TEST_DATA TestDataTemplate = { 42 }; >> TEST_DATA TestData; >> >> CopyMem (&TestData, TestDataTemplate, sizeof (TEST_DATA)); >> // ... >> } >> >> Thanks >> Laszlo >> >>> >>> Best regards, >>> >>> Mike >>> >>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bret Barkelew via groups.io >>> Sent: Tuesday, October 6, 2020 5:28 PM >>> To: devel@edk2.groups.io >>> Subject: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest >>> >>> I\x19ve worked through all the ECC issues with Variable Policy (AND the UnitTests) on this branch: >>> Commits · corthon/edk2 (github.com)<https://github.com/corthon/edk2/commits/var_policy_dev_submission_v8> >>> >>> I even wrote the Main() entry point lib that Laszlo suggested (it works rather nicely): >>> TEMP: Staging for HostTest entry point · corthon/edk2@4ce5210 (github.com)<https://github.com/corthon/edk2/commit/4ce52108b3e1bcb2ba78995be94c3949fe647eda> >>> >>> However, there\x19s one that I just can\x19t get past and I would like to take it up with the community. I don\x19t think that UnitTests should have to deal with the \x1ccan\x19t initialize variables in declaration\x1d check. Almost none of the solutions that I tested worked, and the ones that did were too cumbersome. They failed on two key points that are important for test writing: >>> >>> * They were annoying to write ===> fewer tests. >>> * They moved even more of the test case data away from the test ===> harder to read tests. >>> >>> I would like to move for an exception for unit tests (or at least host-based unit tests), but I don\x19t know how to accomplish that from a technical standpoint. >>> >>> Thoughts? >>> >>> - Bret >>> >>> >>> >>> >>> >>> >>> >> >> >> >> >> >> > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [EXTERNAL] Re: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest 2020-10-07 15:50 ` Laszlo Ersek @ 2020-10-07 16:44 ` Bret Barkelew 2020-10-07 18:19 ` Michael D Kinney 2020-10-08 13:10 ` Laszlo Ersek 0 siblings, 2 replies; 9+ messages in thread From: Bret Barkelew @ 2020-10-07 16:44 UTC (permalink / raw) To: Laszlo Ersek, Andrew Fish, devel@edk2.groups.io; +Cc: Kinney, Michael D [-- Attachment #1: Type: text/plain, Size: 7195 bytes --] I can test it again, but I hit a compiler complaint around the STATIC CONST solution. Also, it doesn’t apply in all cases because I have at lease half a dozen cases that say “test X, prove negative, twiddle value, test Y, prove positive”. I’ll try a few more things, but I may reissue the patch series and withhold the tests until they can be rewritten to match. I don’t want them to hold up VarPol any longer. - Bret From: Laszlo Ersek<mailto:lersek@redhat.com> Sent: Wednesday, October 7, 2020 8:51 AM To: Andrew Fish<mailto:afish@apple.com>; devel@edk2.groups.io<mailto:devel@edk2.groups.io> Cc: Kinney, Michael D<mailto:michael.d.kinney@intel.com>; Bret Barkelew<mailto:Bret.Barkelew@microsoft.com> Subject: [EXTERNAL] Re: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest On 10/07/20 16:27, Andrew Fish wrote: > For case 1 I thought the size had to be > 8 bytes, not just a struct? Maybe that is compiler specific? Honestly, I've got no clue. I just remember we must avoid initializers for objects that do not have static storage duration. Laszlo > > Sent from my iPhone > >> On Oct 7, 2020, at 6:43 AM, Laszlo Ersek <lersek@redhat.com> wrote: >> >> On 10/07/20 03:46, Michael D Kinney wrote: >>> >>> Bret, >>> >>> Initializing variable in declaration for structures and arrays >>> introduces use of intrinsics. Since it is possible for unit test >>> sources to be used for both host and target tests, I recommend we >>> continue to follow the EDK II coding style for unit tests to support >>> maximum compatibility and code reuse. >>> >>> Using a module global variable with initializers instead of >>> initializing a local declaration is the same amount of work, so I do >>> not believe that will result in fewer tests. >>> >>> I agree it is useful to have the test data next to the test code. This >>> can be accomplished by breaking up into more files so the test data is >>> immediately above the test function the test data is used. Does ECC >>> raise an error if a module global is placed between 2 functions? A >>> 2nd approach to put the module global immediately above the test >>> function the test data is used. >> >> Consider the following example structure type, for the sake of >> discussion: >> >> typedef struct { >> UINT32 Value; >> } TEST_DATA; >> >> >> * Case#1: block scope, automatic storage duration >> >> EFI_STATUS >> FoobarTest ( >> VOID >> ) >> { >> TEST_DATA TestData = { 42 }; >> // ... >> } >> >> Problem: uses intrinsics. >> >> >> * Case#2: file scope, static storage duration. >> >> STATIC CONST TEST_DATA mTestData = { 42 }; >> >> EFI_STATUS >> FoobarTest ( >> VOID >> ) >> { >> // ... >> } >> >> Problem: either "mTestData" is textually far from FoobarTest(), or -- if >> we keep them close to each other -- we mix variable definitions with >> function definitions, at file scope. >> >> >> * Case #3: block scope, static storage duration. >> >> EFI_STATUS >> FoobarTest ( >> VOID >> ) >> { >> STATIC CONST TEST_DATA TestData = { 42 }; >> // ... >> } >> >> Problem: there should be none. Does not involve intrinsics, and the >> object definition is part of the function's scope. >> >> >> If ECC does not recognize case#3 as valid, then that is an *ECC bug*. >> >> ECC has no reason to prevent case#3, as case#3 does not involve >> intrinsics, and is a generally valid and useful C language construct (it >> combines the life cycle of case#2 with the visibility of case#1). >> >> Again, if ECC rejects case#3, that's *definitely* a bug in ECC, and we >> should fix it first. Given that ECC includes a full-blown C language >> parser, the fix should not be too difficult -- check if the declaration >> has the "static" storage-class specifier. >> >> ... In fact, I think that purely CONST-qualifying TestData might suffice >> for shutting up ECC. See the following in >> "BaseTools/Source/Python/Ecc/c.py", method >> "CheckFuncLayoutLocalVariable": >> >>> for Result in ResultSet: >>> if len(Result[1]) > 0 and 'CONST' not in Result[3]: >>> PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2]) >> >> So case#3 should work through that avenue already, because case#3 has >> CONST *too*. >> >> Now, in case#3, if "TestData" needs to undergo modifications, and so >> CONST is not immediately desirable, that's solvable: >> >> EFI_STATUS >> FoobarTest ( >> VOID >> ) >> { >> STATIC CONST TEST_DATA TestDataTemplate = { 42 }; >> TEST_DATA TestData; >> >> CopyMem (&TestData, TestDataTemplate, sizeof (TEST_DATA)); >> // ... >> } >> >> Thanks >> Laszlo >> >>> >>> Best regards, >>> >>> Mike >>> >>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bret Barkelew via groups.io >>> Sent: Tuesday, October 6, 2020 5:28 PM >>> To: devel@edk2.groups.io >>> Subject: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest >>> >>> Ive worked through all the ECC issues with Variable Policy (AND the UnitTests) on this branch: >>> Commits · corthon/edk2 (github.com)<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fcorthon%2Fedk2%2Fcommits%2Fvar_policy_dev_submission_v8&data=04%7C01%7Cbret.barkelew%40microsoft.com%7C8286accbe81740bde8cc08d86ad8c8ae%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637376826604910138%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=XSNAxTGdbKGlrPLV%2BqWVNEAQjyyeSoKQ8zcfG1%2B4W1s%3D&reserved=0> >>> >>> I even wrote the Main() entry point lib that Laszlo suggested (it works rather nicely): >>> TEMP: Staging for HostTest entry point · corthon/edk2@4ce5210 (github.com)<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fcorthon%2Fedk2%2Fcommit%2F4ce52108b3e1bcb2ba78995be94c3949fe647eda&data=04%7C01%7Cbret.barkelew%40microsoft.com%7C8286accbe81740bde8cc08d86ad8c8ae%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637376826604910138%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=46MZeja1WTnq44vSZOwJQ%2BAs61TbdFQtFfyj7wgm5mY%3D&reserved=0> >>> >>> However, theres one that I just cant get past and I would like to take it up with the community. I dont think that UnitTests should have to deal with the \x1ccant initialize variables in declaration check. Almost none of the solutions that I tested worked, and the ones that did were too cumbersome. They failed on two key points that are important for test writing: >>> >>> * They were annoying to write ===> fewer tests. >>> * They moved even more of the test case data away from the test ===> harder to read tests. >>> >>> I would like to move for an exception for unit tests (or at least host-based unit tests), but I dont know how to accomplish that from a technical standpoint. >>> >>> Thoughts? >>> >>> - Bret >>> >>> >>> >>> >>> >>> >>> >> >> >> >> >> >> > [-- Attachment #2: Type: text/html, Size: 11615 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [EXTERNAL] Re: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest 2020-10-07 16:44 ` [EXTERNAL] " Bret Barkelew @ 2020-10-07 18:19 ` Michael D Kinney 2020-10-08 13:10 ` Laszlo Ersek 1 sibling, 0 replies; 9+ messages in thread From: Michael D Kinney @ 2020-10-07 18:19 UTC (permalink / raw) To: Bret Barkelew, Laszlo Ersek, Andrew Fish, devel@edk2.groups.io, Kinney, Michael D [-- Attachment #1: Type: text/plain, Size: 7777 bytes --] Bret, Can you provide the compiler log? You can still use STATIC CONST and copy it to a 2nd local that allows mods. Mike From: Bret Barkelew <Bret.Barkelew@microsoft.com> Sent: Wednesday, October 7, 2020 9:45 AM To: Laszlo Ersek <lersek@redhat.com>; Andrew Fish <afish@apple.com>; devel@edk2.groups.io Cc: Kinney, Michael D <michael.d.kinney@intel.com> Subject: RE: [EXTERNAL] Re: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest I can test it again, but I hit a compiler complaint around the STATIC CONST solution. Also, it doesn’t apply in all cases because I have at lease half a dozen cases that say “test X, prove negative, twiddle value, test Y, prove positive”. I’ll try a few more things, but I may reissue the patch series and withhold the tests until they can be rewritten to match. I don’t want them to hold up VarPol any longer. - Bret From: Laszlo Ersek<mailto:lersek@redhat.com> Sent: Wednesday, October 7, 2020 8:51 AM To: Andrew Fish<mailto:afish@apple.com>; devel@edk2.groups.io<mailto:devel@edk2.groups.io> Cc: Kinney, Michael D<mailto:michael.d.kinney@intel.com>; Bret Barkelew<mailto:Bret.Barkelew@microsoft.com> Subject: [EXTERNAL] Re: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest On 10/07/20 16:27, Andrew Fish wrote: > For case 1 I thought the size had to be > 8 bytes, not just a struct? Maybe that is compiler specific? Honestly, I've got no clue. I just remember we must avoid initializers for objects that do not have static storage duration. Laszlo > > Sent from my iPhone > >> On Oct 7, 2020, at 6:43 AM, Laszlo Ersek <lersek@redhat.com<mailto:lersek@redhat.com>> wrote: >> >> On 10/07/20 03:46, Michael D Kinney wrote: >>> >>> Bret, >>> >>> Initializing variable in declaration for structures and arrays >>> introduces use of intrinsics. Since it is possible for unit test >>> sources to be used for both host and target tests, I recommend we >>> continue to follow the EDK II coding style for unit tests to support >>> maximum compatibility and code reuse. >>> >>> Using a module global variable with initializers instead of >>> initializing a local declaration is the same amount of work, so I do >>> not believe that will result in fewer tests. >>> >>> I agree it is useful to have the test data next to the test code. This >>> can be accomplished by breaking up into more files so the test data is >>> immediately above the test function the test data is used. Does ECC >>> raise an error if a module global is placed between 2 functions? A >>> 2nd approach to put the module global immediately above the test >>> function the test data is used. >> >> Consider the following example structure type, for the sake of >> discussion: >> >> typedef struct { >> UINT32 Value; >> } TEST_DATA; >> >> >> * Case#1: block scope, automatic storage duration >> >> EFI_STATUS >> FoobarTest ( >> VOID >> ) >> { >> TEST_DATA TestData = { 42 }; >> // ... >> } >> >> Problem: uses intrinsics. >> >> >> * Case#2: file scope, static storage duration. >> >> STATIC CONST TEST_DATA mTestData = { 42 }; >> >> EFI_STATUS >> FoobarTest ( >> VOID >> ) >> { >> // ... >> } >> >> Problem: either "mTestData" is textually far from FoobarTest(), or -- if >> we keep them close to each other -- we mix variable definitions with >> function definitions, at file scope. >> >> >> * Case #3: block scope, static storage duration. >> >> EFI_STATUS >> FoobarTest ( >> VOID >> ) >> { >> STATIC CONST TEST_DATA TestData = { 42 }; >> // ... >> } >> >> Problem: there should be none. Does not involve intrinsics, and the >> object definition is part of the function's scope. >> >> >> If ECC does not recognize case#3 as valid, then that is an *ECC bug*. >> >> ECC has no reason to prevent case#3, as case#3 does not involve >> intrinsics, and is a generally valid and useful C language construct (it >> combines the life cycle of case#2 with the visibility of case#1). >> >> Again, if ECC rejects case#3, that's *definitely* a bug in ECC, and we >> should fix it first. Given that ECC includes a full-blown C language >> parser, the fix should not be too difficult -- check if the declaration >> has the "static" storage-class specifier. >> >> ... In fact, I think that purely CONST-qualifying TestData might suffice >> for shutting up ECC. See the following in >> "BaseTools/Source/Python/Ecc/c.py", method >> "CheckFuncLayoutLocalVariable": >> >>> for Result in ResultSet: >>> if len(Result[1]) > 0 and 'CONST' not in Result[3]: >>> PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2]) >> >> So case#3 should work through that avenue already, because case#3 has >> CONST *too*. >> >> Now, in case#3, if "TestData" needs to undergo modifications, and so >> CONST is not immediately desirable, that's solvable: >> >> EFI_STATUS >> FoobarTest ( >> VOID >> ) >> { >> STATIC CONST TEST_DATA TestDataTemplate = { 42 }; >> TEST_DATA TestData; >> >> CopyMem (&TestData, TestDataTemplate, sizeof (TEST_DATA)); >> // ... >> } >> >> Thanks >> Laszlo >> >>> >>> Best regards, >>> >>> Mike >>> >>> From: devel@edk2.groups.io<mailto:devel@edk2.groups.io> <devel@edk2.groups.io<mailto:devel@edk2.groups.io>> On Behalf Of Bret Barkelew via groups.io >>> Sent: Tuesday, October 6, 2020 5:28 PM >>> To: devel@edk2.groups.io<mailto:devel@edk2.groups.io> >>> Subject: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest >>> >>> Ive worked through all the ECC issues with Variable Policy (AND the UnitTests) on this branch: >>> Commits · corthon/edk2 (github.com)<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fcorthon%2Fedk2%2Fcommits%2Fvar_policy_dev_submission_v8&data=04%7C01%7Cbret.barkelew%40microsoft.com%7C8286accbe81740bde8cc08d86ad8c8ae%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637376826604910138%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=XSNAxTGdbKGlrPLV%2BqWVNEAQjyyeSoKQ8zcfG1%2B4W1s%3D&reserved=0> >>> >>> I even wrote the Main() entry point lib that Laszlo suggested (it works rather nicely): >>> TEMP: Staging for HostTest entry point · corthon/edk2@4ce5210 (github.com)<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fcorthon%2Fedk2%2Fcommit%2F4ce52108b3e1bcb2ba78995be94c3949fe647eda&data=04%7C01%7Cbret.barkelew%40microsoft.com%7C8286accbe81740bde8cc08d86ad8c8ae%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637376826604910138%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=46MZeja1WTnq44vSZOwJQ%2BAs61TbdFQtFfyj7wgm5mY%3D&reserved=0> >>> >>> However, theres one that I just cant get past and I would like to take it up with the community. I dont think that UnitTests should have to deal with the \x1ccant initialize variables in declaration check. Almost none of the solutions that I tested worked, and the ones that did were too cumbersome. They failed on two key points that are important for test writing: >>> >>> * They were annoying to write ===> fewer tests. >>> * They moved even more of the test case data away from the test ===> harder to read tests. >>> >>> I would like to move for an exception for unit tests (or at least host-based unit tests), but I dont know how to accomplish that from a technical standpoint. >>> >>> Thoughts? >>> >>> - Bret >>> >>> >>> >>> >>> >>> >>> >> >> >> >> >> >> > [-- Attachment #2: Type: text/html, Size: 50792 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [EXTERNAL] Re: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest 2020-10-07 16:44 ` [EXTERNAL] " Bret Barkelew 2020-10-07 18:19 ` Michael D Kinney @ 2020-10-08 13:10 ` Laszlo Ersek 1 sibling, 0 replies; 9+ messages in thread From: Laszlo Ersek @ 2020-10-08 13:10 UTC (permalink / raw) To: Bret Barkelew, Andrew Fish, devel@edk2.groups.io; +Cc: Kinney, Michael D On 10/07/20 18:44, Bret Barkelew wrote: > I can test it again, but I hit a compiler complaint around the STATIC CONST solution. I'm curious. > Also, it doesn’t apply in all cases because I have at lease half a dozen cases that say “test X, prove negative, twiddle value, test Y, prove positive”. That works with the last example I gave; "STATIC CONST TestDataTemplate" + normal local TestData. CopyMem from template to local variable, check and tweak local var as needed. Please check the end of my previous email again. EFI_STATUS FoobarTest ( VOID ) { STATIC CONST TEST_DATA TestDataTemplate = { 42 }; TEST_DATA TestData; CopyMem (&TestData, TestDataTemplate, sizeof (TEST_DATA)); // // run a test on TestData, verify that it fails // TestData.Value = 43; // // run the same test on TestData, verify that it succeeds // } thanks Laszlo > > I’ll try a few more things, but I may reissue the patch series and withhold the tests until they can be rewritten to match. I don’t want them to hold up VarPol any longer. > > - Bret > > From: Laszlo Ersek<mailto:lersek@redhat.com> > Sent: Wednesday, October 7, 2020 8:51 AM > To: Andrew Fish<mailto:afish@apple.com>; devel@edk2.groups.io<mailto:devel@edk2.groups.io> > Cc: Kinney, Michael D<mailto:michael.d.kinney@intel.com>; Bret Barkelew<mailto:Bret.Barkelew@microsoft.com> > Subject: [EXTERNAL] Re: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest > > On 10/07/20 16:27, Andrew Fish wrote: >> For case 1 I thought the size had to be > 8 bytes, not just a struct? Maybe that is compiler specific? > > Honestly, I've got no clue. I just remember we must avoid initializers > for objects that do not have static storage duration. > > Laszlo > >> >> Sent from my iPhone >> >>> On Oct 7, 2020, at 6:43 AM, Laszlo Ersek <lersek@redhat.com> wrote: >>> >>> On 10/07/20 03:46, Michael D Kinney wrote: >>>> >>>> Bret, >>>> >>>> Initializing variable in declaration for structures and arrays >>>> introduces use of intrinsics. Since it is possible for unit test >>>> sources to be used for both host and target tests, I recommend we >>>> continue to follow the EDK II coding style for unit tests to support >>>> maximum compatibility and code reuse. >>>> >>>> Using a module global variable with initializers instead of >>>> initializing a local declaration is the same amount of work, so I do >>>> not believe that will result in fewer tests. >>>> >>>> I agree it is useful to have the test data next to the test code. This >>>> can be accomplished by breaking up into more files so the test data is >>>> immediately above the test function the test data is used. Does ECC >>>> raise an error if a module global is placed between 2 functions? A >>>> 2nd approach to put the module global immediately above the test >>>> function the test data is used. >>> >>> Consider the following example structure type, for the sake of >>> discussion: >>> >>> typedef struct { >>> UINT32 Value; >>> } TEST_DATA; >>> >>> >>> * Case#1: block scope, automatic storage duration >>> >>> EFI_STATUS >>> FoobarTest ( >>> VOID >>> ) >>> { >>> TEST_DATA TestData = { 42 }; >>> // ... >>> } >>> >>> Problem: uses intrinsics. >>> >>> >>> * Case#2: file scope, static storage duration. >>> >>> STATIC CONST TEST_DATA mTestData = { 42 }; >>> >>> EFI_STATUS >>> FoobarTest ( >>> VOID >>> ) >>> { >>> // ... >>> } >>> >>> Problem: either "mTestData" is textually far from FoobarTest(), or -- if >>> we keep them close to each other -- we mix variable definitions with >>> function definitions, at file scope. >>> >>> >>> * Case #3: block scope, static storage duration. >>> >>> EFI_STATUS >>> FoobarTest ( >>> VOID >>> ) >>> { >>> STATIC CONST TEST_DATA TestData = { 42 }; >>> // ... >>> } >>> >>> Problem: there should be none. Does not involve intrinsics, and the >>> object definition is part of the function's scope. >>> >>> >>> If ECC does not recognize case#3 as valid, then that is an *ECC bug*. >>> >>> ECC has no reason to prevent case#3, as case#3 does not involve >>> intrinsics, and is a generally valid and useful C language construct (it >>> combines the life cycle of case#2 with the visibility of case#1). >>> >>> Again, if ECC rejects case#3, that's *definitely* a bug in ECC, and we >>> should fix it first. Given that ECC includes a full-blown C language >>> parser, the fix should not be too difficult -- check if the declaration >>> has the "static" storage-class specifier. >>> >>> ... In fact, I think that purely CONST-qualifying TestData might suffice >>> for shutting up ECC. See the following in >>> "BaseTools/Source/Python/Ecc/c.py", method >>> "CheckFuncLayoutLocalVariable": >>> >>>> for Result in ResultSet: >>>> if len(Result[1]) > 0 and 'CONST' not in Result[3]: >>>> PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, Result[2]) >>> >>> So case#3 should work through that avenue already, because case#3 has >>> CONST *too*. >>> >>> Now, in case#3, if "TestData" needs to undergo modifications, and so >>> CONST is not immediately desirable, that's solvable: >>> >>> EFI_STATUS >>> FoobarTest ( >>> VOID >>> ) >>> { >>> STATIC CONST TEST_DATA TestDataTemplate = { 42 }; >>> TEST_DATA TestData; >>> >>> CopyMem (&TestData, TestDataTemplate, sizeof (TEST_DATA)); >>> // ... >>> } >>> >>> Thanks >>> Laszlo >>> >>>> >>>> Best regards, >>>> >>>> Mike >>>> >>>> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bret Barkelew via groups.io >>>> Sent: Tuesday, October 6, 2020 5:28 PM >>>> To: devel@edk2.groups.io >>>> Subject: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest >>>> >>>> Ive worked through all the ECC issues with Variable Policy (AND the UnitTests) on this branch: >>>> Commits · corthon/edk2 (github.com)<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fcorthon%2Fedk2%2Fcommits%2Fvar_policy_dev_submission_v8&data=04%7C01%7Cbret.barkelew%40microsoft.com%7C8286accbe81740bde8cc08d86ad8c8ae%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637376826604910138%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=XSNAxTGdbKGlrPLV%2BqWVNEAQjyyeSoKQ8zcfG1%2B4W1s%3D&reserved=0> >>>> >>>> I even wrote the Main() entry point lib that Laszlo suggested (it works rather nicely): >>>> TEMP: Staging for HostTest entry point · corthon/edk2@4ce5210 (github.com)<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fcorthon%2Fedk2%2Fcommit%2F4ce52108b3e1bcb2ba78995be94c3949fe647eda&data=04%7C01%7Cbret.barkelew%40microsoft.com%7C8286accbe81740bde8cc08d86ad8c8ae%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637376826604910138%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=46MZeja1WTnq44vSZOwJQ%2BAs61TbdFQtFfyj7wgm5mY%3D&reserved=0> >>>> >>>> However, theres one that I just cant get past and I would like to take it up with the community. I dont think that UnitTests should have to deal with the \x1ccant initialize variables in declaration check. Almost none of the solutions that I tested worked, and the ones that did were too cumbersome. They failed on two key points that are important for test writing: >>>> >>>> * They were annoying to write ===> fewer tests. >>>> * They moved even more of the test case data away from the test ===> harder to read tests. >>>> >>>> I would like to move for an exception for unit tests (or at least host-based unit tests), but I dont know how to accomplish that from a technical standpoint. >>>> >>>> Thoughts? >>>> >>>> - Bret >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>> >>> >>> >>> >>> >>> >> > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest 2020-10-07 13:42 ` [edk2-devel] " Laszlo Ersek 2020-10-07 14:27 ` Andrew Fish @ 2020-10-07 16:24 ` Michael D Kinney 1 sibling, 0 replies; 9+ messages in thread From: Michael D Kinney @ 2020-10-07 16:24 UTC (permalink / raw) To: Laszlo Ersek, devel@edk2.groups.io, Bret Barkelew, Kinney, Michael D Hi Laszlo, Option #3 looks really good to me. And I agree that ECC should not generate an error if a STATIC CONST local variable is initialized. Thanks, Mike > -----Original Message----- > From: Laszlo Ersek <lersek@redhat.com> > Sent: Wednesday, October 7, 2020 6:43 AM > To: devel@edk2.groups.io; Kinney, Michael D <michael.d.kinney@intel.com>; Bret Barkelew <Bret.Barkelew@microsoft.com> > Subject: Re: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest > > On 10/07/20 03:46, Michael D Kinney wrote: > > > > Bret, > > > > Initializing variable in declaration for structures and arrays > > introduces use of intrinsics. Since it is possible for unit test > > sources to be used for both host and target tests, I recommend we > > continue to follow the EDK II coding style for unit tests to support > > maximum compatibility and code reuse. > > > > Using a module global variable with initializers instead of > > initializing a local declaration is the same amount of work, so I do > > not believe that will result in fewer tests. > > > > I agree it is useful to have the test data next to the test code. This > > can be accomplished by breaking up into more files so the test data is > > immediately above the test function the test data is used. Does ECC > > raise an error if a module global is placed between 2 functions? A > > 2nd approach to put the module global immediately above the test > > function the test data is used. > > Consider the following example structure type, for the sake of > discussion: > > typedef struct { > UINT32 Value; > } TEST_DATA; > > > * Case#1: block scope, automatic storage duration > > EFI_STATUS > FoobarTest ( > VOID > ) > { > TEST_DATA TestData = { 42 }; > // ... > } > > Problem: uses intrinsics. > > > * Case#2: file scope, static storage duration. > > STATIC CONST TEST_DATA mTestData = { 42 }; > > EFI_STATUS > FoobarTest ( > VOID > ) > { > // ... > } > > Problem: either "mTestData" is textually far from FoobarTest(), or -- if > we keep them close to each other -- we mix variable definitions with > function definitions, at file scope. > > > * Case #3: block scope, static storage duration. > > EFI_STATUS > FoobarTest ( > VOID > ) > { > STATIC CONST TEST_DATA TestData = { 42 }; > // ... > } > > Problem: there should be none. Does not involve intrinsics, and the > object definition is part of the function's scope. > > > If ECC does not recognize case#3 as valid, then that is an *ECC bug*. > > ECC has no reason to prevent case#3, as case#3 does not involve > intrinsics, and is a generally valid and useful C language construct (it > combines the life cycle of case#2 with the visibility of case#1). > > Again, if ECC rejects case#3, that's *definitely* a bug in ECC, and we > should fix it first. Given that ECC includes a full-blown C language > parser, the fix should not be too difficult -- check if the declaration > has the "static" storage-class specifier. > > ... In fact, I think that purely CONST-qualifying TestData might suffice > for shutting up ECC. See the following in > "BaseTools/Source/Python/Ecc/c.py", method > "CheckFuncLayoutLocalVariable": > > > for Result in ResultSet: > > if len(Result[1]) > 0 and 'CONST' not in Result[3]: > > PrintErrorMsg(ERROR_C_FUNCTION_LAYOUT_CHECK_NO_INIT_OF_VARIABLE, 'Variable Name: %s' % Result[0], FileTable, > Result[2]) > > So case#3 should work through that avenue already, because case#3 has > CONST *too*. > > Now, in case#3, if "TestData" needs to undergo modifications, and so > CONST is not immediately desirable, that's solvable: > > EFI_STATUS > FoobarTest ( > VOID > ) > { > STATIC CONST TEST_DATA TestDataTemplate = { 42 }; > TEST_DATA TestData; > > CopyMem (&TestData, TestDataTemplate, sizeof (TEST_DATA)); > // ... > } > > Thanks > Laszlo > > > > > Best regards, > > > > Mike > > > > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Bret Barkelew via groups.io > > Sent: Tuesday, October 6, 2020 5:28 PM > > To: devel@edk2.groups.io > > Subject: [edk2-devel] VariablePolicy: Final Changes Thread 2 - ECC & UnitTest > > > > I\x19ve worked through all the ECC issues with Variable Policy (AND the UnitTests) on this branch: > > Commits · corthon/edk2 (github.com)<https://github.com/corthon/edk2/commits/var_policy_dev_submission_v8> > > > > I even wrote the Main() entry point lib that Laszlo suggested (it works rather nicely): > > TEMP: Staging for HostTest entry point · corthon/edk2@4ce5210 > (github.com)<https://github.com/corthon/edk2/commit/4ce52108b3e1bcb2ba78995be94c3949fe647eda> > > > > However, there\x19s one that I just can\x19t get past and I would like to take it up with the community. I don\x19t think that UnitTests > should have to deal with the \x1ccan\x19t initialize variables in declaration\x1d check. Almost none of the solutions that I tested worked, > and the ones that did were too cumbersome. They failed on two key points that are important for test writing: > > > > * They were annoying to write ===> fewer tests. > > * They moved even more of the test case data away from the test ===> harder to read tests. > > > > I would like to move for an exception for unit tests (or at least host-based unit tests), but I don\x19t know how to accomplish that > from a technical standpoint. > > > > Thoughts? > > > > - Bret > > > > > > > > > > > > > > ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2020-10-08 13:10 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2020-10-07 0:28 VariablePolicy: Final Changes Thread 2 - ECC & UnitTest Bret Barkelew 2020-10-07 1:46 ` Michael D Kinney 2020-10-07 13:42 ` [edk2-devel] " Laszlo Ersek 2020-10-07 14:27 ` Andrew Fish 2020-10-07 15:50 ` Laszlo Ersek 2020-10-07 16:44 ` [EXTERNAL] " Bret Barkelew 2020-10-07 18:19 ` Michael D Kinney 2020-10-08 13:10 ` Laszlo Ersek 2020-10-07 16:24 ` Michael D Kinney
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox