ast, parser, fio: fix six PVS-Studio findings#3111
Merged
Conversation
- isFullySealed re-tested firstType where it null-checked secondType (copy-paste), so a sealed key type masked an unsealed value type — prematurely folding typeinfo offsetof; doctest pins it - bitfield-constant 'not initialized' error branch fell through to found->init->clone() — null deref (macro-reachable shape) - non-verbose 'too many matching variables' error was dead code (if (verbose) inside the else of if (verbose)) — ambiguous globals compiled with no diagnostic; folded the mirror always-true check too - two early returns left program->updateAliasMapCallback holding a lambda with by-ref captures of dead stack frames; a later das-side update_alias_map call would write through them - lexer line directives parsed the file name with sscanf %s, which stops at whitespace: #1,2,"a b"# made strlen(lFile)-2 underflow into a wild OOB write; both lexers now take the quote-bounded span (also un-breaks paths with spaces and >255-char paths) - register_dynamic_module deref'd context unguarded on its first error path while both sibling paths guard; harmonized Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a handful of confirmed PVS-Studio findings in daScript’s core compiler/runtime components (AST/type inference, dynamic module loading, and both lexers), and adds a C++ regression test to lock in the isFullySealed behavior.
Changes:
- Fix
TypeDecl::isFullySealedto correctly validatesecondType(plus new doctest regression coverage). - Fix two inference/diagnostic issues in
ast_infer_type.cpp(missing return in a bitfield-constant error path; make ambiguous-variable diagnostics non-silent). - Harden lexer line-directive filename extraction to handle whitespace safely (and regenerate lexer outputs), plus guard a
Context*deref inregister_dynamic_module.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| tests-cpp/small/test_fully_sealed.cpp | Adds regression coverage ensuring isFullySealed checks secondType independently. |
| src/ast/ast_typedecl.cpp | Fixes copy-paste bug: secondType now calls secondType->isFullySealed. |
| src/ast/ast_infer_type.cpp | Adds missing early return on bitfield-constant init error; ensures ambiguous/missing variable errors are emitted consistently. |
| src/ast/ast_infer_type_function.cpp | Clears program->updateAliasMapCallback on early-return paths to avoid dangling callbacks. |
| src/builtin/module_builtin_fio.cpp | Guards context before emitting/throwing on dynamic module load failure. |
| src/parser/ds_lexer.lpp | Fixes line-directive filename parsing to use quote-bounded span (supports spaces; avoids OOB write). |
| src/parser/ds_lexer.cpp | Regenerated lexer output reflecting the line-directive parsing fix. |
| src/parser/ds2_lexer.lpp | Same line-directive parsing fix for ds2 lexer. |
| src/parser/ds2_lexer.cpp | Regenerated ds2 lexer output reflecting the line-directive parsing fix. |
| src/parser/lex.yy.h | Regenerated header line markers (line directives shifted due to lexer regeneration). |
| src/parser/lex2.yy.h | Regenerated header line markers (line directives shifted due to lexer regeneration). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Triage of a PVS-Studio sweep over the vendored daScript copy: ~80 warnings, 6 real findings, all fixed here. Everything else classified as false positives (invariant-guarded derefs the parser guarantees, gc_node-tracked "leaks", deliberate hopeless-clear memsets, union aliasing PVS can't model, flex-generated boilerplate).
Fixes
isFullySealedcopy-paste (ast_typedecl.cpp) — null-checkedsecondTypebut re-testedfirstType, so a sealed key type masked an unsealed value type (e.g. a table with sealed key and still-auto value), lettingtypeinfo offsetoffold prematurely. Pinned by a new doctest (tests-cpp/small/test_fully_sealed.cpp).found->init->clone(). Added the missing return; only reachable via macro-side flag manipulation (the grammar always sets the initializer).else { if (verbose) error(...) }made the terse "too many matching variables" diagnostic dead code, so non-verbose compiles reported nothing for an ambiguous global. Also folded the mirror always-trueif (verbose)on the "can't locate variable" path.updateAliasMapCallback(ast_infer_type_function.cpp, 2 sites) — early returns leftprogram->updateAliasMapCallbackholding a lambda capturing dead stack frames by reference; a later das-sideupdate_alias_mapcall (typeinfo macro) would write through them. The third site already cleared the callback before its early return — copied that pattern.#row,col,"file"#was parsed withsscanf %s, which stops at whitespace: a file name containing a space madestrlen(lFile)-2underflow into a wild out-of-bounds write. Both lexers now take the quote-bounded span directly (also un-breaks paths with spaces and paths longer than 255 chars). Generated lexer sources regenerated.contextguard asymmetry (module_builtin_fio.cpp) —register_dynamic_modulederef'dcontextunguarded on its first error path while both sibling error paths guard withif (context); harmonized (a null context is passed internally today, Quiet-only).Validation
--full: 16 passed, 0 failed (lint skipped — no .das changes): cpp-syntax full sweep, das2rst + sphinx latex/html + pdflatex, tests-cpp, interp + JIT + AOT suites, sequence smokeisFullySealedregression test#5,1,"probe b.das"#(space in name) now lexes, resolves, and runs; plain directives unchanged🤖 Generated with Claude Code