Skip to content

[Cocoa] Fix deprecated SEL cast in sel_registerName (issue #3186)#3194

Open
HeikoKlare wants to merge 1 commit intoeclipse-platform:masterfrom
HeikoKlare:fix/replace-deprecated-sel-cast-in-sel-registerName
Open

[Cocoa] Fix deprecated SEL cast in sel_registerName (issue #3186)#3194
HeikoKlare wants to merge 1 commit intoeclipse-platform:masterfrom
HeikoKlare:fix/replace-deprecated-sel-cast-in-sel-registerName

Conversation

@HeikoKlare
Copy link
Copy Markdown
Contributor

@HeikoKlare HeikoKlare commented Apr 3, 2026

Issue

Clang emits a -Wcast-of-sel-type deprecation warning in the auto-generated os.c when sel_registerName returns a SEL that is directly cast to jlong:

rc = (jlong)sel_registerName(lparg0);
// warning: cast of type 'SEL _Nonnull' to 'jlong' (aka 'long') is deprecated;
//          use sel_getName instead [-Wcast-of-sel-type]

This warning is part of a broader set of deprecation warnings in the macOS/Cocoa native implementation tracked in issue #3186. Eliminating all such warnings is a prerequisite for enabling -Werror in the native build.

Solution options considered

Several approaches were investigated before arriving at the final solution.

❌ Direct intermediate cast: (jlong)(uintptr_t)sel_registerName(...)

Adding an intermediate uintptr_t cast does not help — the compiler treats any cast from a SEL value to any type (integer or pointer) as deprecated:

warning: cast of type 'SEL _Nonnull' to 'uintptr_t' (aka 'unsigned long') is deprecated;
         use sel_getName instead [-Wcast-of-sel-type]

Same result with void* or const char* as intermediate types — the -Wcast-of-sel-type warning fires for any explicit cast from a SEL value regardless of the target type.

❌ Using sel_getName: (jlong)(uintptr_t)sel_getName(sel_registerName(...))

The compiler's suggestion — routing through sel_getName(SEL) → const char* — eliminates the deprecated cast. This was implemented via flags=no_gen in OS.java and a hand-written function body in os_custom.c. It works correctly, but has two drawbacks: it calls an extra runtime function and moves the implementation out of the auto-generated os.c into os_custom.c, which is harder to maintain.

Note: the build in the aarch64 fragment folder regenerates os.c from OS.java annotations on each run, so any annotation-based approach must work with the compiled JNI generator in the Maven toolchain — not just the source.

✅ Function-pointer cast: ((jlong (*)(const char*))sel_registerName)(lparg0)

The fix applies the same pattern SWT already uses for all objc_msgSend variants. Instead of casting the value returned by sel_registerName, the function pointer itself is cast to declare a different return type:

rc = (jlong)((jlong (*)(const char*))sel_registerName)((const char*)lparg0);

The compiler sees no cast of a SEL value at all — the function is declared (via its retyped pointer) as returning jlong directly. This is semantically safe on all 64-bit Apple platforms where SEL (an 8-byte opaque pointer) and jlong share the same size and representation.

This approach is driven entirely by two JNI generator annotations in OS.java, keeping the implementation inside the auto-generated os.c:

/**
 * @method flags=cast
 * @param selectorName cast=(const char*)
 */
public static final native long sel_registerName(String selectorName);
  • flags=cast — instructs the generator to emit a function-pointer cast rather than a direct call
  • cast=(const char*) — matches the native C parameter type const char* in the cast signature

Changes

  • OS.java: adds @method flags=cast and @param selectorName cast=(const char*) annotations to sel_registerName
  • os.c: updated generated function body (reflects what the generator produces from the new annotations)

Test plan

  • Build natives from the binaries/org.eclipse.swt.cocoa.macosx.aarch64 fragment using mvn clean process-resources -Dnative=cocoa.macosx.aarch64 — confirms the -Wcast-of-sel-type warning is gone
  • Verify the 7 remaining warnings are only the other known deprecated APIs from issue Replace deprecated native methods in macOS implementation #3186:
    • os.c:1102: CFURLCreateFromFSRef — deprecated macOS 10.9
    • os.c:1920: GetCurrentProcess — deprecated macOS 10.9
    • os.c:2119: LSGetApplicationForInfo — deprecated macOS 10.10
    • os.c:4040: NSPrintSavePath — deprecated macOS 10.6
    • os.c:4678: SecPolicySearchCopyNext — deprecated macOS 10.7
    • os.c:4694: SecPolicySearchCreate — deprecated macOS 10.7
    • os.c:4883: passing arguments to a function without a prototype [-Wdeprecated-non-prototype]
  • Run the SWT test suite on macOS to confirm selector dispatch still works correctly across the codebase

Notes

This change was developed with the assistance of Claude Code (claude-sonnet-4-6). Multiple solution approaches were explored interactively, including direct casts, sel_getName routing, no_gen + os_custom.c, and the final function-pointer cast pattern.

Contributes to #3186.

The Clang compiler (-Wcast-of-sel-type) deprecates any direct cast of
the
Objective-C SEL type to an arithmetic or pointer type, recommending the
use
of sel_getName() instead. The warning appeared in os.c:

  rc = (jlong)sel_registerName(lparg0);
  // warning: cast of type 'SEL _Nonnull' to 'jlong' is deprecated;
  //          use sel_getName instead [-Wcast-of-sel-type]

Rather than routing through sel_getName() (which returns a const char*
that would still require an integer cast), the fix applies the same
pattern already used for objc_msgSend throughout SWT: the `flags=cast`
JNI generator annotation, which casts the entire C function pointer to
the desired return type instead of casting the returned value:

  rc = (jlong)((jlong (*)(const char*))sel_registerName)(lparg0);

This avoids any explicit cast of the SEL value itself. The function
pointer cast tells the compiler that the function returns jlong
directly,
bypassing the SEL type in the return position entirely. This is
semantically safe on 64-bit platforms where SEL (a pointer) and jlong
are both 8 bytes with the same bit representation.

The annotation changes in OS.java drive the code generation:
  - @method flags=cast  — use function-pointer-cast call pattern
  - @param selectorName cast=(const char*) — match the native signature
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

Test Results (macos)

   54 files  ±0     54 suites  ±0   5m 37s ⏱️ - 3m 38s
4 531 tests ±0  4 287 ✅ ±0  244 💤 ±0  0 ❌ ±0 
2 130 runs  ±0  2 068 ✅ ±0   62 💤 ±0  0 ❌ ±0 

Results for commit e5dc93d. ± Comparison against base commit d820f7e.

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.

1 participant