Repository navigation
Fix C/C++ frontend defects: sizeof operands, C++ extensions, catch handlers, AST cache key - #190
Merged
Merged
Conversation
… and sizeof... apart sizeof(char *) was emitted as sizeof(char), and alignof, typeid, typeof and sizeof... all became <operator>.sizeOf, so passes that read sizeof as a byte size also read alignments, type ids and pack counts. Each operator now has its own name, the type operand keeps its abstract declarator, and the GNU unary forms (__alignof__ expr, noexcept, &&label) no longer fall through to <operator>.unknown.
Only .c, .cc and .cpp were translation units, so .cxx and .c++ sources were never parsed, and .hh headers were parsed as C. C++ sources now include .cxx, .c++ and .C, C++ headers include .hxx, .h++, .H, .ipp, .inl and .tcc, and longer extensions also match in upper case. A .tcc file is now also a C-family file for internal linkage.
The argument splitter compared characters against raw NUL literals, which made git treat the file as binary. The expansion under a macro's INLINED call also reused argument index 1, colliding with the first argument copy; it now takes the index after the last argument, matching its order.
The hidden flag was accepted but had no action, so it could not undo an earlier --with-include-auto-discovery.
Every C++ catch body was a direct child of the try with order 2, so siblings shared one position, the exception parameter was dropped (a use of e in the handler resolved to nothing) and function-try-blocks lost their handlers. The handlers now sit in one block coded catch, numbered in source order, each holding its exception as a local followed by its statements, and a function try block wraps the function body in a try. The CFG reads the children of a catch group as alternatives, which also fixes javasrc2cpg, where a second catch clause ran after the first instead of being entered from the try body.
…acros The lesson listed MACRO_DEF and MACRO_EXPANSION nodes that do not exist, a --enable-ast-cache flag that is not accepted, a frontend-args syntax atom does not parse and an include discovery step that finds system rather than project paths. It now documents the parsed extensions, the full pass list, the macro census flags and how macro invocations are represented. The CDT notes say the vendored core bundle ships in both CDT 12.4 and 12.5.
The uninitialised-read rule saw the new local for catch (int e) as declared and never assigned, and reported every read of e. The throw initialises it: the rule now skips a handler block's own local. The handler's statements stay in their body block, so the binding is the only local of the handler block; the CFG reads that body block through, as it does the try body.
The cache was keyed on file content, include paths, defines and macro files only. atom's header mode parses a project without function bodies and leaves its cache in <input>/.chen; a later full run over the same directory replayed those body-less ASTs, so its graph had no method bodies and its usage slices were empty placeholders (cdxgen's C evidence step followed by evinse hits exactly this). Function bodies, inactive code, comments, image locations, trivial expressions, the C++ standard, include discovery and the project index now take part in the key.
Types, member layouts and constants registered by an earlier run in the same process that never drained them (a run that stopped early, or an AST pass used on its own) were lent to the next graph as extra TYPE nodes. This also made the warm-restore test fail whenever the AST cache tests ran first in the same JVM.
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.
C/C++ frontend fixes found while comparing c2cpg with a fully resolving C++ front end. One commit per fix, each with regression tests.
Frontend (c2cpg)
sizeofand friends.sizeof(char *)was emitted assizeof(char): the type operand lost its abstract declarator.alignof,typeid,typeofandsizeof...were all emitted as<operator>.sizeOf, so passes that read sizeof as a byte size also read alignments, type ids and pack counts. Each now has its own operator (<operator>.alignOf,<operator>.typeId,<operator>.typeOf,<operator>.parameterPackSize), the GNU unary forms (__alignof__ x,noexcept(...),&&label) no longer fall through to<operator>.unknown, and the new operators carry no-flow semantics like sizeof..c,.ccand.cppwere translation units, so.cxxand.c++sources were never parsed, and.hhheaders were parsed as C. C++ sources now include.cxx,.c++and.C; C++ headers include.hxx,.h++,.H,.ipp,.inland.tcc; longer extensions also match in upper case.eresolved to nothing), and function-try-blocks lost their handlers. Handlers now sit in one block codedcatch, each at its own position with its exception bound as a local, and a function-try-block wraps the function body in a try. The CFG reads acatchgroup's children as alternatives, which also fixes javasrc2cpg, where a second catch clause ran after the first instead of being entered from the try body. The uninitialised-read rule treats the new binding as initialised by the throw.MacroHandler.scalaheld raw NUL bytes, so git treated it as binary. The expansion under a macro's INLINED call reused argument index 1, colliding with the first argument copy; it now takes the index after the last argument.--no-include-auto-discoverywas accepted but had no action.AST cache
<input>/.chen; a later full run over the same directory replayed those ASTs, so its graph had no method bodies and its usage slices were<empty>placeholders (cdxgen's C evidence step followed byevinsehits exactly this). Function bodies, inactive code, comments, image locations, trivial expressions, the C++ standard, include discovery and the project index now take part in the key.C2Cpg.createCpgnow starts from empty tables. This also fixesCWarmRestoreTestsfailing whenever the AST cache tests ran first in the same JVM.Docs
The c2cpg lesson listed
MACRO_DEF/MACRO_EXPANSIONnodes that do not exist, a--enable-ast-cacheflag that is not accepted and a frontend-args syntax atom does not parse. It now documents the parsed extensions, the pass list, the macro census flags and how macro invocations are represented. The CDT notes say the vendored core bundle ships in both CDT 12.4 and 12.5.Testing
c2cpg/test1211,x2cpg/test118,dataflowengineoss/test53,javasrc2cpg/test573: all pass.sbt scalafmtAllapplied.