Opened 3 weeks ago
Last modified 41 hours ago
#880 _started defect
Build fails on macOS with Apple Clang 21 ("call to 'makeWindowCallback' is ambiguous") due to duplicate template overloads generated by ConstParamT<T*>
| Reported by: | guest | Owned by: | westram |
|---|---|---|---|
| Priority: | major | Milestone: | |
| Component: | global | Version: | SVN |
| Keywords: | Cc: |
Description (last modified by westram)
Operating system: macOS Tahoe 26.2.5 (also reproduced on an earlier Tahoe point release)
ARB version: 7.0.1, built via the arb-project/arb Homebrew tap (arb@7 formula), both stable and —HEAD
Compiler: Apple Clang 21.0.0 (clang-2100.1.1.101),
Target: x86_64-apple-darwin (built under Rosetta on Apple Silicon; same failure occurs natively on arm64)
Description:
ARB fails to compile with Apple's newest Clang (21.0.0), shipped with macOS Tahoe. The build fails in multiple modules (AWTC, AW_NAME, PROBE_DESIGN, MULTI_PROBE) with errors like:
AWTC_submission.cxx:290:19: error: call to 'makeWindowCallback' is ambiguous 290 | aws->callback(makeWindowCallback(ed_save_var_to_file, AWAR_SUBMIT_PARSED, AWAR_SUBMIT_FILE)); | ^~~~~~~~~~~~~~~~~~ INCLUDE/cb.h:42:1: note: candidate function [with P1 = const char *, P2 = const char *] INCLUDE/cbtypes.h:456:34: note: expanded from macro 'DECLARE_CBTYPE_FVV_AND_BUILDERS' <scratch space>:49:1: note: expanded from here 49 | makeWindowCallback INCLUDE/cb.h:42:1: note: candidate function [with P1 = const char *, P2 = const char *] INCLUDE/cbtypes.h:456:34: note: expanded from macro 'DECLARE_CBTYPE_FVV_AND_BUILDERS' <scratch space>:49:1: note: expanded from here 49 | makeWindowCallback
Similar errors occur for makeRootCallback in AW_names_admin.cxx:137, and for makeWindowCallback in probe_design.cxx (multiple call sites), rootAsWin.h:50, SaiProbeVisualization?.cxx:765, and MP_Window.cxx.
Root cause (traced in source):
In SL/CB/cbtypes.h, the macro CBTYPE_FVV_BUILDER_NP12 (and the analogous CBTYPE_VV_BUILDER_NP12) generates two overloads of the builder function for each parameter — one using the parameter type P1 as-is, and one using CONST_PARAM_T(P1):
CBTYPE_FVV_BUILDER_P1P2(BUILDER,CB,RESULT,FIXED,SIG,P1,P2,P1,P2); CBTYPE_FVV_BUILDER_P1P2(BUILDER,CB,RESULT,FIXED,SIG,P1,P2,P1,CONST_PARAM_T(P2)); CBTYPE_FVV_BUILDER_P1P2(BUILDER,CB,RESULT,FIXED,SIG,P1,P2,CONST_PARAM_T(P1),P2); CBTYPE_FVV_BUILDER_P1P2(BUILDER,CB,RESULT,FIXED,SIG,P1,P2,CONST_PARAM_T(P1),CONST_PARAM_T(P2))
CONST_PARAM_T expands to ConstParamT<T>::Type. For pointer types, the specialization is:
template<typename T>
struct ConstParamT<T*> {
typedef typename TypeOp<T>::ConstT *Type;
};
This takes the pointee type T and adds const to it. The problem: when T is already const-qualified — which is the case for all of ARB's AWAR name constants, typed as const char * — adding const to an already-const type is a no-op. So for P1 = const char*, both the "plain" builder overload and the "CONST_PARAM_T" builder overload end up with the exact same generated signature (const char*, const char*), i.e. two textually identical function template overloads are declared.
Apparently older Clang versions silently tolerated or merged this redundancy. Clang 21 now (correctly, per the standard) flags this as a genuine ambiguous overload, since there are two indistinguishable candidate templates.
This affects any callback type declared via DECLARE_CBTYPE_FVV_AND_BUILDERS / DECLARE_CBTYPE_VV_AND_BUILDERS (e.g. makeWindowCallback, makeRootCallback, makeTimedCallback, makeCreateWindowCallback) whenever it's invoked with const-qualified pointer parameters (most commonly const char* AWAR names) for both bound parameters.
Suggested fix direction:
A robust fix likely needs to avoid instantiating the "CONST_PARAM_T" overload when it would be identical to the plain P1/P2 overload — e.g. via a SFINAE/type-trait check (something like enable_if< !is_same<P1, CONST_PARAM_T(P1)>::value >) gating the redundant overload(s) in CBTYPE_FVV_BUILDER_P1P2 / CBTYPE_VV_BUILDER_P1P2. I have not attempted this patch myself, since I don't have access to ARB's test infrastructure to validate it doesn't break other instantiations of this macro (used across several callback types with different parameter shapes).
Additional notes:
This reproduces both on native Apple Silicon (arm64) and under Rosetta (x86_64) — it is not architecture-specific, purely a Clang-version issue. Already reported on the arb-project/homebrew-arb GitHub repo, issue #35, approximately 3 weeks ago, without a response — filing here as well since that may not be actively monitored. Happy to test a candidate patch against this exact build environment if one is proposed.
Change History (6)
comment:1 Changed 3 weeks ago by westram
- Component changed from no idea to global
- Description modified (diff)
- Owner changed from devel to westram
- Priority changed from normal to major
- Status changed from new to accepted
- Version set to SVN
comment:2 Changed 3 weeks ago by westram
- Status changed from accepted to _started
Jan had already submitted (an OpenCode generated) patch for this issue last monday.
comment:3 Changed 3 weeks ago by westram
[19974] basically fixed the problem. see ARB head build #1320
comment:4 Changed 3 weeks ago by westram
Building with unittests fails when using clang ≥ 20.1.0
Code to reproduce behavior: https://godbolt.org/z/jnrjchPbx
The code basically is an excerpt of the relevant parts from the preprocessor output of this revision of cb.cxx
comment:5 Changed 3 days ago by westram
- builds w/o unittests succeeded until [19976], but only at the cost of accidentally sabotaging const correctness of callback interface.
- [19983] (and probably already [19978]) fail again.
https://godbolt.org/z/Kh1er6vda contains code to track down the problem.
comment:6 Changed 41 hours ago by westram
[19985] fixed ambiguities for ARB head build #1338

Thank you for the
report.