Loading
Commits on Source 3
-
cznic authored
Every completeness check of a struct type nested k levels deep recursed through all k levels with a fresh visited map, so translating deeply nested aggregates was quadratic in the nesting depth. For gcc.c-torture/compile/limits-structnest.c (10,000 levels) that recursion alone took minutes and dominated the whole translation, and on the darwin/amd64 builder (Rosetta) the ccgo test binary died with a SIGBUS while inside it. Completeness is monotonic: a struct or union type that is complete stays complete. Cache a negative result in structType.isComplete once the definition has been finished (size >= 0) or when it comes from the forward declaration's definition, and short-circuit on it. The file now translates in ~0.3s instead of minutes; the cc tests and the ccgo corpus results are unchanged. Co-Authored-By:
Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y9nCaVXi5ycW1kjAxXk6Vu
-
cznic authored
Translate used the preprocessor's #if evaluator to assign a value to every object-like constant macro, and that evaluator treats each identifier it meets, sizeof included, as 0: sizeof(T)*N came out as 0, (N-8)/sizeof(T) as N-8, an enumeration constant or a cast as 0 and a floating point expression as 0. ccgo then emitted const WALINDEX_PGSZ = 0 and const M_PI = 0 for SQLite, and const SQLITE_PRIVATE = 0 for a macro that is not an expression at all. The macro-expanded replacement list is now parsed and type checked as a C expression in the file scope of the translation unit, with everything the unit declares visible, so sizeof, casts, enumeration constants and typedef names have their C meaning. A macro whose expansion is not a constant expression gets no value; there is no fallback to the #if evaluator any more. Anything the throwaway parse declares lands in a child scope, the file scope itself is not touched. AST.check returns its context so that Translate can check the expressions against the unit. On the 3.53.4 amalgamation 3809 of the 4691 object-like macros get a value (1645 had one from their use sites before), for no measurable cost on top of the 2.6 s translation. In the ccgo output for SQLite this changes 235 exported constants: 70 zeros become the right number, 41 constants appear (casts, sizeof, enumeration constants), 19 bogus values disappear (RESERVED_BYTE, errno, INFINITY, ...), 97 macros that merely name another identifier fall back to ccgo's alias string form, and 8 numbers change: three sizeof fixes and pointer casts like ((void*)-1), which are all-ones now instead of -1. Found by hazyhaar while working on sqlite#221 (libsqlite3!4). Co-Authored-By:
Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DPoSMckkK9hLqU8t3ATQHr
-
cznic authored
gcc 15 defaults to -std=gnu23. Under C23 glibc's <assert.h>, <stdbool.h> and <stddef.h> no longer define static_assert, bool, true, false and nullptr as macros - they are keywords - and cc, which knew only the C11 spellings, failed on testdata/bug/10.c with "unexpected 'sizeof', expected declarator or abstract declarator" on the linux/loong64 builder (Debian 14, gcc 15.3) in every run since 2026-08-20. When the probed predefined macros say __STDC_VERSION__ >= 202000L (gcc's C2x value included), NewConfig adds alignas, alignof, bool, static_assert and thread_local to the keyword set as the tokens of their C11 spellings. Builtin defines true, false and nullptr as macros under the same condition, which is where <stdbool.h> and <stddef.h> used to put them. Below C23 nothing changes. TestC23 exercises both and skips where the host compiler has no -std=gnu23. Co-Authored-By:
Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DPoSMckkK9hLqU8t3ATQHr