Skip to content

Format function arg defaults from their source text#1069

Open
conrade-ctc wants to merge 1 commit into
compiler-research:mainfrom
conrade-ctc:argdefault-symbolic-floating-defaults
Open

Format function arg defaults from their source text#1069
conrade-ctc wants to merge 1 commit into
compiler-research:mainfrom
conrade-ctc:argdefault-symbolic-floating-defaults

Conversation

@conrade-ctc

@conrade-ctc conrade-ctc commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Description

Cpp::GetFunctionArgDefault pretty-printed the default's AST and round-tripped floating-typed results through std::stod — a FIXME-documented workaround for clang printing floats at representation precision (3.1400000000000001 for a written 3.14). A symbolic default (double ratio = kDefaultRatio, or MemoryPool* pool = default_memory_pool()-style APIs with float variants, as in arrow/parquet) is not a numeric literal, so std::stod threw std::invalid_argument into code built without exception support and the process terminated. Any reflection or help()-style prototype formatting of such a method was fatal.

Per review, this now formats the default the way clang's own code completion does (GetDefaultValueString in SemaCodeComplete): read the parameter's getDefaultArgRange() source text via Lexer::getSourceText. That is as-written by construction, so the float-precision FIXME and its numeric normalization disappear entirely. The lexed range sometimes includes the leading = (SemaCodeComplete documents the same quirk), which is stripped; defaults with no usable source range fall back to the previous AST pretty-print.

Behavior note: literal defaults now render exactly as written — 4.0 where the old normalization produced 4. — and the existing test expectations are updated accordingly.

Type of change

  • Bug fix

Testing

Updated FunctionReflection_GetFunctionArgDefault for as-written literal spellings, and new FunctionReflection_GetFunctionArgDefaultSymbolic covering an identifier default, a call default, an expression default, and a literal — the symbolic shapes were fatal before this change.

Checklist

  • I have read the contribution guide recently

🤖 Done with the help of Claude Code (Fable 5, human in the loop)

@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.87%. Comparing base (3103be9) to head (2d07020).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1069      +/-   ##
==========================================
- Coverage   87.01%   86.87%   -0.14%     
==========================================
  Files          23       23              
  Lines        6069     6074       +5     
==========================================
- Hits         5281     5277       -4     
- Misses        788      797       +9     
Files with missing lines Coverage Δ
lib/CppInterOp/CppInterOp.cpp 89.23% <100.00%> (-0.28%) ⬇️
Files with missing lines Coverage Δ
lib/CppInterOp/CppInterOp.cpp 89.23% <100.00%> (-0.28%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread lib/CppInterOp/CppInterOp.cpp Outdated
// is not a plain literal.
errno = 0;
char* ParseEnd = nullptr;
double DefaultArgValue = std::strtod(Result.c_str(), &ParseEnd);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can take a step back here -- is that the way clang does this?

@conrade-ctc conrade-ctc Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point... claude pointed out to me that there is a more standard, generic fix... two possibilities... let me try that them, and repost... might close one of the two PRs actually, since they are related. Give me a sec...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call — reworked. It now does what SemaCodeComplete's GetDefaultValueString does: read the parameter's getDefaultArgRange() source text via Lexer::getSourceText (including stripping the sometimes-present leading =, per the FIXME there), falling back to the AST pretty-print only when there's no usable range. That makes the output as-written by construction, so the float-precision FIXME and the std::stod normalization are gone entirely. Literal defaults now render exactly as written (4.0 where the old code produced 4.) — existing test expectations updated to match.

@github-actions

Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

GetFunctionArgDefault pretty-printed the default's AST and round-tripped
floating-typed results through std::stod to undo clang printing floats at
representation precision. A symbolic default (double ratio = kDefaultRatio,
or arrow's pool = default_memory_pool() style) is not a numeric literal, so
stod threw std::invalid_argument into the exception-free build and the
process terminated.

Read the default's source range instead - the way clang's own code
completion formats default arguments (GetDefaultValueString in
SemaCodeComplete): as-written by construction, so the float-precision
FIXME and its numeric normalization disappear. The lexed range sometimes
includes the leading '=' (SemaCodeComplete documents the same quirk), so
strip it; defaults with no usable source range keep the pretty-printed
fallback. Literal defaults now render exactly as written ("4.0" where the
normalized form was "4.").

Co-developed-with-the-help-of: Claude Code (Fable 5, human in the loop)
@conrade-ctc conrade-ctc changed the title Keep symbolic floating defaults in GetFunctionArgDefault Format function arg defaults from their source text Jul 16, 2026
@conrade-ctc
conrade-ctc force-pushed the argdefault-symbolic-floating-defaults branch from 189b6aa to 2d07020 Compare July 16, 2026 17:33
@github-actions

Copy link
Copy Markdown
Contributor

clang-tidy review says "All clean, LGTM! 👍"

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.

2 participants