* Difficulty in implementing a GCC plugin for [[invariant]] contract functions in classes/structs without prior experience? @ 2022-12-29 15:37 Gavin Ray 2022-12-29 18:33 ` Gavin Ray 0 siblings, 1 reply; 3+ messages in thread From: Gavin Ray @ 2022-12-29 15:37 UTC (permalink / raw) To: gcc [-- Attachment #1: Type: text/plain, Size: 1368 bytes --] Hey all, The feature I appreciate most about the D programming language is its "Design by Contract" feature. Contract programming - Dlang Tour <https://tour.dlang.org/tour/en/gems/contract-programming> With the recent merge of Contracts to GCC master, C++ comes close to this, with support for function-based contracts. The most powerful contract though, is the "invariant" contract: *invariant() is a special member function of struct and class types that > allows sanity checking an object's state during its whole lifetime:* > > *- invariant() is called after the constructor has run and before the > destructor is called.* > *- invariant() is called before entering a member function* > *- invariant() is called after exiting a member function.**- Class > invariants are inherited. That means that a derived class invariant will > implicitly call the base class invariant.* I'm very interested in prototyping a GCC plugin to implement support for transforming all member function calls in class/struct types such that a call to the [[invariant]]-annotated function (if any) is placed at the beginning and end of method bodies. Does anyone have any idea whether something like this would be suitable for a first plugin, or if there would be roadblocks/technical challenges to implementing such a thing? I'd be grateful for any advice. Thank you, Gavin =) ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Difficulty in implementing a GCC plugin for [[invariant]] contract functions in classes/structs without prior experience? 2022-12-29 15:37 Difficulty in implementing a GCC plugin for [[invariant]] contract functions in classes/structs without prior experience? Gavin Ray @ 2022-12-29 18:33 ` Gavin Ray 2022-12-30 17:29 ` Gavin Ray 0 siblings, 1 reply; 3+ messages in thread From: Gavin Ray @ 2022-12-29 18:33 UTC (permalink / raw) To: gcc [-- Attachment #1: Type: text/plain, Size: 2525 bytes --] So I have prototyped the code here, there are two places where I am confused: GCC [[invariant]] plugin for Design by Contract (WIP) (github.com) <https://gist.github.com/GavinRay97/890a65db4ddea46ec6fb6d92e1a145fb#file-invariant-cpp-L41-L93> 1. Is it proper to cast like this? tree args = NULL_TREE; tree tmp_tree = NULL_TREE; vec<tree, va_gc>** args_ptr = (vec<tree, va_gc>**)&args; tree call = build_new_method_call(class_type, id, args_ptr, fun->decl, LOOKUP_NORMAL, &tmp_tree, tf_warning_or_error); 2. At the bottom, I want to call "invariant()" before "return", but I'm not sure how to phrase this in code. The following doesn't work quite right: because you can't compare "gsi_stmt()" and NULL_TREE // If the last block is a return block, insert the call before the return statement. if (gsi_stmt(gsi) != NULL_TREE && gimple_code(gsi_stmt(gsi)) == GIMPLE_RETURN) gsi_insert_before(&gsi, g, GSI_SAME_STMT); else gsi_insert_after(&gsi, g, GSI_SAME_STMT); On Thu, Dec 29, 2022 at 10:37 AM Gavin Ray <ray.gavin97@gmail.com> wrote: > Hey all, > > The feature I appreciate most about the D programming language is its > "Design by Contract" feature. > Contract programming - Dlang Tour > <https://tour.dlang.org/tour/en/gems/contract-programming> > > With the recent merge of Contracts to GCC master, C++ comes close to this, > with support for function-based contracts. > The most powerful contract though, is the "invariant" contract: > > *invariant() is a special member function of struct and class types that >> allows sanity checking an object's state during its whole lifetime:* > > >> >> *- invariant() is called after the constructor has run and before the >> destructor is called.* >> *- invariant() is called before entering a member function* >> *- invariant() is called after exiting a member function.**- Class >> invariants are inherited. That means that a derived class invariant will >> implicitly call the base class invariant.* > > > I'm very interested in prototyping a GCC plugin to implement support for > transforming all member function calls in class/struct types > such that a call to the [[invariant]]-annotated function (if any) is > placed at the beginning and end of method bodies. > > Does anyone have any idea whether something like this would be suitable > for a first plugin, > or if there would be roadblocks/technical challenges to implementing such > a thing? > > I'd be grateful for any advice. > > Thank you, > Gavin =) > > ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Difficulty in implementing a GCC plugin for [[invariant]] contract functions in classes/structs without prior experience? 2022-12-29 18:33 ` Gavin Ray @ 2022-12-30 17:29 ` Gavin Ray 0 siblings, 0 replies; 3+ messages in thread From: Gavin Ray @ 2022-12-30 17:29 UTC (permalink / raw) To: gcc [-- Attachment #1: Type: text/plain, Size: 3509 bytes --] Hey all, I've continued to work on this and have it mostly finished The implementation is here GCC [[invariant]] plugin for Design by Contract (WIP) (github.com) <https://gist.github.com/GavinRay97/890a65db4ddea46ec6fb6d92e1a145fb> I have posted the final remaining question to StackOverflow in case anyone knows It's about how to insert a call to a C++ Member Function, from another Mem-Fn using the GIMPLE API: GCC GIMPLE C++ API, how to insert a call to a member-function from another member-function? - Stack Overflow <https://stackoverflow.com/questions/74964153/gcc-gimple-c-api-how-to-insert-a-call-to-a-member-function-from-another-membe> Would be grateful for any advice. I asked Iain Buclaw, who maintains GDC, and he was able to help but doesn't have a ton of expertise in the C++ frontend. Thanks all On Thu, Dec 29, 2022 at 1:33 PM Gavin Ray <ray.gavin97@gmail.com> wrote: > So I have prototyped the code here, there are two places where I am > confused: > GCC [[invariant]] plugin for Design by Contract (WIP) (github.com) > <https://gist.github.com/GavinRay97/890a65db4ddea46ec6fb6d92e1a145fb#file-invariant-cpp-L41-L93> > > 1. Is it proper to cast like this? > > tree args = NULL_TREE; > tree tmp_tree = NULL_TREE; > vec<tree, va_gc>** args_ptr = (vec<tree, va_gc>**)&args; > > tree call = build_new_method_call(class_type, id, args_ptr, fun->decl, > LOOKUP_NORMAL, &tmp_tree, tf_warning_or_error); > > 2. At the bottom, I want to call "invariant()" before "return", but I'm > not sure how to phrase this in code. The following doesn't work quite right: > because you can't compare "gsi_stmt()" and NULL_TREE > > // If the last block is a return block, insert the call before the > return statement. > if (gsi_stmt(gsi) != NULL_TREE && gimple_code(gsi_stmt(gsi)) == > GIMPLE_RETURN) > gsi_insert_before(&gsi, g, GSI_SAME_STMT); > else > gsi_insert_after(&gsi, g, GSI_SAME_STMT); > > > > > On Thu, Dec 29, 2022 at 10:37 AM Gavin Ray <ray.gavin97@gmail.com> wrote: > >> Hey all, >> >> The feature I appreciate most about the D programming language is its >> "Design by Contract" feature. >> Contract programming - Dlang Tour >> <https://tour.dlang.org/tour/en/gems/contract-programming> >> >> With the recent merge of Contracts to GCC master, C++ comes close to >> this, with support for function-based contracts. >> The most powerful contract though, is the "invariant" contract: >> >> *invariant() is a special member function of struct and class types that >>> allows sanity checking an object's state during its whole lifetime:* >> >> >>> >>> *- invariant() is called after the constructor has run and before the >>> destructor is called.* >>> *- invariant() is called before entering a member function* >>> *- invariant() is called after exiting a member function.**- Class >>> invariants are inherited. That means that a derived class invariant will >>> implicitly call the base class invariant.* >> >> >> I'm very interested in prototyping a GCC plugin to implement support for >> transforming all member function calls in class/struct types >> such that a call to the [[invariant]]-annotated function (if any) is >> placed at the beginning and end of method bodies. >> >> Does anyone have any idea whether something like this would be suitable >> for a first plugin, >> or if there would be roadblocks/technical challenges to implementing such >> a thing? >> >> I'd be grateful for any advice. >> >> Thank you, >> Gavin =) >> >> ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2022-12-30 17:30 UTC | newest] Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-12-29 15:37 Difficulty in implementing a GCC plugin for [[invariant]] contract functions in classes/structs without prior experience? Gavin Ray 2022-12-29 18:33 ` Gavin Ray 2022-12-30 17:29 ` Gavin Ray
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).