Skip to content

First session notes ‐ unhandled issues found

Marcio Oliveira edited this page Aug 29, 2026 · 3 revisions

Just notes from my session fixing mbeddr.cpp tests and test environment:

A. Gaps/bugs found in mbeddr.cpp itself — not fixed, only worked around or deferred

  1. Generator: free function templates lose template on forward-declared prototypes — templates.mps, commit 0e88c30452. Blocks identity/compare/deref/multiplyBy and their tests; currently commented out.

  2. Generator: template classes with explicit constructors emit spurious, wrongly-qualified duplicate out-of-line definitions in the .cpp — same commit. Constructor-free template classes are unaffected, so this is specific to templates + explicit constructors.

  3. Generator: List/IntList template emission-order issue — same commit, same test area. No model-level workaround found; needs a real generator fix.

  4. Generator: global-using declarations are always emitted as a group ahead of every namespace declaration — namespaces.mps, commit c4b51ee1be. Invalid C++ when the referenced namespace lives in the same file. namespaceGlobalUsing test case commented out pending this.

  5. Nullptr_tType/CPPImplementationModule.importsForHeader() exists and works correctly but is never called from any generator template — nullPointers.mps, commit 62aa36dc3b. Result: (and any other computed std header) never reaches generated output, so std::nullptr_t fails to compile. Explicit TODO left in the commit: wire importsForHeader() into the header-generation template, then restore nullptr_t constructor/field/tests.

  6. Cross-module dependency scanner never emits an #include when a base class lives in another module — classes.mps, commit 0d9d456ee35. Traced to InheritanceInstance not extending TypeWithDeclaration. Worked around by reordering classes into the same module; commit explicitly says "no big changes were made to the language" and flags a need for a dedicated cross-module-inheritance test plus a real language-level fix.

  7. ArrayAttributeInitExpression textGen gap — same commit. Counter.value2 (an array field with this init form) was dropped rather than fixed; needs a textGen rule implementation.

  8. BuildConfiguration-generation-order bug: class visibility sections only generate correctly for pre-existing BuildConfigurations — thisPointer.mps, commit 0845d07b4e. Root cause never isolated ("persisted after trying different experiments"); content commented out rather than fixed.

  9. Constructor initializer lists can directly initialize an inherited field (invalid C++) — the language permits modeling it (permissive scope in ConstructorInitializedAttribute_Constraints) and the generator emits it verbatim with no correction (ConstructorInitializedAttribute_TextGen). The one place this was hit (constructor.mps, commit 020fa9739c) was fixed by reworking the test model, not by closing the underlying gap — the language still lets you model something the C++ generator can't emit correctly.

  10. Typesystem inconsistency: char literals can't initialize char16_t/char32_t/wchar_t globals, but the same types can be compared across each other — chars.mps, commit 80bc3b2026 fixed the editor-crashing NumberFormatException, but left 3 pre-existing ERROR-severity typesystem issues in place ("type char const volatile is not a subtype of ..."). Non-blocking (real g++ accepts the generated code) but a real subtyping-rule gap.

  11. Static.mps/specifier.mps deleted, not fixed — commit b0981b91f1. Used removed language concepts (e.g. StaticVar); root nodes stripped to unblock the rest of the suite. Recoverable from git history once those concepts are ported/replaced.

  12. testExTests doesn't fail the build when generated binaries/Makefiles silently go missing — the main recommendation from the earlier code review, explicitly deferred: "Until tests are not stable, I cannot fail the build when tests disappear."

  13. Shared PlatformTemplates default (-std=c++11) doesn't include -fpermissive — every existing test.ex module already had its own explicit override so this didn't need fixing there, but any newly created BuildConfiguration will silently need -fpermissive added by hand until either the template default is updated or item B below is fixed upstream.

B. Bug that lives in mbeddr (upstream), not mbeddr.cpp — only worked around here

  1. UnitTestUtil_boolToStr in mbeddr.core's bundled unit-test C runtime (com.mbeddr.core.unittest, languageAccessories/runtime.mps) returns C string literals ("true"/"false") from a function declared to return non-const char* — invalid C++ under any -std= version. This is why -fpermissive is permanently required in every test.ex BuildConfiguration, regardless of C++ standard. Confirmed unfixed and unchanged across mbeddr versions from 2022.3.26500.b633ef3 (what we vendor) through the newest 2026.1 branch. Not fixable from mbeddr.cpp — would need a fix or bug report upstream in mbeddr.core; once fixed, -fpermissive could potentially be dropped and -std=c++14+ revisited.

  2. releaseArtifacts' file path is a fragile, stringly-typed reconstruction of the ant-built zip's filename, not a reference to an actual declared Gradle task output. If the ant packaging template's naming convention ever changes independently, this breaks silently at publish/githubRelease time, not at build/check time. Predates this session (introduced 2021). Proper fix requires the BuildLanguages/RunAntScript-wrapped packaging task to declare a real outputs.file(...), a bigger refactor than a one-line fix — same class of "opaque ant-wrapper task type" limitation as the clean/incremental-cache problem.

  3. Open design question: publish and githubRelease still run automatically on every push to main, not on a deliberate release trigger (a version tag, workflow_dispatch, or similar). The duplicate-version conflict this caused is fixed (unique version per run), but whether every commit to main should produce a new package version and a new GitHub Release was never actually decided — left as-is, but worth a real decision later, since otherwise every merged PR permanently adds one more package version and one more GitHub Release, indefinitely.

  4. de.itemis.mps:mps-gradle-plugin's BuildLanguages/RunAntScript task types trigger a Gradle deprecation (Invocation of Task.project at execution time... will fail with an error in Gradle 10). Not fixable from mbeddr.cpp's own build.gradle — it's inside the plugin itself (pinned at 1.30.2.1.649c88d). Worth checking for a newer plugin release, or reporting upstream, before Gradle 10 makes this a hard failure.

  5. Two MPS-generated Java files trigger uses or overrides a deprecated API javac notes (check_ArrayAttributeInitExpression_NonTypesystemRule.java, CPPImplementationModule_Constraints.java). Generated code, so not hand-editable — would need -Xlint:deprecation plus tracing back to whichever generator template/behavior implementation produced it. Low priority.

  6. test.ex fails to build from the MPS IDE unless MPS itself was launched from a terminal. Root cause is almost certainly the classic macOS GUI-launch PATH gap: an app launched via Finder/Dock/Spotlight gets its environment from launchd, which never sources the user's shell startup files (.zshrc/.zprofile) — so Homebrew's /opt/homebrew/bin (where the real g++/make live) isn't on PATH for a GUI-launched MPS, and the IDE's own invocation of the generated Makefile can't find the toolchain (or silently falls back to whatever /usr/bin/g++ resolves to, which may not be the intended compiler at all). Launching MPS from a terminal inherits that shell's exported PATH and works, which is the workaround already in use — but the IDE not working when launched normally (Finder/Dock) remains an open, unresolved gap. A permanent fix would need to inject the right PATH into MPS's own launch environment (e.g. via launchctl setenv, a wrapper .app/launch script, or an MPS-side run-configuration environment override) rather than relying on how the user happens to start the IDE.

Clone this wiki locally