Implement a new OwnedOrReference memory utility - #2774
Conversation
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
|
@cubic-ai review |
🤖 Augment PR SummarySummary: This PR introduces a new header-only Changes:
const T*; callers are responsible for ensuring the referent remains stable and alive while it is read.
🤖 Was this summary useful? React with 👍 or 👎 |
| OwnedOrReference(const OwnedOrReference &) = delete; | ||
| auto operator=(const OwnedOrReference &) -> OwnedOrReference & = delete; | ||
| OwnedOrReference(OwnedOrReference &&) = default; | ||
| auto operator=(OwnedOrReference &&) -> OwnedOrReference & = default; |
There was a problem hiding this comment.
At src/lang/memory/include/sourcemeta/core/memory_owned_or_reference.h:76, when the source borrows the target’s owned value (for example, OwnedOrReference<T> borrowed{target.value()}; target = std::move(borrowed);), memberwise assignment clears target.owned_ before copying borrowed.referenced_. The target then selects a dangling pointer in value(), so this publicly constructible aliasing case has use-after-free behavior.
Severity: medium
🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
There was a problem hiding this comment.
Benchmark (linux/llvm)
Details
| Benchmark suite | Current: fd12d23 | Previous: f69eafb | Ratio |
|---|---|---|---|
Regex_Lower_S_Or_Upper_S_Asterisk |
2.188720581463846 ns/iter |
2.4884130312074215 ns/iter |
0.88 |
Regex_Caret_Lower_S_Or_Upper_S_Asterisk_Dollar |
2.1782760005585886 ns/iter |
2.460737034914427 ns/iter |
0.89 |
Regex_Period_Asterisk |
2.17804989725783 ns/iter |
2.4625929653064644 ns/iter |
0.88 |
Regex_Group_Period_Asterisk_Group |
2.178384219290354 ns/iter |
2.4712752292977918 ns/iter |
0.88 |
Regex_Period_Plus |
2.802491372379258 ns/iter |
3.8712103067816184 ns/iter |
0.72 |
Regex_Period |
2.8082947431299576 ns/iter |
3.8692310457620134 ns/iter |
0.73 |
Regex_Caret_Period_Plus_Dollar |
2.79977313409954 ns/iter |
3.8698058203172074 ns/iter |
0.72 |
Regex_Caret_Group_Period_Plus_Group_Dollar |
2.8010876324473486 ns/iter |
3.866428156068232 ns/iter |
0.72 |
Regex_Caret_Period_Asterisk_Dollar |
3.110215127134372 ns/iter |
2.461708850079733 ns/iter |
1.26 |
Regex_Caret_Group_Period_Asterisk_Group_Dollar |
2.1783277766182225 ns/iter |
2.461994536906273 ns/iter |
0.88 |
Regex_Caret_X_Hyphen |
5.297218027796066 ns/iter |
6.746779777122211 ns/iter |
0.79 |
Regex_Period_Md_Dollar |
27.424842855123572 ns/iter |
26.205919851653285 ns/iter |
1.05 |
Regex_Caret_Slash_Period_Asterisk |
5.710729906326224 ns/iter |
7.314154268712151 ns/iter |
0.78 |
Regex_Caret_Period_Range_Dollar |
2.801924382899019 ns/iter |
3.6380529256843332 ns/iter |
0.77 |
Regex_Nested_Backtrack |
38.40707620611925 ns/iter |
38.65412722320275 ns/iter |
0.99 |
JSON_Array_Of_Objects_Unique |
451.1070202317697 ns/iter |
476.2605599219049 ns/iter |
0.95 |
JSON_Parse_1 |
4505.23305495694 ns/iter |
4378.939459270909 ns/iter |
1.03 |
JSON_Parse_Real |
5185.969624424431 ns/iter |
5023.327739999956 ns/iter |
1.03 |
JSON_Parse_Decimal |
7475.060462334318 ns/iter |
7388.621687561396 ns/iter |
1.01 |
JSON_Parse_Schema_ISO_Language |
3241054.483870904 ns/iter |
3307806.5377357583 ns/iter |
0.98 |
JSON_Parse_Integer |
3541.7450859415876 ns/iter |
3747.316345590892 ns/iter |
0.95 |
JSON_Parse_String_NonSSO_Plain |
2969.49785282912 ns/iter |
3093.85450953128 ns/iter |
0.96 |
JSON_Parse_String_SSO_Plain |
2577.427210164116 ns/iter |
2633.696270463931 ns/iter |
0.98 |
JSON_Parse_String_Escape_Heavy |
12124.152865141165 ns/iter |
12062.794008797977 ns/iter |
1.01 |
JSON_Parse_Object_Short_Keys |
7750.334976458156 ns/iter |
7716.813713318759 ns/iter |
1.00 |
JSON_Parse_Object_Scalar_Properties |
4022.178292305564 ns/iter |
3917.461406652149 ns/iter |
1.03 |
JSON_Parse_Object_Array_Properties |
5304.141707313329 ns/iter |
5317.702621074854 ns/iter |
1.00 |
JSON_Parse_Object_Object_Properties |
5295.4346368123215 ns/iter |
5295.701112853668 ns/iter |
1.00 |
JSON_Parse_Nested_Containers |
34619.9902666742 ns/iter |
34008.77222845473 ns/iter |
1.02 |
JSON_From_String_Copy |
10.862049291088027 ns/iter |
11.760441712578192 ns/iter |
0.92 |
JSON_From_String_Temporary |
9.917698633987236 ns/iter |
10.064613855435997 ns/iter |
0.99 |
JSON_Number_To_Double |
23.402638528647874 ns/iter |
22.846559833186742 ns/iter |
1.02 |
JSON_Object_At_Last_Key/8 |
3.9193740793220617 ns/iter |
4.029512740252286 ns/iter |
0.97 |
JSON_Object_At_Last_Key/32 |
12.281156489871863 ns/iter |
13.335027048719926 ns/iter |
0.92 |
JSON_Object_At_Last_Key/128 |
49.138258375941476 ns/iter |
46.83488685147448 ns/iter |
1.05 |
JSON_Object_At_Last_Key/512 |
384.5437721418027 ns/iter |
360.6595800037441 ns/iter |
1.07 |
JSON_Fast_Hash_Helm_Chart_Lock |
55.911476436331455 ns/iter |
66.12162710762902 ns/iter |
0.85 |
JSON_Equality_Helm_Chart_Lock |
156.9181156746328 ns/iter |
161.05492452145324 ns/iter |
0.97 |
JSON_Divisible_By_Decimal |
246.16199627916117 ns/iter |
250.47835039205842 ns/iter |
0.98 |
JSON_String_Equal/10 |
5.91835600222862 ns/iter |
5.633446397930454 ns/iter |
1.05 |
JSON_String_Equal/100 |
6.544436361776354 ns/iter |
6.335018154004917 ns/iter |
1.03 |
JSON_String_Equal_Small_By_Perfect_Hash/10 |
0.953269539545265 ns/iter |
1.0556436630129387 ns/iter |
0.90 |
JSON_String_Equal_Small_By_Runtime_Perfect_Hash/10 |
14.927955135216541 ns/iter |
12.477760385894335 ns/iter |
1.20 |
JSON_String_Fast_Hash/10 |
2.184816099856054 ns/iter |
2.1110357489597704 ns/iter |
1.03 |
JSON_String_Fast_Hash/100 |
2.1786280751211375 ns/iter |
2.111072722836147 ns/iter |
1.03 |
JSON_String_Key_Hash/10 |
2.7135977126496655 ns/iter |
2.4618714271649655 ns/iter |
1.10 |
JSON_String_Key_Hash/100 |
9.025084832961221 ns/iter |
8.196151044277862 ns/iter |
1.10 |
JSON_Object_Defines_Miss_Same_Length |
3.4264375414669894 ns/iter |
4.221022165413392 ns/iter |
0.81 |
JSON_Object_Defines_Miss_Too_Small |
3.1902669159432673 ns/iter |
3.196846100610072 ns/iter |
1.00 |
JSON_Object_Defines_Miss_Too_Large |
2.7304964062442716 ns/iter |
3.0781881212554207 ns/iter |
0.89 |
Pointer_Object_Traverse |
28.55522594274324 ns/iter |
30.61094573134936 ns/iter |
0.93 |
Pointer_Object_Try_Traverse |
30.5598943417695 ns/iter |
32.70211456747107 ns/iter |
0.93 |
Pointer_Push_Back_Pointer_To_Weak_Pointer |
200.60893153947208 ns/iter |
180.8061425076066 ns/iter |
1.11 |
Pointer_Walker_Schema_ISO_Language |
1566263.1489841735 ns/iter |
1575872.1770114673 ns/iter |
0.99 |
Pointer_Maybe_Tracked_Deeply_Nested/0 |
1273657.0828829408 ns/iter |
1266159.3224637492 ns/iter |
1.01 |
Pointer_Maybe_Tracked_Deeply_Nested/1 |
1660589.6190476362 ns/iter |
1914561.5107033886 ns/iter |
0.87 |
Pointer_Position_Tracker_Get_Deeply_Nested |
658.1851453730758 ns/iter |
710.1000445950247 ns/iter |
0.93 |
JSONPath_Descendant_Filter_Nested |
1528.3548515609937 ns/iter |
1525.7236538200914 ns/iter |
1.00 |
URITemplateRouter_Create |
25036.47643979025 ns/iter |
22118.355261091856 ns/iter |
1.13 |
URITemplateRouter_Match |
177.106051549541 ns/iter |
179.5416531243094 ns/iter |
0.99 |
URITemplateRouter_Match_BasePath |
200.93393989610442 ns/iter |
212.73695340565342 ns/iter |
0.94 |
URITemplateRouterView_Restore |
8426.037285501885 ns/iter |
9916.539042538572 ns/iter |
0.85 |
URITemplateRouterView_Match |
140.12951617208037 ns/iter |
143.9400998095039 ns/iter |
0.97 |
URITemplateRouterView_Match_BasePath |
161.87076817401567 ns/iter |
164.24651007833808 ns/iter |
0.99 |
URITemplateRouterView_Arguments |
423.266251058413 ns/iter |
450.25182761029606 ns/iter |
0.94 |
JSONL_Parse_Large |
9402226.157894533 ns/iter |
8612494.975609729 ns/iter |
1.09 |
JSONL_Parse_Large_GZIP |
10985613.23437508 ns/iter |
10323870.470588425 ns/iter |
1.06 |
JSONLD_Catalog_Annotation_List_Populate |
613519.0215439904 ns/iter |
589178.0302013519 ns/iter |
1.04 |
JSONLD_Catalog_Materialize |
3533586.8163263155 ns/iter |
3554287.387755106 ns/iter |
0.99 |
HTML_Build_Table_100000 |
58489985.18182085 ns/iter |
67405181.69999917 ns/iter |
0.87 |
HTML_Render_Table_100000 |
1971226.6397694487 ns/iter |
2019103.4285713679 ns/iter |
0.98 |
GZIP_Compress_ISO_Language_Set_3_Locations |
34130978.8000018 ns/iter |
35823532.20000129 ns/iter |
0.95 |
GZIP_Decompress_ISO_Language_Set_3_Locations |
4258347.083832577 ns/iter |
4269583.530487938 ns/iter |
1.00 |
GZIP_Compress_ISO_Language_Set_3_Schema |
1925938.8928571003 ns/iter |
2138147.1310974467 ns/iter |
0.90 |
GZIP_Decompress_ISO_Language_Set_3_Schema |
353028.96450306644 ns/iter |
278110.8028560106 ns/iter |
1.27 |
JOSE_VerifySignature_RS256 |
56846.26569105821 ns/iter |
63939.62968036457 ns/iter |
0.89 |
JOSE_VerifySignature_ES512 |
2466423.109154903 ns/iter |
2659108.8212926774 ns/iter |
0.93 |
This comment was automatically generated by workflow using github-action-benchmark.
There was a problem hiding this comment.
Benchmark (linux/gcc)
Details
| Benchmark suite | Current: fd12d23 | Previous: f69eafb | Ratio |
|---|---|---|---|
JOSE_VerifySignature_RS256 |
21071.103041280923 ns/iter |
22168.73600228386 ns/iter |
0.95 |
JOSE_VerifySignature_ES512 |
466519.0885485975 ns/iter |
575824.785655401 ns/iter |
0.81 |
GZIP_Compress_ISO_Language_Set_3_Locations |
26476786.55555473 ns/iter |
36602686.21052715 ns/iter |
0.72 |
GZIP_Decompress_ISO_Language_Set_3_Locations |
3448309.256157665 ns/iter |
4479699.645962619 ns/iter |
0.77 |
GZIP_Compress_ISO_Language_Set_3_Schema |
1707527.60396036 ns/iter |
2045148.792397603 ns/iter |
0.83 |
GZIP_Decompress_ISO_Language_Set_3_Schema |
320745.0487693666 ns/iter |
377041.39160840074 ns/iter |
0.85 |
HTML_Build_Table_100000 |
51040909.090909794 ns/iter |
56098712.81818228 ns/iter |
0.91 |
HTML_Render_Table_100000 |
2824349.185185204 ns/iter |
1864473.5848564103 ns/iter |
1.51 |
JSONLD_Catalog_Annotation_List_Populate |
656927.5982986961 ns/iter |
682573.2987141616 ns/iter |
0.96 |
JSONLD_Catalog_Materialize |
2900416.8185653524 ns/iter |
3895880.8814433347 ns/iter |
0.74 |
JSONL_Parse_Large |
8036881.399999963 ns/iter |
10247471.985294128 ns/iter |
0.78 |
JSONL_Parse_Large_GZIP |
9471330.864865063 ns/iter |
11492513.399999876 ns/iter |
0.82 |
URITemplateRouter_Create |
16140.247686369505 ns/iter |
20735.42503178535 ns/iter |
0.78 |
URITemplateRouter_Match |
146.20191406133026 ns/iter |
158.59236711435344 ns/iter |
0.92 |
URITemplateRouter_Match_BasePath |
167.63516755104374 ns/iter |
185.39004185093162 ns/iter |
0.90 |
URITemplateRouterView_Restore |
3329.594115327161 ns/iter |
8542.901270677374 ns/iter |
0.39 |
URITemplateRouterView_Match |
115.16411673383227 ns/iter |
124.60717971098747 ns/iter |
0.92 |
URITemplateRouterView_Match_BasePath |
130.68642744194293 ns/iter |
149.79254041069632 ns/iter |
0.87 |
URITemplateRouterView_Arguments |
429.24556741550117 ns/iter |
472.20331860405497 ns/iter |
0.91 |
JSONPath_Descendant_Filter_Nested |
1245.1496741624896 ns/iter |
1655.4100411068055 ns/iter |
0.75 |
Pointer_Object_Traverse |
22.88028188973464 ns/iter |
24.955895090058895 ns/iter |
0.92 |
Pointer_Object_Try_Traverse |
22.238742489000455 ns/iter |
23.073865397331247 ns/iter |
0.96 |
Pointer_Push_Back_Pointer_To_Weak_Pointer |
102.18576541462599 ns/iter |
134.2793633854266 ns/iter |
0.76 |
Pointer_Walker_Schema_ISO_Language |
1746798.1721518852 ns/iter |
1420500.0349076653 ns/iter |
1.23 |
Pointer_Maybe_Tracked_Deeply_Nested/0 |
1067840.1951219689 ns/iter |
1197967.135042718 ns/iter |
0.89 |
Pointer_Maybe_Tracked_Deeply_Nested/1 |
1624954.1971831147 ns/iter |
1709229.9583332944 ns/iter |
0.95 |
Pointer_Position_Tracker_Get_Deeply_Nested |
614.6787850057785 ns/iter |
603.1558068275378 ns/iter |
1.02 |
JSON_Array_Of_Objects_Unique |
393.66460812023877 ns/iter |
462.6222457403554 ns/iter |
0.85 |
JSON_Parse_1 |
4386.3310466984685 ns/iter |
5304.890191776696 ns/iter |
0.83 |
JSON_Parse_Real |
4877.672941660177 ns/iter |
5763.412002758096 ns/iter |
0.85 |
JSON_Parse_Decimal |
7512.783164584031 ns/iter |
10491.900496470254 ns/iter |
0.72 |
JSON_Parse_Schema_ISO_Language |
3195938.8571427315 ns/iter |
3576844.4744899375 ns/iter |
0.89 |
JSON_Parse_Integer |
3070.6479342959374 ns/iter |
3725.773345871975 ns/iter |
0.82 |
JSON_Parse_String_NonSSO_Plain |
2613.852538093994 ns/iter |
3250.6351891068334 ns/iter |
0.80 |
JSON_Parse_String_SSO_Plain |
2476.0586464409425 ns/iter |
3029.4476410461193 ns/iter |
0.82 |
JSON_Parse_String_Escape_Heavy |
15527.141986538034 ns/iter |
16650.853609864756 ns/iter |
0.93 |
JSON_Parse_Object_Short_Keys |
7247.410212277495 ns/iter |
8518.830630258033 ns/iter |
0.85 |
JSON_Parse_Object_Scalar_Properties |
3683.794423801606 ns/iter |
4254.636795176433 ns/iter |
0.87 |
JSON_Parse_Object_Array_Properties |
5416.489344435986 ns/iter |
6384.291846979531 ns/iter |
0.85 |
JSON_Parse_Object_Object_Properties |
5602.312909549145 ns/iter |
6435.600922065288 ns/iter |
0.87 |
JSON_Parse_Nested_Containers |
35011.63379509627 ns/iter |
39241.481976941024 ns/iter |
0.89 |
JSON_From_String_Copy |
7.953998823082765 ns/iter |
8.541109917515547 ns/iter |
0.93 |
JSON_From_String_Temporary |
5.792509354437904 ns/iter |
7.195135502522248 ns/iter |
0.81 |
JSON_Number_To_Double |
22.142605071907823 ns/iter |
20.5931530914767 ns/iter |
1.08 |
JSON_Object_At_Last_Key/8 |
5.054640270618098 ns/iter |
3.740966817134817 ns/iter |
1.35 |
JSON_Object_At_Last_Key/32 |
12.607684011529523 ns/iter |
11.875825254297645 ns/iter |
1.06 |
JSON_Object_At_Last_Key/128 |
47.84653641657133 ns/iter |
48.61466721780844 ns/iter |
0.98 |
JSON_Object_At_Last_Key/512 |
199.553682997506 ns/iter |
358.6214680756582 ns/iter |
0.56 |
JSON_Fast_Hash_Helm_Chart_Lock |
69.06960047587579 ns/iter |
72.90800160644454 ns/iter |
0.95 |
JSON_Equality_Helm_Chart_Lock |
126.14893616643806 ns/iter |
159.35949733444755 ns/iter |
0.79 |
JSON_Divisible_By_Decimal |
236.97306271150833 ns/iter |
258.5633901520767 ns/iter |
0.92 |
JSON_String_Equal/10 |
5.063390647603061 ns/iter |
5.6057604155002405 ns/iter |
0.90 |
JSON_String_Equal/100 |
6.484986280752266 ns/iter |
5.997799175596543 ns/iter |
1.08 |
JSON_String_Equal_Small_By_Perfect_Hash/10 |
0.8638807095511225 ns/iter |
0.7401395456929125 ns/iter |
1.17 |
JSON_String_Equal_Small_By_Runtime_Perfect_Hash/10 |
15.860327883098943 ns/iter |
25.193945834278477 ns/iter |
0.63 |
JSON_String_Fast_Hash/10 |
3.030717693764483 ns/iter |
3.1505706960083586 ns/iter |
0.96 |
JSON_String_Fast_Hash/100 |
3.2218787818737864 ns/iter |
3.1535313836592236 ns/iter |
1.02 |
JSON_String_Key_Hash/10 |
1.8086852728366132 ns/iter |
1.6187619382516643 ns/iter |
1.12 |
JSON_String_Key_Hash/100 |
12.210869522851999 ns/iter |
12.442259240722402 ns/iter |
0.98 |
JSON_Object_Defines_Miss_Same_Length |
2.843447339939471 ns/iter |
3.4242507160808864 ns/iter |
0.83 |
JSON_Object_Defines_Miss_Too_Small |
3.100896576816061 ns/iter |
3.1128754726283754 ns/iter |
1.00 |
JSON_Object_Defines_Miss_Too_Large |
2.835455490923495 ns/iter |
3.4567758997792066 ns/iter |
0.82 |
Regex_Lower_S_Or_Upper_S_Asterisk |
0.9264159724782799 ns/iter |
0.6232169906727918 ns/iter |
1.49 |
Regex_Caret_Lower_S_Or_Upper_S_Asterisk_Dollar |
0.9229827542268747 ns/iter |
0.623374527852774 ns/iter |
1.48 |
Regex_Period_Asterisk |
0.9029950807190337 ns/iter |
0.6255115084456976 ns/iter |
1.44 |
Regex_Group_Period_Asterisk_Group |
0.8892254210186152 ns/iter |
0.6229714710461275 ns/iter |
1.43 |
Regex_Period_Plus |
0.8808295104291688 ns/iter |
0.6228164155608633 ns/iter |
1.41 |
Regex_Period |
0.8920026080954232 ns/iter |
0.6231607391036613 ns/iter |
1.43 |
Regex_Caret_Period_Plus_Dollar |
0.899131179048035 ns/iter |
0.6236413821478847 ns/iter |
1.44 |
Regex_Caret_Group_Period_Plus_Group_Dollar |
0.9020337696973302 ns/iter |
0.6231896545836457 ns/iter |
1.45 |
Regex_Caret_Period_Asterisk_Dollar |
0.9040450349496184 ns/iter |
0.6228193654385223 ns/iter |
1.45 |
Regex_Caret_Group_Period_Asterisk_Group_Dollar |
0.9333082699554919 ns/iter |
0.6225401001982364 ns/iter |
1.50 |
Regex_Caret_X_Hyphen |
2.8632564341079028 ns/iter |
3.738022607170993 ns/iter |
0.77 |
Regex_Period_Md_Dollar |
16.00905710212351 ns/iter |
28.140922140727955 ns/iter |
0.57 |
Regex_Caret_Slash_Period_Asterisk |
2.88812909484237 ns/iter |
4.04484038140929 ns/iter |
0.71 |
Regex_Caret_Period_Range_Dollar |
1.5053512340977706 ns/iter |
1.2457892720150332 ns/iter |
1.21 |
Regex_Nested_Backtrack |
33.26179130494241 ns/iter |
37.43869455547715 ns/iter |
0.89 |
This comment was automatically generated by workflow using github-action-benchmark.
There was a problem hiding this comment.
2 issues found across 11 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/lang/memory/include/sourcemeta/core/memory_owned_or_reference.h">
<violation number="1" location="src/lang/memory/include/sourcemeta/core/memory_owned_or_reference.h:79">
P1: When a borrowed `OwnedOrReference` points at the destination’s current `owned_` value, the defaulted move assignment destroys that value before copying the borrowed pointer, leaving `referenced_` dangling. Implement a custom move assignment that detects this aliasing case before replacing `owned_`.</violation>
<violation number="2" location="src/lang/memory/include/sourcemeta/core/memory_owned_or_reference.h:103">
P3: `to_owned() &&` is disabled for the move-only types that this type explicitly supports, so an owned move-only value can never be extracted even though the owned branch only needs a move. After construction, `Ownable` accepts any `std::move_constructible` object (and the tests target a `MoveOnly` type and a `holds_a_move_only_value` case), but calling `to_owned()` on such an `OwnedOrReference` fails to compile because the whole overload is gated on `std::copy_constructible<T>`. Only the referenced branch (`return *this->referenced_;`) actually needs copyability; the owned branch (`std::move(this->owned_).value()`) needs only a move. This contradicts the method's stated contract ("moving out of this one when it owns it"). Requiring copyability should be scoped to the referenced-copy path, not the whole function, so owned move-only values can be moved out.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| /// Move | ||
| OwnedOrReference(OwnedOrReference &&) = default; | ||
| /// Move | ||
| auto operator=(OwnedOrReference &&) -> OwnedOrReference & = default; |
There was a problem hiding this comment.
P1: When a borrowed OwnedOrReference points at the destination’s current owned_ value, the defaulted move assignment destroys that value before copying the borrowed pointer, leaving referenced_ dangling. Implement a custom move assignment that detects this aliasing case before replacing owned_.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lang/memory/include/sourcemeta/core/memory_owned_or_reference.h, line 79:
<comment>When a borrowed `OwnedOrReference` points at the destination’s current `owned_` value, the defaulted move assignment destroys that value before copying the borrowed pointer, leaving `referenced_` dangling. Implement a custom move assignment that detects this aliasing case before replacing `owned_`.</comment>
<file context>
@@ -0,0 +1,120 @@
+ /// Move
+ OwnedOrReference(OwnedOrReference &&) = default;
+ /// Move
+ auto operator=(OwnedOrReference &&) -> OwnedOrReference & = default;
+ ~OwnedOrReference() = default;
+
</file context>
| auto operator=(OwnedOrReference &&) -> OwnedOrReference & = default; | |
| auto operator=(OwnedOrReference &&other) -> OwnedOrReference & { | |
| if (this == &other) { | |
| return *this; | |
| } | |
| if (this->owned_.has_value() && | |
| other.referenced_ == &this->owned_.value()) { | |
| return *this; | |
| } | |
| this->owned_ = std::move(other.owned_); | |
| this->referenced_ = other.referenced_; | |
| return *this; | |
| } |
| /// Get a value the caller owns, moving out of this one when it owns it and | ||
| /// copying only when it holds a reference | ||
| [[nodiscard]] auto to_owned() && -> T | ||
| requires std::copy_constructible<T> |
There was a problem hiding this comment.
P3: to_owned() && is disabled for the move-only types that this type explicitly supports, so an owned move-only value can never be extracted even though the owned branch only needs a move. After construction, Ownable accepts any std::move_constructible object (and the tests target a MoveOnly type and a holds_a_move_only_value case), but calling to_owned() on such an OwnedOrReference fails to compile because the whole overload is gated on std::copy_constructible<T>. Only the referenced branch (return *this->referenced_;) actually needs copyability; the owned branch (std::move(this->owned_).value()) needs only a move. This contradicts the method's stated contract ("moving out of this one when it owns it"). Requiring copyability should be scoped to the referenced-copy path, not the whole function, so owned move-only values can be moved out.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/lang/memory/include/sourcemeta/core/memory_owned_or_reference.h, line 103:
<comment>`to_owned() &&` is disabled for the move-only types that this type explicitly supports, so an owned move-only value can never be extracted even though the owned branch only needs a move. After construction, `Ownable` accepts any `std::move_constructible` object (and the tests target a `MoveOnly` type and a `holds_a_move_only_value` case), but calling `to_owned()` on such an `OwnedOrReference` fails to compile because the whole overload is gated on `std::copy_constructible<T>`. Only the referenced branch (`return *this->referenced_;`) actually needs copyability; the owned branch (`std::move(this->owned_).value()`) needs only a move. This contradicts the method's stated contract ("moving out of this one when it owns it"). Requiring copyability should be scoped to the referenced-copy path, not the whole function, so owned move-only values can be moved out.</comment>
<file context>
@@ -0,0 +1,120 @@
+ /// Get a value the caller owns, moving out of this one when it owns it and
+ /// copying only when it holds a reference
+ [[nodiscard]] auto to_owned() && -> T
+ requires std::copy_constructible<T>
+ {
+ assert(this->has_value());
</file context>
There was a problem hiding this comment.
Benchmark (windows/msvc)
Details
| Benchmark suite | Current: fd12d23 | Previous: f69eafb | Ratio |
|---|---|---|---|
Regex_Lower_S_Or_Upper_S_Asterisk |
3.9210803571425905 ns/iter |
5.024749999999958 ns/iter |
0.78 |
Regex_Caret_Lower_S_Or_Upper_S_Asterisk_Dollar |
3.8422451854326 ns/iter |
5.039869999999951 ns/iter |
0.76 |
Regex_Period_Asterisk |
3.8433921359943346 ns/iter |
5.104368000000363 ns/iter |
0.75 |
Regex_Group_Period_Asterisk_Group |
3.849516183035893 ns/iter |
5.050395000000094 ns/iter |
0.76 |
Regex_Period_Plus |
3.590000886446534 ns/iter |
4.901311050201313 ns/iter |
0.73 |
Regex_Period |
3.567796445317923 ns/iter |
4.829895492149502 ns/iter |
0.74 |
Regex_Caret_Period_Plus_Dollar |
3.5673051283551205 ns/iter |
4.774575892857363 ns/iter |
0.75 |
Regex_Caret_Group_Period_Plus_Group_Dollar |
3.5825806194025187 ns/iter |
4.8221205357142445 ns/iter |
0.74 |
Regex_Caret_Period_Asterisk_Dollar |
3.841714285714686 ns/iter |
5.048033035714233 ns/iter |
0.76 |
Regex_Caret_Group_Period_Asterisk_Group_Dollar |
3.8879212430571304 ns/iter |
5.091234000000213 ns/iter |
0.76 |
Regex_Caret_X_Hyphen |
6.040900000000095 ns/iter |
8.175871651785776 ns/iter |
0.74 |
Regex_Period_Md_Dollar |
41.27493514726769 ns/iter |
47.24996087611785 ns/iter |
0.87 |
Regex_Caret_Slash_Period_Asterisk |
5.846497321428501 ns/iter |
7.925393973214742 ns/iter |
0.74 |
Regex_Caret_Period_Range_Dollar |
4.1489110026121265 ns/iter |
5.707647321428462 ns/iter |
0.73 |
Regex_Nested_Backtrack |
67.8650223214307 ns/iter |
60.306741071432924 ns/iter |
1.13 |
JSON_Array_Of_Objects_Unique |
520.52249999997 ns/iter |
617.7195535714069 ns/iter |
0.84 |
JSON_Parse_1 |
7269.200892857494 ns/iter |
8856.608258928565 ns/iter |
0.82 |
JSON_Parse_Real |
12800.46964285678 ns/iter |
16285.88405725899 ns/iter |
0.79 |
JSON_Parse_Decimal |
8602.170758928043 ns/iter |
11819.441071427913 ns/iter |
0.73 |
JSON_Parse_Schema_ISO_Language |
6224133.928572176 ns/iter |
7581362.499999602 ns/iter |
0.82 |
JSON_Parse_Integer |
4618.730863590205 ns/iter |
6532.235714285914 ns/iter |
0.71 |
JSON_Parse_String_NonSSO_Plain |
6234.216071428632 ns/iter |
8463.765786759643 ns/iter |
0.74 |
JSON_Parse_String_SSO_Plain |
2860.6355682412714 ns/iter |
3941.759486606942 ns/iter |
0.73 |
JSON_Parse_String_Escape_Heavy |
16764.519851693414 ns/iter |
21877.921428570957 ns/iter |
0.77 |
JSON_Parse_Object_Short_Keys |
10081.59374999984 ns/iter |
13252.89284422798 ns/iter |
0.76 |
JSON_Parse_Object_Scalar_Properties |
5310.4589285715465 ns/iter |
6884.277678571391 ns/iter |
0.77 |
JSON_Parse_Object_Array_Properties |
9425.332476194255 ns/iter |
11566.26071428641 ns/iter |
0.81 |
JSON_Parse_Object_Object_Properties |
9201.818741880465 ns/iter |
11791.764062500042 ns/iter |
0.78 |
JSON_Parse_Nested_Containers |
64742.16964285517 ns/iter |
85035.596625149 ns/iter |
0.76 |
JSON_From_String_Copy |
49.49065000000701 ns/iter |
65.88318749999797 ns/iter |
0.75 |
JSON_From_String_Temporary |
63.093044642863156 ns/iter |
57.920276785716446 ns/iter |
1.09 |
JSON_Number_To_Double |
104.7771874999981 ns/iter |
121.2326071428598 ns/iter |
0.86 |
JSON_Object_At_Last_Key/8 |
5.724864285714456 ns/iter |
7.5677330019297715 ns/iter |
0.76 |
JSON_Object_At_Last_Key/32 |
21.206244480440766 ns/iter |
23.22128545512 ns/iter |
0.91 |
JSON_Object_At_Last_Key/128 |
72.10700892856485 ns/iter |
89.30167904902942 ns/iter |
0.81 |
JSON_Object_At_Last_Key/512 |
333.1273176761385 ns/iter |
426.32759563155287 ns/iter |
0.78 |
JSON_Fast_Hash_Helm_Chart_Lock |
86.37854078667735 ns/iter |
104.13150000000648 ns/iter |
0.83 |
JSON_Equality_Helm_Chart_Lock |
158.34216517855992 ns/iter |
208.96988352812616 ns/iter |
0.76 |
JSON_Divisible_By_Decimal |
309.22531250001026 ns/iter |
306.5139285714074 ns/iter |
1.01 |
JSON_String_Equal/10 |
7.688246651786912 ns/iter |
10.522024506598724 ns/iter |
0.73 |
JSON_String_Equal/100 |
8.788367187499343 ns/iter |
11.69776428571469 ns/iter |
0.75 |
JSON_String_Equal_Small_By_Perfect_Hash/10 |
1.6640739936784816 ns/iter |
2.5134799999999506 ns/iter |
0.66 |
JSON_String_Equal_Small_By_Runtime_Perfect_Hash/10 |
12.935489285713484 ns/iter |
15.17211354833869 ns/iter |
0.85 |
JSON_String_Fast_Hash/10 |
5.055174999999963 ns/iter |
6.588872321428495 ns/iter |
0.77 |
JSON_String_Fast_Hash/100 |
5.052106000000549 ns/iter |
6.760481249999982 ns/iter |
0.75 |
JSON_String_Key_Hash/10 |
3.8880223214286604 ns/iter |
5.466966964285344 ns/iter |
0.71 |
JSON_String_Key_Hash/100 |
8.495994604928846 ns/iter |
11.919400000000024 ns/iter |
0.71 |
JSON_Object_Defines_Miss_Same_Length |
3.641963744308988 ns/iter |
4.732809385564335 ns/iter |
0.77 |
JSON_Object_Defines_Miss_Too_Small |
3.5885585658211316 ns/iter |
4.716897724267261 ns/iter |
0.76 |
JSON_Object_Defines_Miss_Too_Large |
3.5935395033132633 ns/iter |
4.756082153473515 ns/iter |
0.76 |
Pointer_Object_Traverse |
52.033269999992626 ns/iter |
68.41795758928245 ns/iter |
0.76 |
Pointer_Object_Try_Traverse |
52.85595999999941 ns/iter |
71.22494419642729 ns/iter |
0.74 |
Pointer_Push_Back_Pointer_To_Weak_Pointer |
124.72726785714728 ns/iter |
163.03528323897902 ns/iter |
0.77 |
Pointer_Walker_Schema_ISO_Language |
8904001.333333628 ns/iter |
11125637.500000047 ns/iter |
0.80 |
Pointer_Maybe_Tracked_Deeply_Nested/0 |
1872404.2895443523 ns/iter |
2436154.062499973 ns/iter |
0.77 |
Pointer_Maybe_Tracked_Deeply_Nested/1 |
2861764.6586344633 ns/iter |
3835913.9037431017 ns/iter |
0.75 |
Pointer_Position_Tracker_Get_Deeply_Nested |
482.3010714285861 ns/iter |
556.1126449475712 ns/iter |
0.87 |
JSONPath_Descendant_Filter_Nested |
2000.9393090841465 ns/iter |
2401.606136600345 ns/iter |
0.83 |
URITemplateRouter_Create |
30054.022647271064 ns/iter |
40652.521618013125 ns/iter |
0.74 |
URITemplateRouter_Match |
182.34583363922837 ns/iter |
233.0949516635023 ns/iter |
0.78 |
URITemplateRouter_Match_BasePath |
205.13334867262415 ns/iter |
268.1218490233 ns/iter |
0.77 |
URITemplateRouterView_Restore |
20674.18369806665 ns/iter |
34701.52229424505 ns/iter |
0.60 |
URITemplateRouterView_Match |
140.16452722478883 ns/iter |
187.22097012639594 ns/iter |
0.75 |
URITemplateRouterView_Match_BasePath |
157.66885430817402 ns/iter |
209.41973298389678 ns/iter |
0.75 |
URITemplateRouterView_Arguments |
467.8917562258587 ns/iter |
545.6003571428677 ns/iter |
0.86 |
JSONL_Parse_Large |
25685260.71428729 ns/iter |
32825690.00000137 ns/iter |
0.78 |
JSONL_Parse_Large_GZIP |
27527123.076923158 ns/iter |
33705300.00000014 ns/iter |
0.82 |
JSONLD_Catalog_Annotation_List_Populate |
2639146.785714226 ns/iter |
3199604.4642857513 ns/iter |
0.82 |
JSONLD_Catalog_Materialize |
6918263.333333622 ns/iter |
9994486.666666945 ns/iter |
0.69 |
HTML_Build_Table_100000 |
75006128.57143097 ns/iter |
92506033.3333363 ns/iter |
0.81 |
HTML_Render_Table_100000 |
6815714.44444368 ns/iter |
7905402.222221862 ns/iter |
0.86 |
GZIP_Compress_ISO_Language_Set_3_Locations |
29958700.000001956 ns/iter |
35828585.000001565 ns/iter |
0.84 |
GZIP_Decompress_ISO_Language_Set_3_Locations |
7515069.999999469 ns/iter |
10095424.44444441 ns/iter |
0.74 |
GZIP_Compress_ISO_Language_Set_3_Schema |
1764776.5217391325 ns/iter |
2095171.3043478262 ns/iter |
0.84 |
GZIP_Decompress_ISO_Language_Set_3_Schema |
411038.5602678386 ns/iter |
649494.5535714233 ns/iter |
0.63 |
JOSE_VerifySignature_RS256 |
18434.63155920946 ns/iter |
25305.96889327253 ns/iter |
0.73 |
JOSE_VerifySignature_ES512 |
1227829.910714208 ns/iter |
1415023.6401673697 ns/iter |
0.87 |
This comment was automatically generated by workflow using github-action-benchmark.
There was a problem hiding this comment.
Benchmark (macos/llvm)
Details
| Benchmark suite | Current: fd12d23 | Previous: f69eafb | Ratio |
|---|---|---|---|
Regex_Lower_S_Or_Upper_S_Asterisk |
2.3867209133283755 ns/iter |
2.0456059220173115 ns/iter |
1.17 |
Regex_Caret_Lower_S_Or_Upper_S_Asterisk_Dollar |
2.6431290066665074 ns/iter |
2.0452476315346453 ns/iter |
1.29 |
Regex_Period_Asterisk |
2.5568264291035496 ns/iter |
2.5009608730568424 ns/iter |
1.02 |
Regex_Group_Period_Asterisk_Group |
2.864939910512583 ns/iter |
2.179354415634096 ns/iter |
1.31 |
Regex_Period_Plus |
2.9096944256060455 ns/iter |
2.28771534496926 ns/iter |
1.27 |
Regex_Period |
2.799722848420279 ns/iter |
2.6628584310689933 ns/iter |
1.05 |
Regex_Caret_Period_Plus_Dollar |
3.0114965006738363 ns/iter |
2.4054926925145868 ns/iter |
1.25 |
Regex_Caret_Group_Period_Plus_Group_Dollar |
2.946371440027684 ns/iter |
2.395518440595729 ns/iter |
1.23 |
Regex_Caret_Period_Asterisk_Dollar |
2.131975493600361 ns/iter |
1.8347259164275478 ns/iter |
1.16 |
Regex_Caret_Group_Period_Asterisk_Group_Dollar |
2.083278085136973 ns/iter |
1.797178047813772 ns/iter |
1.16 |
Regex_Caret_X_Hyphen |
8.405205856979125 ns/iter |
6.740246688050831 ns/iter |
1.25 |
Regex_Period_Md_Dollar |
26.77673413796163 ns/iter |
20.464533922868473 ns/iter |
1.31 |
Regex_Caret_Slash_Period_Asterisk |
5.596119757038301 ns/iter |
5.132361751572248 ns/iter |
1.09 |
Regex_Caret_Period_Range_Dollar |
2.4546618012948342 ns/iter |
2.7354036856988047 ns/iter |
0.90 |
Regex_Nested_Backtrack |
35.068877923416416 ns/iter |
32.57294213884443 ns/iter |
1.08 |
JSON_Array_Of_Objects_Unique |
431.28069954533055 ns/iter |
473.2361072633566 ns/iter |
0.91 |
JSON_Parse_1 |
3728.717513798881 ns/iter |
3252.4578060595795 ns/iter |
1.15 |
JSON_Parse_Real |
6682.108750730934 ns/iter |
5861.0113280632 ns/iter |
1.14 |
JSON_Parse_Decimal |
6924.699839959067 ns/iter |
5992.693714606234 ns/iter |
1.16 |
JSON_Parse_Schema_ISO_Language |
2636325.5813952344 ns/iter |
2256450.6201297487 ns/iter |
1.17 |
JSON_Parse_Integer |
3893.538503593381 ns/iter |
3953.051638555308 ns/iter |
0.98 |
JSON_Parse_String_NonSSO_Plain |
4244.786364957911 ns/iter |
3221.6134049948196 ns/iter |
1.32 |
JSON_Parse_String_SSO_Plain |
2009.2190146736993 ns/iter |
1876.0166265419778 ns/iter |
1.07 |
JSON_Parse_String_Escape_Heavy |
18421.10830231201 ns/iter |
16712.046981131967 ns/iter |
1.10 |
JSON_Parse_Object_Short_Keys |
6441.718509145454 ns/iter |
5934.6966207394435 ns/iter |
1.09 |
JSON_Parse_Object_Scalar_Properties |
3741.7173378942575 ns/iter |
3217.207853609046 ns/iter |
1.16 |
JSON_Parse_Object_Array_Properties |
4525.1871176784225 ns/iter |
4470.884732619589 ns/iter |
1.01 |
JSON_Parse_Object_Object_Properties |
5947.423847280208 ns/iter |
4482.062750574556 ns/iter |
1.33 |
JSON_Parse_Nested_Containers |
34943.0866912615 ns/iter |
27725.897877057803 ns/iter |
1.26 |
JSON_From_String_Copy |
15.377269155974682 ns/iter |
11.34249831127692 ns/iter |
1.36 |
JSON_From_String_Temporary |
8.842302466466426 ns/iter |
6.380137518947387 ns/iter |
1.39 |
JSON_Number_To_Double |
46.45669392202549 ns/iter |
32.91845115838117 ns/iter |
1.41 |
JSON_Object_At_Last_Key/8 |
5.8343627798247 ns/iter |
4.489450462725714 ns/iter |
1.30 |
JSON_Object_At_Last_Key/32 |
16.701991931891214 ns/iter |
12.3718377885963 ns/iter |
1.35 |
JSON_Object_At_Last_Key/128 |
69.53502297475747 ns/iter |
51.4765087456422 ns/iter |
1.35 |
JSON_Object_At_Last_Key/512 |
256.7698626904572 ns/iter |
194.3015503399055 ns/iter |
1.32 |
JSON_Fast_Hash_Helm_Chart_Lock |
80.85902234235792 ns/iter |
57.776354252998395 ns/iter |
1.40 |
JSON_Equality_Helm_Chart_Lock |
200.9917505797505 ns/iter |
254.65917104092426 ns/iter |
0.79 |
JSON_Divisible_By_Decimal |
216.94006239919634 ns/iter |
238.37574860440841 ns/iter |
0.91 |
JSON_String_Equal/10 |
8.851035335151444 ns/iter |
7.277372572351919 ns/iter |
1.22 |
JSON_String_Equal/100 |
8.684726288942505 ns/iter |
7.235708582365523 ns/iter |
1.20 |
JSON_String_Equal_Small_By_Perfect_Hash/10 |
0.4522976185381608 ns/iter |
0.34914362123138704 ns/iter |
1.30 |
JSON_String_Equal_Small_By_Runtime_Perfect_Hash/10 |
4.19291462926328 ns/iter |
3.456199510526342 ns/iter |
1.21 |
JSON_String_Fast_Hash/10 |
2.9210535932591113 ns/iter |
2.529583127198354 ns/iter |
1.15 |
JSON_String_Fast_Hash/100 |
2.6141902030697493 ns/iter |
2.127181778849073 ns/iter |
1.23 |
JSON_String_Key_Hash/10 |
2.1040018033418355 ns/iter |
1.7098583089768613 ns/iter |
1.23 |
JSON_String_Key_Hash/100 |
3.4159161400993403 ns/iter |
2.163355336516792 ns/iter |
1.58 |
JSON_Object_Defines_Miss_Same_Length |
3.3878134604943138 ns/iter |
2.7882342716737547 ns/iter |
1.22 |
JSON_Object_Defines_Miss_Too_Small |
3.396112082369174 ns/iter |
2.8069571742445962 ns/iter |
1.21 |
JSON_Object_Defines_Miss_Too_Large |
3.528461075870622 ns/iter |
3.2421338610692754 ns/iter |
1.09 |
Pointer_Object_Traverse |
34.1498766929562 ns/iter |
22.05794298697649 ns/iter |
1.55 |
Pointer_Object_Try_Traverse |
54.63189278710827 ns/iter |
35.18567376680917 ns/iter |
1.55 |
Pointer_Push_Back_Pointer_To_Weak_Pointer |
224.1155437428089 ns/iter |
153.80970494151993 ns/iter |
1.46 |
Pointer_Walker_Schema_ISO_Language |
2656932.84927528 ns/iter |
1557602.0114942812 ns/iter |
1.71 |
Pointer_Maybe_Tracked_Deeply_Nested/0 |
1422971.7874793322 ns/iter |
965430.0430504214 ns/iter |
1.47 |
Pointer_Maybe_Tracked_Deeply_Nested/1 |
1988653.8396944688 ns/iter |
1795878.211469525 ns/iter |
1.11 |
Pointer_Position_Tracker_Get_Deeply_Nested |
579.5936785740672 ns/iter |
424.78145550398057 ns/iter |
1.36 |
JSONPath_Descendant_Filter_Nested |
1831.1436469823157 ns/iter |
1921.6447521746002 ns/iter |
0.95 |
URITemplateRouter_Create |
29005.75357253876 ns/iter |
22042.533917952325 ns/iter |
1.32 |
URITemplateRouter_Match |
251.67239226069677 ns/iter |
188.09924584739997 ns/iter |
1.34 |
URITemplateRouter_Match_BasePath |
301.8739663992706 ns/iter |
241.87277313778387 ns/iter |
1.25 |
URITemplateRouterView_Restore |
15648.950223357642 ns/iter |
15308.733682657947 ns/iter |
1.02 |
URITemplateRouterView_Match |
186.40638090000138 ns/iter |
152.3092037331676 ns/iter |
1.22 |
URITemplateRouterView_Match_BasePath |
258.2211872264604 ns/iter |
181.38108522503865 ns/iter |
1.42 |
URITemplateRouterView_Arguments |
837.2820122445922 ns/iter |
631.9120423299361 ns/iter |
1.32 |
JSONL_Parse_Large |
11785412.573770327 ns/iter |
7573868.46078357 ns/iter |
1.56 |
JSONL_Parse_Large_GZIP |
12643840.957746083 ns/iter |
8604866.296702942 ns/iter |
1.47 |
JSONLD_Catalog_Annotation_List_Populate |
814429.0849673674 ns/iter |
628961.3911290403 ns/iter |
1.29 |
JSONLD_Catalog_Materialize |
4307095.938271585 ns/iter |
2604757.206766945 ns/iter |
1.65 |
HTML_Build_Table_100000 |
80309515.62498955 ns/iter |
46520212.94444669 ns/iter |
1.73 |
HTML_Render_Table_100000 |
2814177.7777780895 ns/iter |
1968056.233933384 ns/iter |
1.43 |
GZIP_Compress_ISO_Language_Set_3_Locations |
49180431.500003256 ns/iter |
51184684.52381075 ns/iter |
0.96 |
GZIP_Decompress_ISO_Language_Set_3_Locations |
6227147.500000001 ns/iter |
5533016.6086963 ns/iter |
1.13 |
GZIP_Compress_ISO_Language_Set_3_Schema |
2889674.3093525446 ns/iter |
2445990.5495206793 ns/iter |
1.18 |
GZIP_Decompress_ISO_Language_Set_3_Schema |
406554.65032254905 ns/iter |
427601.2968299644 ns/iter |
0.95 |
JOSE_VerifySignature_RS256 |
33653.06799354356 ns/iter |
34387.39399869405 ns/iter |
0.98 |
JOSE_VerifySignature_ES512 |
1686115.5133928005 ns/iter |
1256533.405286506 ns/iter |
1.34 |
This comment was automatically generated by workflow using github-action-benchmark.
Signed-off-by: Juan Cruz Viotti jv@jviotti.com