I post again the response of the AI (which has the context window of the analysis.) It refers to my bazel based win10 migration. The full build did compile and link.
Once i have a running build for win10 i port it to trunk.
Enjoy

Peter

Am 13.08.2026 um 03:33 schrieb Damjan Jovanovic:
On Thu, Aug 13, 2026 at 12:00 AM <[email protected]> wrote:


3. Scope: this is a codemaker change, and it cannot be incremental
------------------------------------------------------------------------
The specifications are generated.
InterfaceType::dumpExceptionSpecification()
in codemaker/source/cppumaker/cpputype.cxx writes " throw (" onto every UNO
interface method, so every generated .hpp carries them.

That forces the change to be atomic across the generated/hand-written
boundary.
For a non-destructor virtual function, an override with no specification
may
throw anything -- which is LESS restrictive than a base declaring
throw(RuntimeException), and therefore ill-formed. Strip them from
hand-written
overrides while the generated bases still have them and you simply trade
one
set of errors for another.

So cppumaker and the sources have to move in the same commit. I mention it
because "start removing them a module at a time" is the natural first
instinct
and it does not work.

Yes, cppumaker is probably where this change should be made, and leave Java
alone. Java will still need exception specifications, as will the IDL to
cater for languages such as Java.
Agreed, and that is exactly the shape of it. To be concrete about what moves:

  - codemaker/source/cppumaker/cpputype.cxx  -- changed. The C++ emitter is
    the only thing that stops writing specifications.
  - the .idl files                           -- untouched.
  - the type library (RDB)                   -- untouched. The exception lists
    stay in the type descriptions, which is what javamaker and the other
    language bindings read.
  - javamaker                                -- untouched. Java's throws
    clauses are checked exceptions, a real language feature, not a vestige.

So this is a change to the C++ language binding only. Nothing about the
interface contract as expressed in IDL changes.

One deliberate exception: the EMPTY specification stays. cppumaker still emits throw () where the list would be empty -- that is what acquire() and release() carry. MSVC implements throw() as __declspec(nothrow), and C++17 keeps it as a
deprecated spelling of noexcept. Migrating those to noexcept is the separate
second change I mentioned; mixing it in here would have changed codegen.


4. The good news on compatibility
------------------------------------------------------------------------
Exception specifications do not participate in name mangling, so this is
not
an ABI break.

I don't know if that's completely true on all platforms, see
commits 0a9d806e6889118a07d68c9403d7c84bfac0af44 and
64e326c7e8e93e4234452640047d2d55a6d98111
and fc7f71c8064a223e8598f8729834d18b56bb4bf0. We had to provide exception
type_infos at runtime, and their names had to be visible and mangled,
although the names of the methods throwing them do not list the exceptions
thrown, so maybe it is ABI compatible.
Your last clause is the right conclusion, and I think the three commits are a
different mechanism rather than a counter-example. They are all about the
visibility of type_info symbols for the exception TYPES:

  fc7f71c806  force availability of type_info symbols thrown by ucb (#i124421#)
  64e326c7e8  jvmaccess visibility attributes + gcc3.map/mingw.map exports
  0a9d806e68  component.map cannot be used yet, it does not export RTTI/typeinfos

That requirement comes from throw and catch across DSO boundaries: for
catch (SomeException&) in one library to match an exception thrown in another, both sides must agree on the type_info, hence the exports. It is independent of
whether the function DECLARATION carries a specification.

Removing the specifications does not touch any of that. The exception classes
still need their type_infos exported, exactly as those commits arranged, and
nothing in this change alters a mangled function name -- an exception
specification is not part of the mangled name on either the Itanium ABI or MSVC. So old and new binaries interoperate: the enforcement was always emitted in the
callee, never encoded at the call site.

If anything the pressure goes the other way. With enforced eh-specs the compiler
also emits the list of permitted type_infos into the exception table so that
__cxa_call_unexpected can compare against it -- that is one CONSUMER of those
type_infos, and it disappears. The catch-matching consumer remains, so the
exports stay necessary; we just stop needing them for spec checking too.

Easy to settle empirically rather than by argument: dump the exported symbols of a built library before and after and diff them. If the change is ABI-neutral the
lists are identical. I can do that on my branch and post the result.


It is also backward compatible for extensions: once the bases lose their
specifications, a third-party component that still declares
throw(RuntimeException) on its overrides is merely more restrictive,
which is
legal. External UNO components keep compiling unchanged.


The benefit I see, is that many exceptions are thrown in contradiction of
exception specifications (https://bz.apache.org/ooo/show_bug.cgi?id=127252),
which is why we use "-fno-enforce-eh-specs" with GCC, and why OpenOffice
crashes more often when built with Clang which doesn't have that flag (as
throwing an exception that wasn't declared is a serious error, ending in
unexpected() -> abort()). So we would have a more stable OpenOffice on
FreeBSD (and Mac?), without needing to build with GCC. There would also be
better interoperability between languages, as Java throwing to C++ often
crashes with Clang for the same reason.
This is a much better headline than the one I led with, and I would put it first
in any summary of the change. "Deprecated in C++11, removed in C++17" is a
schedule. "The specifications are false, and we suppress the consequences with a
GCC-only flag" is a defect.

It also matches what I ran into from the other end. On a modern MSVC branch,
three destructors carrying throw(RuntimeException) -- ~OWeakObject,
~OWeakAggObject, ~OComponentHelper -- produce 6,690 errors across 25 modules and 242 classes, because since C++11 a destructor with no written specification is
implicitly noexcept, so any class inheriting from one of those AND from an
ordinary base claims both "may throw" and "will not throw" about the same object. All three bodies are {}. Same underlying problem as #127252: the specifications assert things the code does not honour. One compiler aborts at runtime, another
refuses to compile.

Dropping them lets -fno-enforce-eh-specs go too, which is the concrete win: a Clang build that does not need a GCC flag to survive, and Java-to-C++ propagation
that stops terminating.

Status, in case it is useful: I have part (a) applied on a branch -- 72,490
specification sites across 5,063 files, plus the cppumaker change. Core UNO
(cppu, cppuhelper, comphelper) builds green on both an old and a modern MSVC
toolchain; the full product build on both is still outstanding. Happy to push it
somewhere visible once that passes.

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to