Skip to content

C++ Mode v0.3.1

Latest

Choose a tag to compare

@pepc84 pepc84 released this 22 Jul 04:31

What's new?

Parser Hardening: Function Pointers, Template Defaults, Bitfields, and More

This release continues the parser hardening work from v0.3.0, targeting a new batch of valid C++17/20 constructs that were previously mishandled. Fixes span the parser, CodeGen, and the Windows install wizard.


Parser

  • Function pointer parameters with defaults: float (*fn)(float) = nullptr now parses correctly. The ref-to-array branch ((&arr)[N]) now discriminates against function pointer params by checking whether ( or [ follows the closing ), rather than consuming both forms the same way.
  • Function pointer parameter encoding: parser encodes fn-ptr params as name__fnptr__(sig) so CodeGen can round-trip the full declarator shape rettype (*name)(sig).
  • Template default values with comparisons: template<int N = (sizeof(float) > 2 ? 8 : 4)> now parses correctly. parseTemplateDefaultValue now tracks parenDepth and angleDepth separately, so > inside parentheses is treated as a comparison operator rather than a template closer.
  • Explicit empty <>: Foo<> x now emits Foo<> x rather than Foo x. The parser stores a sentinel NamedType("<>") to distinguish explicit empty args from no args.
  • Array-new value-init: new float[n]() trailing () is now consumed correctly instead of being left in the stream and breaking the enclosing constructor init-list parser.
  • Trailing ref-qualifiers: T& operator=(const T&) & and T& operator=(T&&) && — trailing & and && ref-qualifiers on member functions are now consumed in the trailing qualifier loop.
  • Bitfields: named (unsigned int active : 1) and unnamed (unsigned int : 2) bitfield declarations now parse correctly inside struct bodies. Unnamed bitfields return an empty name before expectIdentifier() would throw.
  • Throw as expression: cond ? val : throw std::runtime_error("null")throw in ternary else position now handled in parseTernary() before delegating to parseLogicalOr().
  • Template speculation and ternary: looksLikeTemplateArgList now rejects speculation when a bare ? appears at depth 0, preventing v < lo ? lo : v > hi from being misread as a template instantiation.

CodeGen

  • Function pointer param emission: decodes name__fnptr__(sig) encoding and emits rettype (*name)(sig) correctly.
  • Array-of-function-pointer dims: void (*ops[4])(int) now emits with [4] inside the parens rather than outside — discriminates array-of-fn-ptr from ptr-to-array using paramTypes.isEmpty().
  • Long double literals: L/l suffix now excluded from the float f-append pass — 180.0L was becoming 180.0Lf.

CppBuild / InstallWizard

  • E0005 false positive fixed: Array<T>.get().field no longer triggers E0005. The check now requires positive confirmation that the receiver is an ArrayList before firing — Array<T> is value-storage and .field is correct there.
  • Windows install wizard now fires reliably: PATH g++ (Git for Windows, Cygwin, other MinGW installs) is no longer trusted on Windows. Only g++ at known MSYS2 mingw64 paths is accepted. Previously, any g++ on PATH would silently bypass the wizard, leading to linker errors at build time due to missing GLFW/GLEW. Both CppBuild.checkGppAvailable() and InstallWizard.detectWindowsMissing() now check MSYS2 paths exclusively.

Stress Test Coverage

Rounds 21–23 of the parser stress test suite, covering: inline function pointer parameters with defaults, arrays of function pointers, reference-to-array parameters, nested template closes (>>), conditional expression NTTPs, pointer-to-member template parameters, cast inside brace-init, pack expansion in member init-lists, operator overloads with ref-qualifiers, structured bindings in range-for, if/switch-with-init, template type aliases, using X::Y qualified imports, three-link postfix chains on temporaries, trailing return types with decltype, constexpr if, fold expressions, C++20 lambda template parameters, requires clauses on free functions, concept definitions, structured bindings from arrays, immediately invoked lambdas, variable templates, bitfield members, conditional noexcept, and throw-expressions in ternary context.