Skip to content

fix(codegen): add operator==/operator<< for generated union types - #94

Open
devin-ai-integration[bot] wants to merge 1 commit into
developmentfrom
devin/union-struct-helpers
Open

fix(codegen): add operator==/operator<< for generated union types#94
devin-ai-integration[bot] wants to merge 1 commit into
developmentfrom
devin/union-struct-helpers

Conversation

@devin-ai-integration

Copy link
Copy Markdown

Summary

A STRUCT that contained a UNION-typed member failed to compile because the generated C++ union had no operator== or operator<<, so the struct's own generated comparison and test-display helpers could not resolve.

This change makes every generated union emit:

  • member operator== / operator!= that compare all leaf members (flattening inline anonymous structs used for nested struct overlays).
  • a friend std::ostream& operator<< under #ifdef STRUCPP_TEST so ASSERT_EQ on structs/FBs containing unions can display the value.

Pseudo-diff

union U {
    UDINT_t N;
    struct { BYTE_t b1; BYTE_t b2; BYTE_t b3; BYTE_t b4; } bytes;
    static constexpr std::size_t iec_byte_size = std::max({sizeof(N), sizeof(bytes)});
+   bool operator==(const U& other) const noexcept {
+       return N == other.N &&
+              bytes.b1 == other.bytes.b1 &&
+              bytes.b2 == other.bytes.b2 &&
+              bytes.b3 == other.bytes.b3 &&
+              bytes.b4 == other.bytes.b4;
+   }
+   bool operator!=(const U& other) const noexcept { return !(*this == other); }
+   #ifdef STRUCPP_TEST
+   friend std::ostream& operator<<(std::ostream& os, const U& u) {
+       os << "{N=" << to_display_string(u.N) << ", bytes={b1=" << ... << "}}";
+       return os;
+   }
+   #endif
};

Test coverage

  • Added tests/st-validation/data_types/union_in_struct.st and test_union_in_struct.st, which define a STRUCT containing a UNION and exercise both member access and ASSERT_EQ on the struct variable.

Verification

  • npm run typecheck clean
  • npx eslint src/ --quiet clean
  • npm test: 128 files / 2343 passed
  • Struc-ToolTest1 downstream: 17 files / 51 passed

Closes #92 and the union-related items in #86 / #90.

Link to Devin session: https://app.devin.ai/sessions/01bd5a0c3ebc4e3a93e5228eb07cf11b
Requested by: @wattzor

…structs containing unions compile

- Emit member operator==/!= and a STRUCPP_TEST friend operator<< inside every C++ union.

- Flatten inline anonymous struct members into leaf field comparisons/display fragments.

- Add st-validation regression for a struct containing a union with ASSERT_EQ and member access.

Closes #92 and the union-related gaps in #86/#90.

Co-Authored-By: Simon Atti <wattimedia@gmail.com>
@wattzor wattzor self-assigned this Aug 9, 2026
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@devin-ai-integration

Copy link
Copy Markdown
Author

Verified PR #94 end-to-end — all green.

  • npm run build:tsc-only
  • npm run typecheck
  • npx eslint src/ --quiet
  • tests/integration/st-validation.test.ts -t "data_types/union_in_struct" passes, including ASSERT_EQ(uut.s, uut.s)
  • Full npm test: 128 files / 2346 passed
  • STRUCPP_PATH=... npm test in Struc-ToolTest1: 17 files / 51 passed
  • Adversarial st-validation shapes pass:
    • elementary-only union ASSERT_EQ(uut.u, uut.u)
    • named-struct overlay union ASSERT_EQ(uut.u, uut.u)
    • struct containing a named union ASSERT_EQ(uut.s, uut.s)
  • Generated C++ confirms union UOVERLAY and struct SWITHU emit operator==/operator!= and operator<< (under STRUCPP_TEST) for union and struct members ✅

summary
codegen

Full report: /home/ubuntu/test-report-pr94.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UNION type lacks operator==/to_display_string, breaks any STRUCT containing a union

1 participant