<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Unicorn Developer</title>
    <description>The latest articles on DEV Community by Unicorn Developer (@pvsdev).</description>
    <link>https://dev.to/pvsdev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1110345%2F0615f05a-4746-4c6f-89ff-a4ef95008a77.png</url>
      <title>DEV Community: Unicorn Developer</title>
      <link>https://dev.to/pvsdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pvsdev"/>
    <language>en</language>
    <item>
      <title>Game++. Part 2.2: Types of optimization</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Fri, 23 Oct 2026 12:18:36 +0000</pubDate>
      <link>https://dev.to/pvsdev/game-part-22-types-of-optimization-4aal</link>
      <guid>https://dev.to/pvsdev/game-part-22-types-of-optimization-4aal</guid>
      <description>&lt;p&gt;This book offers insights into C++, including the algorithms and practices used in game development, and explores the language's strengths and weaknesses, its established workflows, and hands-on solutions, because C++ still dominates the game industry today thanks to its combination of high performance, flexibility, and deep low-level control.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F04qurrit37jls97ecno1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F04qurrit37jls97ecno1.png" alt="1422_pt_7/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hotspots and bottlenecks
&lt;/h2&gt;

&lt;p&gt;The key task in optimization is to find hotspots, which are code fragments with a high computational load, and bottlenecks, which are components that limit overall throughput, and these problems usually fall into three categories, namely abstractions, smoothness, and hardware limitations.&lt;/p&gt;

&lt;p&gt;Abstractions, or more precisely premature abstractions, add unnecessary layers to the engine architecture and make the whole system more complex than it needs to be, and the usual suspects here are multiple inheritance, one-size-fits-all solutions to game development problems, and heavy use of design patterns in places where simple procedural code would do the job just fine.&lt;/p&gt;

&lt;p&gt;The same category includes writing beautiful code instead of fast code, when performance-critical sections get buried under unnecessary layers of ceremony and checks, which is exactly what the KISS principle warns us about.&lt;/p&gt;

&lt;p&gt;Most developers agree that smoothness matters more than peak performance, and the things that work against it are well known, because sporadic memory allocations on the main thread make the frame rate uneven, algorithms with unpredictable complexity make frame times inconsistent, and blocking resource loads cause stuttering. A stable 30 FPS beats a frame rate that jumps between 60 and 20, because players feel those jumps immediately, which is why a consistent frame rate is such an easy-to-understand and measurable indicator of quality.&lt;/p&gt;

&lt;p&gt;Hardware limitations are best treated as creative constraints, because brute-forcing a platform's physical limits instead of applying smart optimizations only adds complexity without any real payoff. Raising the polygon count without a proper level-of-detail system will leave the player with low FPS, and the same goes for complex shaders that ignore fill-rate limits, memory-hungry data structures that don't account for the cache hierarchy, and so on.&lt;/p&gt;

&lt;p&gt;A modern CPU-GPU architecture is a complex data-processing pipeline with many parallel execution units, and in this "digital hell" data moves through a hierarchy of caches, travels between the CPU and GPU over the bus, and gets synchronized across threads with memory barriers and atomic operations, so the system almost never does exactly what you wrote in the code.&lt;/p&gt;

&lt;p&gt;You can get solid and stable performance by balancing the workload across all of these components, and even then you may not be able to push the CPU beyond 70 to 80%, but you can make much better use of the GPU, memory bandwidth, and caches. The real challenge is finding a delicate balance right at the edge of what's possible for every component at once, and if you get it wrong, resource contention follows, one component becomes the critical link, and the rest of the system suffers from pipeline stalls, context-switching overhead, and reduced throughput.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hotspots
&lt;/h2&gt;

&lt;p&gt;In software systems, hotspots are localized sections of code with unusually high resource consumption, whether that's CPU time, memory, or disk I/O, and they're characterized by a disproportionately high execution frequency, heavy CPU utilization, high memory pressure, or significant system call overhead.&lt;/p&gt;

&lt;p&gt;In the context of code optimization, the Pareto principle, also known as the 80/20 rule, means that 20% of the source code accounts for 80% of a program's total execution time, which makes hunting down hotspots a highly effective strategy. Searching iteratively helps you find the code blocks that consume the most resources so you can target them and cool them down, but once one issue is fixed, the workload shifts and previously minor sections turn into new hotspots that need attention. This process goes on until the results are acceptable or the time allocated for the task runs out, and it's worth remembering that an engineer's time is a finite resource too, because the more time a developer spends polishing one part of the code, the less time they have for everything else.&lt;/p&gt;

&lt;p&gt;Modern profilers provide detailed analysis down to the level of individual CPU instructions, which makes it possible to identify temporal hotspots, code with a high number of cache misses, heavy I/O operations, and resource-lock contention in multithreaded applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottlenecks
&lt;/h2&gt;

&lt;p&gt;Imagine a dish being prepared in a café. The chef can't make the whole thing at once, so they hand the side dish off to an assistant while working on the main part themselves, and then the two parts come together and a waiter takes the finished plate to the customer. How long will the whole process take? Suppose the chef finishes first, but the assistant simply can't work any faster, and now the assistant is the bottleneck that slows down the entire system.&lt;/p&gt;

&lt;p&gt;Games work exactly the same way, because there's always a "slow assistant" somewhere, whether it's the CPU, the GPU, memory, or something in the code that holds everything else back, and the developer's job is to find that weak link and bring its performance in line with the rest. Optimization almost always involves trade-offs, and in 99% of cases there's no silver bullet that will fix the problem right away.&lt;/p&gt;

&lt;p&gt;The first and most common trade-off is between performance and memory, since sometimes it's more efficient to store extra data than to recalculate it from scratch. This is called &lt;strong&gt;memoization&lt;/strong&gt; or &lt;strong&gt;caching&lt;/strong&gt;, and the idea is that you calculate something once, store the result, and then simply pull it from memory whenever you need it, which costs more memory but gets you the result faster.&lt;/p&gt;

&lt;p&gt;The second trade-off is between accuracy and speed. Sometimes you can cut corners and speed up a system by simplifying a data type or using a less precise algorithm, and shaders are a good example, because they provide both &lt;code&gt;log&lt;/code&gt; and &lt;code&gt;logp&lt;/code&gt;, where the former is more accurate but slower and the latter is faster but less precise. In the final image, players are unlikely to notice that a neighboring polygon has shifted by a quarter of a pixel, but the game may run noticeably faster, and the same principle applies to almost any data model, pathfinding system, or game AI. The key question is how much precision you're willing to give up, or, in more formal terms, how much you can shift resources from lower-priority computations to higher-priority ones.&lt;/p&gt;

&lt;p&gt;The third classic trade-off is simplicity versus speed, and this one has more to do with people and the team than with hardware. A classic example is a young, talented developer who has just discovered design patterns and responds by building five levels of nested caching in an attempt to optimize the texture-loading system.&lt;/p&gt;

&lt;p&gt;Sure, they'll get that system built, and it may even run faster thanks to intrusive pointers, custom allocator pools, and a lock-free hash table, but the result is predictable, because nobody, not even the author a month or two later, can understand, debug, or modify that code without risking breaking something. Other developers on the team start avoiding those files, they groan every time they have to touch the system, and code reviews keep getting comments like "What the hell is this? Can we just rewrite it in plain C++?"&lt;/p&gt;

&lt;p&gt;An experienced developer knows that real performance gains don't come from showing off their knowledge of algorithms, but from understanding the trade-off between how maintainable the code is and how much the optimization actually pays off.&lt;/p&gt;

&lt;p&gt;Yes, you can squeeze out another 5% of performance with custom memory pools, but that will take two weeks to implement and another month to debug all the weird edge cases, so it might be smarter to use a simple linear allocator and trade some memory for time.&lt;/p&gt;

&lt;p&gt;Mature optimization means fixing the truly critical bottlenecks with clean, well-documented solutions that you can easily switch off with conditional compilation if something goes wrong. In the real world, shipping the game matters more than cool algorithms, and having code the team can maintain matters more than having code that looks impressive in a conference talk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Myths and misconceptions
&lt;/h2&gt;

&lt;p&gt;Software optimization is inherently endless, because there will always be something left to improve, but it's important to understand that past a certain point you start hitting diminishing returns, and every additional effort delivers a smaller and less noticeable performance gain.&lt;/p&gt;

&lt;p&gt;On top of that, developers often spend time chasing dead ends that provide no real benefit (but make for great slides and conference talks) and only make the system harder to maintain. The key skill here is knowing when to stop and ask whether further improvements will actually add value or turn into a witch hunt.&lt;/p&gt;

&lt;p&gt;One of the most common mistakes is making decisions based on assumptions. You can't just "guess" what's slowing the system down, because those guesses are usually wrong, and the only reliable approach is to measure and analyze, then analyze and measure again, until guesses and gut feelings turn into well-founded engineering decisions.&lt;/p&gt;

&lt;p&gt;Optimization doesn't start after the code is written, and in fact 80% of performance problems can be eliminated at the architecture design stage, because proper decomposition, a clear object hierarchy, and well-thought-out dependency management help you avoid bottlenecks in the first place. Despite the overhead that comes with languages like C# and Java, a well-structured system often outperforms code written in pure C++ that ignores architectural constraints.&lt;/p&gt;

&lt;p&gt;When it comes to optimization, it's important to focus on worst-case scenarios rather than average ones. Most developers test their games and applications on powerful workstations, which often gives them a distorted picture, and on weaker hardware the bottlenecks can be completely different, with memory bandwidth or CPU power becoming the limiting factor instead of the GPU.&lt;/p&gt;

&lt;p&gt;To analyze performance properly, developers need to deliberately test on configurations with minimal or weak hardware specs, because those machines are much closer to what a good portion of your players actually experience. Players can tell the difference between 55 and 60 FPS, but they rarely complain about it, while a drop to 20 FPS feels like serious lag even if it only happens once in a while, and that's why consistent frame times often matter more than a high average frame rate.&lt;/p&gt;

&lt;p&gt;Debug and release builds give fundamentally different results (Pic. 3.1). In debug mode, compiler optimizations are turned off and extra checks are turned on, which can slow the code down several times over, and not evenly. For valid performance profiling, work only with release builds and enable debug symbols or disable optimization for specific sections when you need to, because this lets you strike a balance between traceability and accurate measurements while still giving you a realistic picture of performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fovqor2327a7y6h3tnf8y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fovqor2327a7y6h3tnf8y.png" alt="1422_pt_7/image2.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Picture 3. 1&lt;/p&gt;

&lt;p&gt;That said, debug builds are useful in the early stages of testing, when they can reveal excessive CPU usage or inefficient algorithms before those problems become critical.&lt;/p&gt;

&lt;p&gt;Finally, the key requirement for any benchmark is control over external variables, since poorly designed tests can create the illusion of optimization. For example, the first measurement might be taken in fullscreen mode while the second runs in windowed mode, at a different refresh rate, or at a different resolution, and the frame rate goes up because the environment changed rather than the code, which makes the whole comparison meaningless. To avoid mistakes like this, keep every environment parameter fixed and change only one thing between runs, namely the piece of code you're optimizing. The best practice is to automate your benchmarks, which removes human error and gives you reproducible results.&lt;/p&gt;

&lt;p&gt;Many people think optimization time should be added to sprints once the game is nearly finished, or, even worse, only when performance problems show up. But ignoring optimization in the early stages of development means risking increasingly tangled processes and unpredictable performance problems at the worst possible moment.&lt;/p&gt;

&lt;p&gt;Another myth is that reactive optimization works well enough on its own. Yes, hundreds of games ship after being optimized at the last minute, but this approach usually ends with cutting features or simplifying mechanics to make up for low FPS. Reactive optimization creates a false sense of control, because fixing problems late in development takes far more time and effort than taking a systematic approach throughout the whole project.&lt;/p&gt;

&lt;p&gt;The next myth is that optimization needs large, dedicated blocks of time, when in reality it's much more effective to work it in gradually. With practices like performance budgets, you can set limits for FPS, CPU, and GPU usage up front and organize the team's work around those numbers, and continuous monitoring with incremental code adjustments produces better results than occasional optimization pushes in the final weeks of development.&lt;/p&gt;

&lt;p&gt;There's also a persistent belief that every optimization is justified. In reality, there are plenty of areas where programmers can sink time without seeing any obvious benefit, so only optimize what actually affects performance and weigh the potential payoff against the time the changes will take. This approach keeps you from wasting effort and keeps the focus on the bottlenecks that are really slowing the game down.&lt;/p&gt;

&lt;p&gt;Finally, there's a misconception that performance is a single metric, when a game that "feels slow" can mean any combination of low FPS, longer response times, high CPU and GPU load, and frame rate drops. To optimize even one of these metrics effectively, developers first need to understand which ones are critical for their particular project, how they relate to each other, and what's actually holding the game back.&lt;/p&gt;

&lt;p&gt;A systematic approach like this is the only way to avoid the common misconceptions about optimization. Will anyone actually approve such changes, though? Most likely not, because it's extremely unlikely that the project architect, tech lead, or CTO will sign off on real architectural changes, and that's not really the programmer's call to make anyway, so pushing for it tends to step on the architect's toes. Besides, changing an existing, working, well-tested system can break the systems around it, and there's no way to predict when the error will surface, only that it inevitably will. That's exactly why a developer who just joined the team can't rewrite half the engine "the right way," and what's left for them is code-level and algorithmic tweaks, which can still squeeze out a performance improvement of at least 10%.&lt;/p&gt;

&lt;p&gt;This brings us to the reality that game development forces us to balance our "ideal" technical solutions against the practical constraints of the project. Even a programmer who sees through every optimization myth often has to work within an existing architecture they can't change and settle for local improvements at the algorithm and code level, but this approach can still deliver tangible results, such as the 10 to 15% performance gains that can make all the difference for a successful release.&lt;/p&gt;

&lt;p&gt;Knowing where your influence ends matters, and so does choosing your battles wisely. Optimization was never just a technical skill, because it's also a team sport where every change needs to be justified, measured, and agreed upon, and in the end the best optimization is the one players actually notice, not the one that gets you a few nods in a technical chat.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools
&lt;/h2&gt;

&lt;p&gt;Any work aimed at improving performance is wasted if you can't see what's actually happening in your code. It's like trying to repair a watch blindfolded or tune a musical instrument with your ears plugged, because you can turn the screws and pluck the strings all you want, but the result will be purely random.&lt;/p&gt;

&lt;p&gt;In everyday life, we get immediate feedback, so if you trip, you fall, if you take a wrong turn, you may end up at a dead end, and if you add too much salt, you ruin the dish. These signals help us correct course right away and remember not to make the same mistake twice. In programming, however, things work differently, because code can execute millions of times per second, process gigabytes of data, and interact with dozens of system components, while all we see is the end result, say, an FPS counter that refuses to go above 50.&lt;/p&gt;

&lt;p&gt;Modern software, and games in particular, can run to hundreds of thousands of lines of code stacked on top of complex operating systems, graphics drivers, and various libraries that add even more code. Without specialized analysis tools, all you can really do is guess whether the CPU can't keep up, whether the bottleneck is loading textures from disk, or whether memory is leaking somewhere. Profilers, performance monitors, and debuggers can mislead you too, but you can't do without them, because they show which functions take the longest to execute, how much memory each part of the program uses, how often the application hits the disk, and where the CPU sits idle waiting for data. Without this information you're flying blind, and with it the solution often becomes obvious, although measuring and analyzing performance correctly is its own kind of science that sometimes borders on alchemy.&lt;/p&gt;

&lt;p&gt;Any tool that measures a program's performance will inevitably affect that performance. Some tools are light enough on their feet that they barely slow the program down, and those are called &lt;strong&gt;non-intrusive&lt;/strong&gt;, while others can seriously drag down an application's performance, and those are called &lt;strong&gt;intrusive&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;How much interference you get depends on how much data you need and how often you need it. A simple FPS counter has virtually no impact on the game, while a detailed analyzer that logs every function call and its execution time can slow things down considerably. Some tools, such as Valgrind, go even further and run the entire program inside a virtual machine to collect highly detailed information about every operation, and you can guess what that does to performance, since the program can easily run ten times slower than usual or worse.&lt;/p&gt;

&lt;p&gt;There are several ways to measure performance, and sampling profilers are the gentlest and simplest of them. They periodically take a snapshot of the program to see which code is running at that moment, and by collecting a series of these snapshots, developers can build a statistical picture of what the program spends most of its time doing.&lt;/p&gt;

&lt;p&gt;A more intrusive approach relies on interception tools that sit between the program and external resources, so PIX, for example, intercepts every call the program makes to the GPU through the DirectX API, while network analyzers peek at all network traffic.&lt;/p&gt;

&lt;p&gt;Getting even more detail means adding special commands and profiling markers to the code to collect data, and this process is called instrumentation.&lt;/p&gt;

&lt;p&gt;Choosing the right tool depends on your specific goals and on how much performance you're willing to sacrifice for a more detailed analysis. The one rule that really matters is that the tool shouldn't distort the measurements more than the problem you're hunting for, since there's little point in optimizing a function that accounts for only 1% of execution time if the profiler itself slows the program down by 50%. That's why all three types of tools are often used, each in its own circumstances.&lt;/p&gt;

&lt;h2&gt;
  
  
  Theory and terminology
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Profilers&lt;/strong&gt; is an umbrella term for the performance analysis tools used across most of game and software development, and a profiler's main job is to capture how the workload breaks down during execution in as much detail as the developer allows.&lt;/p&gt;

&lt;p&gt;The classic use case is measuring CPU time, but modern profilers can track much more, including cache misses, memory allocations, disk access, thread usage, and synchronization. Depending on the level of instrumentation, they can give you either an aggregated view of the workload that shows which modules or systems put the most load on the CPU and where, or a per-frame or per-interval snapshot with the call stack and the exact distribution of work across individual instructions.&lt;/p&gt;

&lt;p&gt;Profilers fall into two categories, general-purpose and specialized. General-purpose profilers are usually the ones built into an IDE or a platform SDK, such as the Visual Studio Profiler, and they give you a broad sense of where performance is leaking. Specialized profilers are low-level tools, such as Sony Razor, Intel VTune, PIX, or Tracy, that collect data from CPU performance counters and OS events and let you analyze code behavior with much greater precision, and only these low-level tools let developers evaluate how specific algorithmic steps or memory access patterns affect the overall performance of a piece of code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Total time&lt;/strong&gt; shows the cumulative execution time of a function, including all the nested calls it makes to other functions. In theory, it helps identify hotspots in an application and gives a complete picture of how much time the program spends in a particular section of code along with all its dependencies, but in practice it can give a distorted view of performance.&lt;/p&gt;

&lt;p&gt;As part of its optimizations, the compiler may inline functions directly into the code of the calling function, which blurs the execution time of the parent function even though the inlined code is what actually does the work. This metric also doesn't account for indirect costs, such as cache pollution or data eviction, which can seriously undermine how reliable the measurement is.&lt;/p&gt;

&lt;p&gt;For example, when you analyze functions whose performance depends heavily on their input data, such as sorting an almost-sorted array versus an unsorted one, the profiler will report an average value, which can hide real performance problems that only show up in certain use cases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self time&lt;/strong&gt; measures only the time spent executing instructions inside the function itself, excluding the time spent in all the functions it calls. This helps identify the code blocks that actually do the expensive work rather than just handing it off to other functions, and functions with heavy algorithms, loops, or number crunching typically show high self time.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;ObjectUpdate()&lt;/code&gt; function may have a high total time because it calls all the other subsystems responsible for updating the game state, but a low self time because it doesn't do much work on its own, while a collision-physics function may show significant self time, which tells you that this particular section needs optimization. The problems here are much the same as with the previous metric, because self time can't reflect a function's actual impact on the overall performance of the system. A function may have a low self time while triggering many expensive operations through other functions, which creates a false impression of efficiency. On top of that, this metric ignores function call overhead, so if a function makes thousands of small calls, the cost of creating stack frames, passing parameters, and returning values can be significant, or even close to the actual execution time, and still stay invisible in the self-time numbers.&lt;/p&gt;

&lt;p&gt;Another issue is "aggressive optimization," which is especially common with Clang-based compilers that inline small functions and partially embed their code at the call site. As a result, self-time measurements get distorted, because code that belongs to a different function is counted as self time for the caller (Pic. 3.2).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy1pbly8wx5as494pc6lr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy1pbly8wx5as494pc6lr.png" alt="1422_pt_7/image3.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Picture 3. 2&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Calls&lt;/strong&gt; metric shows how often a particular piece of code runs during a profiling session, which helps reveal how different functions are actually used in the application. Even if their individual execution times are short, functions with a high call count are good candidates for optimization, because the cumulative overhead of all those calls can be significant.&lt;/p&gt;

&lt;p&gt;Analyzing call counts is one of the first steps in finding inefficient algorithms or unnecessary computations (with one caveat, which is covered in the note below). A function that gets called thousands of times per frame may need a whole range of optimization techniques, and a high call count can also point to recursion, resource leaks, or other architectural problems in the application (Pic. 3.3).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbenh4kchc00j2rzy4g5u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbenh4kchc00j2rzy4g5u.png" alt="1422_pt_7/image4.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Picture 3.3&lt;/p&gt;

&lt;p&gt;Overall, this is a fairly useful metric, but the call count alone doesn't show how those calls are distributed over time. A function may be called 100,000 times in a session, but if all those calls happen while a level is loading, they have no impact on gameplay performance, and in that case the profiler will show a high call count without telling you that the function sits idle while frames are being rendered. The call count can also be misleading when it comes to spotting real architectural problems, because a high number of calls may simply be the result of a well-designed architecture with lots of small, specialized functions rather than a sign of inefficiency.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modern compilers have gotten very good at inlining, so focusing only on call counts can lead to premature or incorrect conclusions\.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Total waste time&lt;/strong&gt; tracks how long a function spends with its thread blocked while waiting for resources to become available, I/O operations to complete, or system events to occur (Fig. 3.4). This time doesn't reflect active execution of the function, but rather delays caused by external factors, and a high waste time can point to indirect performance problems that affect the function's overall execution time. This metric is usually analyzed when refactoring code or reducing dependencies between functions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq6bvymm65m6c9wvxgkpm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq6bvymm65m6c9wvxgkpm.png" alt="1422_pt_7/image5.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Picture 3.4&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Author: Sergei Kushnirenko&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sergei has over 20-year experience in coding and game development. He graduated from ITMO National Research University and began his career developing software for naval simulators, navigation systems, and network solutions. For the past fifteen years, Sergei has specialized in game development: at Electronic Arts, he worked on optimizing The Sims and SimCity BuildIt, and at Gaijin Entertainment, Sergei headed up the porting of games to the Nintendo Switch and Apple TV platforms. Sergei actively participates in open-source projects, including the ImSpinner library and the Pharaoh (1999) game restoration project.&lt;/p&gt;

&lt;h2&gt;
  
  
  All parts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/1361/" rel="noopener noreferrer"&gt;Game++. Part 1.1: C++, game engines, and architectures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/1375/" rel="noopener noreferrer"&gt;Game++. Part 1.2: C++, game engines, and architectures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/1384/" rel="noopener noreferrer"&gt;Game++. Part 1.3: C++, game engines, and architectures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/1390/" rel="noopener noreferrer"&gt;Game++. Part 1.4: C++, game engines, and architectures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/1397/" rel="noopener noreferrer"&gt;Game++. Part 2.1: Types of optimization&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cpp</category>
      <category>gamedev</category>
      <category>programming</category>
    </item>
    <item>
      <title>What's new in C# 15: Overview</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Tue, 20 Oct 2026 14:12:02 +0000</pubDate>
      <link>https://dev.to/pvsdev/whats-new-in-c-15-overview-3md3</link>
      <guid>https://dev.to/pvsdev/whats-new-in-c-15-overview-3md3</guid>
      <description>&lt;p&gt;A new version of C# is coming soon, so we're continuing our annual tradition of reviewing its new features. The Microsoft team has prepared several highly anticipated and exciting changes for this release. Let's take a look at them. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7h6yhwy2pluk2yy3spls.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7h6yhwy2pluk2yy3spls.png" alt=" " width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Union types
&lt;/h2&gt;

&lt;p&gt;We'll start with the most straightforward change, &lt;code&gt;union&lt;/code&gt; types. They enable developers to combine types without relying on inheritance or interfaces where it's unnecessary or unavailable. A &lt;code&gt;union&lt;/code&gt; is a structure that contains the complete set of supported types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;union&lt;/span&gt; &lt;span class="nf"&gt;TestUnion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Version&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, &lt;code&gt;union&lt;/code&gt; is the keyword, while &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;Version&lt;/code&gt;, and &lt;code&gt;IEnumerable&amp;lt;string&amp;gt;&lt;/code&gt; are the set of supported types.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;union&lt;/code&gt; types come in handy when traditional inheritance isn't an option, as it requires the types to have something in common. However, there may be cases where inheritance is impossible or makes little architectural sense. We might need to handle a specific set of types, including primitives. Normally, we'd have to specify a variable of the &lt;code&gt;object&lt;/code&gt; type as input and then cast it to the required types within the method, including logic for handling anything unsupported. That's error-prone. Using &lt;code&gt;union&lt;/code&gt; in this situation would solve these problems, making the code safer and easier to read.&lt;/p&gt;

&lt;p&gt;Given the nature of the new structure, when we use &lt;code&gt;union&lt;/code&gt;, the compiler already knows the complete list of types it can contain. So, the &lt;code&gt;default&lt;/code&gt; branch is no longer necessary. The change protects us from a &lt;code&gt;switch&lt;/code&gt; that misses some types while new subclasses keep falling into the &lt;code&gt;default&lt;/code&gt; section, which can cause unpredictable program behavior.&lt;/p&gt;

&lt;p&gt;Let's look at a more specific example. Before this update, we'd have had to write something like this to define a method for handling API responses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;abstract&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="n"&gt;ApiResult&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;ErrorData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="n"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ApiResult&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="n"&gt;ValidationError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ErrorData&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ApiResult&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ApiResult&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Success&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ValidationError&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"Unknown result"&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ApiResult&lt;/code&gt; abstract class, from which specific responses inherit, is declared. So, if a new subclass appears and the developer fails to handle it, executions falls into the &lt;code&gt;default&lt;/code&gt; branch. With a &lt;code&gt;union&lt;/code&gt;, it works differently:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;ErrorData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="nf"&gt;ValidationError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ErrorData&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;union&lt;/span&gt; &lt;span class="nf"&gt;ApiResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ValidationError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;GetData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;Success&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;ValidationError&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, there's no need for a parent class just to group the types together. The behavior is also more predictable because the compiler knows at compile time exactly which types &lt;code&gt;union&lt;/code&gt; can contain. So, if a &lt;code&gt;switch&lt;/code&gt; doesn't handle every type in the union, the compiler issues a warning.&lt;/p&gt;

&lt;p&gt;Moreover, the &lt;code&gt;union&lt;/code&gt; gives developers an easier way to express patterns such as monads. It also enables implementing custom methods and properties within &lt;code&gt;union&lt;/code&gt;, so working with all its types doesn't require writing &lt;code&gt;switch&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closed hierarchies
&lt;/h2&gt;

&lt;p&gt;This change is somewhat related to &lt;code&gt;union&lt;/code&gt; in that it also lets the compiler know exactly how many types it'll work with. It does so by preventing inheritance from a class outside the assembly where it was declared. This behavior resembles a mix of &lt;code&gt;internal&lt;/code&gt; and &lt;code&gt;sealed&lt;/code&gt;: it takes the scope from &lt;code&gt;internal&lt;/code&gt; and the restriction on inheritance from &lt;code&gt;sealed&lt;/code&gt;. This can be useful, for example, in libraries where we want to restrict inheritance from certain classes without blocking it within our own assembly. Here's an example declaration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;closed&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt; &lt;span class="n"&gt;ClosedRecordClass&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;closed&lt;/code&gt; keyword marks the class as closed to inheritance. As a result, attempting to inherit from such a class in another assembly causes a compilation error. Note that, like &lt;code&gt;union&lt;/code&gt;, a closed hierarchy supports an exhaustive &lt;code&gt;switch&lt;/code&gt;, which enables omitting the &lt;code&gt;default&lt;/code&gt; branch. &lt;/p&gt;

&lt;p&gt;A few important details are worth keeping in mind. Firstly, a class marked as &lt;code&gt;closed&lt;/code&gt; is always abstract. This also helps enable an exhaustive &lt;code&gt;switch&lt;/code&gt;. Secondly, descendants don't automatically become closed. If we need to hide them from other assemblies, we can mark them with the &lt;code&gt;internal&lt;/code&gt; access modifier. Thirdly, only classes (&lt;code&gt;class&lt;/code&gt; and &lt;code&gt;record class&lt;/code&gt;) can be closed to inheritance from another assembly. Structs don't support inheritance, while interfaces are specifically designed to be inherited from. So, adding the keyword to a struct or an interface will result in a compilation error. &lt;/p&gt;

&lt;h2&gt;
  
  
  Labeled break and continue
&lt;/h2&gt;

&lt;p&gt;A small but quite important addition: most of us have probably run into situations where we needed to interrupt the execution of an external structure or skip to its next iteration. The classic approach would have looked something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;WorkItemType&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;StopAll&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WorkItem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ....&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;WorkItemType&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OldLabeledBreak&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;PerformAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;WorkItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;workList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;stopProcessing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;workList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// #1&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// #2&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;WorkItemType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="c1"&gt;// ....&lt;/span&gt;
          &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// break #2&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;WorkItemType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StopAll&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="n"&gt;stopProcessing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// break #2&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stopProcessing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// break #1&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// ....&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In other words, we need an additional flag so that the outer loop can exit after the inner &lt;code&gt;switch&lt;/code&gt; finishes executing. Of course, we could use &lt;code&gt;goto&lt;/code&gt;, but it can make the code harder to follow because the label code execution jumps to can appear anywhere. Labeled &lt;code&gt;break&lt;/code&gt; and &lt;code&gt;continue&lt;/code&gt; simplify this. Let's see what this method would look like now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PerformAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;WorkItem&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;workList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;outer:&lt;/span&gt;  &lt;span class="n"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;workList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// #1&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// #2&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;WorkItemType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;// ....&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// break #2&lt;/span&gt;
      &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;WorkItemType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StopAll&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="n"&gt;outer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// break #1&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="c1"&gt;// ....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the syntax is similar to &lt;code&gt;goto&lt;/code&gt;, while the code becomes more readable. This lets us avoid creating extra flags and checks, which can slightly reduce memory usage and also make the code more expressive. Labels can be applied with the following constructs: &lt;code&gt;for&lt;/code&gt;, &lt;code&gt;foreach&lt;/code&gt;, &lt;code&gt;while&lt;/code&gt;, &lt;code&gt;do&lt;/code&gt;, and &lt;code&gt;switch&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extension indexers
&lt;/h2&gt;

&lt;p&gt;This change enables developers to define how collection elements can be accessed by index using extension indexers. For example, it's possible to implement element access with &lt;code&gt;Range&lt;/code&gt; for &lt;code&gt;IReadOnlyList&lt;/code&gt;. Before C# 15, we could implement this as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OldExtensionIndexers&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;IReadOnlyList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;readOnlyList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"val1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"val2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"val3"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;readOnlyList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Slice&lt;/span&gt;&lt;span class="p"&gt;(.&lt;/span&gt;&lt;span class="mf"&gt;.2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OldReadOnlyListExtensions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;IReadOnlyList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Slice&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;IReadOnlyList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                          &lt;span class="n"&gt;Range&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetOffsetAndLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While a regular extension method already solves this problem, C# 15 introduces the option to create extension indexers. So, we'll get access to elements using the familiar brackets. Let's look at how this would work in our example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NewExtensionIndexers&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;IReadOnlyList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;readOnlyList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"val1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"val2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"val3"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;readOnlyList&lt;/span&gt;&lt;span class="p"&gt;[.&lt;/span&gt;&lt;span class="mf"&gt;.2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NewReadOnlyListExtensions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;extension&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IReadOnlyList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IReadOnlyList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Range&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;get&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetOffsetAndLength&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Skip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's worth noting that if a type has its own indexer, it takes precedence over an indexer declared as an extension. The official order of precedence is as follows: &lt;code&gt;explicit&lt;/code&gt; type indexers, &lt;code&gt;implicit&lt;/code&gt; type indexers, &lt;code&gt;explicit&lt;/code&gt; extension indexers, and &lt;code&gt;implicit&lt;/code&gt; extension indexers. &lt;/p&gt;

&lt;h2&gt;
  
  
  Collection expression arguments
&lt;/h2&gt;

&lt;p&gt;The next feature will help shorten code and make collection initialization more convenient by passing the required arguments directly to the constructor. For example, we can pass &lt;code&gt;capacity&lt;/code&gt; and &lt;code&gt;comparer&lt;/code&gt;. In C# 14 and earlier, we would need to write something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ProcessList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;loginList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"login1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"login2"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;newLoginList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loginList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;newLoginList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loginList&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ProcessHashSet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hashSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StringComparer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OrdinalIgnoreCase&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;hashSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"value 1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;hashSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"value 2"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The initializer supports only one option because &lt;code&gt;List&lt;/code&gt; has just three constructors: an empty one, one that takes &lt;code&gt;capacity&lt;/code&gt;, and one that takes a collection. Let's look at the new possible implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ProcessList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;loginList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"login1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"login2"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;newLoginList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;loginList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="n"&gt;loginList&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="c1"&gt;// newLoginList.AddRange(loginList);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ProcessHashSet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hashSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StringComparer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OrdinalIgnoreCase&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
    &lt;span class="s"&gt;"value 1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"value 2"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="c1"&gt;// hashSet.Add("value 1");&lt;/span&gt;
  &lt;span class="c1"&gt;// hashSet.Add("value 2");&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code looks cleaner, right? Your IDE will probably even suggest this syntax and collapse everything into a single line. However, note that &lt;code&gt;with&lt;/code&gt; must always come first; otherwise, the compiler will issue an error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory safety
&lt;/h2&gt;

&lt;p&gt;The final change involves reevaluating what C# considers unsafe. The language team aims to flag only code that actually accesses unmanaged memory as unsafe. In other words, using pointers will no longer automatically make code unsafe. Before C# 15, unsafe code was marked like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;unsafe&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OldMemorySafety&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ReadMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;newPtr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ReadMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newPtr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Any use of pointers used to require the &lt;code&gt;unsafe&lt;/code&gt; keyword. To better understand the change, let's take a look at what the code will look like in the new version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NewMemorySafety&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ReadMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;unsafe&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ptr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;newPtr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ReadMemory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newPtr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We no longer need to mark the class as &lt;code&gt;unsafe&lt;/code&gt;. Instead, the keyword goes only where it's needed. In this case, dereferencing the pointer is unsafe, so it should be marked as such.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;safe&lt;/code&gt; keyword has also been added. It should be used when a block contains unsafe operations that are safe for the caller's context, so callers don't require the &lt;code&gt;unsafe&lt;/code&gt; block. In other words, use &lt;code&gt;safe&lt;/code&gt; when the compiler can't verify safety on its own. Examples include &lt;code&gt;extern&lt;/code&gt; methods and fields in structs with explicit memory layout (&lt;code&gt;[StructLayout(LayoutKind.Explicit)]&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;It's also worth mentioning &lt;code&gt;stackalloc&lt;/code&gt;. Its use is now considered unsafe when all of the following apply: it's converted to &lt;code&gt;Span&amp;lt;T&amp;gt;&lt;/code&gt; or &lt;code&gt;ReadOnlySpan&amp;lt;T&amp;gt;&lt;/code&gt;, it has no initializer, and it's used where &lt;code&gt;SkipLocalsInitAttribute&lt;/code&gt; is present.&lt;/p&gt;

&lt;p&gt;The new rules introduced by this change should be enabled separately. If you'd like to learn more, follow &lt;a href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/language#enable-the-updated-memory-safety-rules" rel="noopener noreferrer"&gt;this link&lt;/a&gt; for the official instructions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This year's language release has brought developers a number of fairly important features. Among them are useful additions such as &lt;code&gt;union&lt;/code&gt; types and closed hierarchies, while several other changes simplify common coding patterns, making development little smoother once again. Some of these features may not become as popular, but that doesn't make them any less useful to certain groups of developers. Which of these changes did you find most useful? Share your thoughts in the comments!&lt;/p&gt;

&lt;p&gt;You can read the C# 15 documentation via &lt;a href="https://learn.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-15" rel="noopener noreferrer"&gt;this link&lt;/a&gt;. Don't forget to check out our overviews of previous versions, here's the list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/csharp/0860/" rel="noopener noreferrer"&gt;What's new in C# 9: overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/csharp/0875/" rel="noopener noreferrer"&gt;What's new in C# 10: overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/csharp/1002/" rel="noopener noreferrer"&gt;What's new in C# 11: overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/csharp/1074/" rel="noopener noreferrer"&gt;What's new in C# 12: overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/csharp/1173/" rel="noopener noreferrer"&gt;What's new in C# 13: overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/csharp/1301/" rel="noopener noreferrer"&gt;What's new in C# 14: overview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>news</category>
      <category>programming</category>
    </item>
    <item>
      <title>PVS-Studio 8.01: OWASP Benchmark, JDK 25 and Go 1.27 support, and much more</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Fri, 16 Oct 2026 14:02:33 +0000</pubDate>
      <link>https://dev.to/pvsdev/pvs-studio-801-owasp-benchmark-jdk-25-and-go-127-support-and-much-more-p5d</link>
      <guid>https://dev.to/pvsdev/pvs-studio-801-owasp-benchmark-jdk-25-and-go-127-support-and-much-more-p5d</guid>
      <description>&lt;p&gt;PVS-Studio 8.01 has been released. This version features expanded support for OWASP, JDK 25 and Go 1.27 support, and much more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi4358vjgxr1v5azcrjar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi4358vjgxr1v5azcrjar.png" alt=" " width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  OWASP Benchmark for Java
&lt;/h2&gt;

&lt;p&gt;In this release, we checked the Java analyzer SAST rules against the &lt;a href="https://owasp.org/www-project-benchmark/" rel="noopener noreferrer"&gt;OWASP Benchmark for Java&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Evaluating the quality of security-related diagnostic rules on real-world projects can be quite challenging. We can't predict how many vulnerabilities the code will contain, so we can't determine which defects the analyzer has overlooked.&lt;/p&gt;

&lt;p&gt;We used the benchmark to address gaps in the Java analyzer SAST capabilities, which made the tool more effective at detecting security defects.&lt;/p&gt;

&lt;h2&gt;
  
  
  New versions of Java and Go
&lt;/h2&gt;

&lt;p&gt;With the release of PVS-Studio 8.01, we've added support for the latest platform versions. The Java analyzer now supports JDK 25, and the Go analyzer supports Go 1.27. &lt;/p&gt;

&lt;p&gt;This enables teams to analyze projects using the latest language versions and standard libraries without delaying updates due to limitations in their analysis tools. &lt;/p&gt;

&lt;p&gt;JDK 25 is also an LTS release, making its support particularly important for teams migrating to a new long-term support version.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reports with analysis configuration details
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;PVS-Studio_Cmd.exe&lt;/code&gt; utility for analyzing MSBuild projects now includes in JSON reports the project configurations used during analysis. This makes it easier to fix warnings that occur on specific platforms. &lt;/p&gt;

&lt;p&gt;In addition, the &lt;code&gt;fullhtml&lt;/code&gt; report generated by &lt;a href="https://pvs-studio.com/en/docs/manual/0038/" rel="noopener noreferrer"&gt;&lt;code&gt;PlogConverter.exe&lt;/code&gt;&lt;/a&gt; now groups warnings by analysis configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Expanded configuration options
&lt;/h2&gt;

&lt;p&gt;This release expands the configuration options for our analyzers and utilities, making them easier to tailor to specific project requirements and environments.&lt;/p&gt;

&lt;p&gt;The JavaScript and TypeScript analyzer now supports the &lt;code&gt;max-old-space-size&lt;/code&gt; setting. You can find it in the &lt;a href="https://pvs-studio.com/en/docs/manual/7193/" rel="noopener noreferrer"&gt;&lt;code&gt;pvs-settings.toml&lt;/code&gt; configuration file&lt;/a&gt; and the &lt;a href="https://pvs-studio.com/en/docs/manual/7195/" rel="noopener noreferrer"&gt;&lt;code&gt;pvs-js.exe&lt;/code&gt; command-line utility&lt;/a&gt;. This setting enables you to specify how much memory the analyzer's Node.js server can use.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;PVS-Studio_Cmd.exe&lt;/code&gt;, you can now specify dependency cache paths relative to the &lt;a href="https://pvs-studio.com/en/docs/manual/6630/" rel="noopener noreferrer"&gt;&lt;code&gt;.pvsconfig&lt;/code&gt; configuration file&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The C and C++ analyzer now offers more options for configuring diagnostic rules. Now, you can specify custom types as "cheap-to-copy," and configure the analyzer behavior based on the target platform.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://pvs-studio.com/en/docs/warnings/v719/" rel="noopener noreferrer"&gt;V719&lt;/a&gt; diagnostic rule now supports additional configuration options: ignoring &lt;code&gt;default&lt;/code&gt; branches and small &lt;code&gt;enum&lt;/code&gt; types, specifying individual values to ignore, and setting the maximum number of constants that can be ignored.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extended warning filtering
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://pvs-studio.com/en/docs/manual/0038/" rel="noopener noreferrer"&gt;Plog Converter utility&lt;/a&gt; for converting and filtering reports now allows you to filter diagnostic rules by CWE codes and SAST identifiers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Breaking Change
&lt;/h2&gt;

&lt;p&gt;This release includes a change that breaks backward compatibility with previous versions of the analyzer. You may need to adjust how you use the analyzer due to these changes.&lt;/p&gt;

&lt;p&gt;The PVS-Studio installer for Windows now &lt;a href="https://pvs-studio.com/en/docs/manual/0025/" rel="noopener noreferrer"&gt;returns exit code &lt;code&gt;100&lt;/code&gt;&lt;/a&gt; if Visual Studio plugin installation fails. We also added the &lt;code&gt;skipVSIXInstallErrorCode&lt;/code&gt; flag to disable the non-zero exit code in this case.&lt;/p&gt;

&lt;h2&gt;
  
  
  New diagnostic rules
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Java
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/docs/warnings/v5341/" rel="noopener noreferrer"&gt;V5341&lt;/a&gt;. OWASP. A cookie was created without enabling the 'Secure' attribute. This may lead to the exposure of sensitive data.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/docs/warnings/v5342/" rel="noopener noreferrer"&gt;V5342&lt;/a&gt;. OWASP. Potentially tainted data is stored in an object that can be used as a source of trusted data.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/docs/warnings/v5343/" rel="noopener noreferrer"&gt;V5343&lt;/a&gt;. OWASP. A cryptographically weak random number is used for sensitive data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Articles
&lt;/h2&gt;

&lt;p&gt;Here's the traditional roundup of posts from our blog! Over the past two months, we've published articles where we looked for bugs in the popular C# ORMs, RepoDB and SqlSugar, reviewed VSCode source code, explored the new features of Java 27, found bugs in the Create mode, and much more. The full list is below:&lt;/p&gt;

&lt;h3&gt;
  
  
  C and C++
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/cpp/1409/" rel="noopener noreferrer"&gt;The worst programming language of all time /s&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Csharp
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/csharp/1411/" rel="noopener noreferrer"&gt;What popular ORMs for C# hide: Let's check RepoDB and SqlSugar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Java
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/java/1412/" rel="noopener noreferrer"&gt;What's new in Java 27&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/java/1417/" rel="noopener noreferrer"&gt;I found some bugs in Create mod and checked them in Minecraft&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  JavaScript and TypeScript
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/js/1407/" rel="noopener noreferrer"&gt;We checked the source code of VS Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Go
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/go/1413/" rel="noopener noreferrer"&gt;PVS-Studio for Go: Quick overview of new diagnostic rules&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/1408/" rel="noopener noreferrer"&gt;Avoid adding new library to project: 10-year retrospective&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Other
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pvs-studio.com/en/blog/posts/1410/" rel="noopener noreferrer"&gt;Why do we integrate PVS-Studio analyzer with so many tools?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Webinars
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Let's make a programming language. Variables
&lt;/h3&gt;

&lt;p&gt;We continue building our own programming language from scratch. In this video, we'll take the next step by adding variables to the language.&lt;/p&gt;

&lt;p&gt;So far, our programs have consisted of a single expression built from smaller language constructs. Now it's time to evolve the language. Instead of parsing a single expression, we'll introduce a list of declarations, allowing our language to support variable declarations and laying the groundwork for more complex programs.&lt;/p&gt;

&lt;p&gt;During the video, Yuri will walk through the implementation step by step, showing how variables are represented and processed in our language, and how to add this functionality to your language in C++.&lt;/p&gt;

&lt;p&gt;This video is designed for developers who want to understand how programming languages work under the hood—not just how to use them.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/Sn8fVb_O90Y" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Go-Go-Gadg...Error? A closer look at the mistakes Go developers make!
&lt;/h3&gt;

&lt;p&gt;Mistakes happen in Go code just like in any other language: typos, duplicates, broken condition checks, and so on.&lt;/p&gt;

&lt;p&gt;But why do they still slip through? After all, many teams use tools like go vet, which catches all of this perfectly well... right?&lt;/p&gt;

&lt;p&gt;In this webinar we covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Common mistakes in Go code, straight from well-known projects;&lt;/li&gt;
&lt;li&gt;Errors that standard tools and approaches fail to catch, and how to handle them.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/gdF_AObnq6Y" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Let's make a programming language. Functions
&lt;/h3&gt;

&lt;p&gt;We continue building our own programming language from scratch.&lt;/p&gt;

&lt;p&gt;In the previous session, we introduced variables—they could be declared, reference one another, and were resolved through a global hash table. Now it's time to add one of the core building blocks of any language: functions. Implementing functions is really a story about scopes and name resolution. We'll explore how identifiers are looked up across different scope levels: the global scope, function scopes with their own variables, and nested local scopes inside function bodies. What happens when the same variable name exists in multiple scopes? How does the compiler determine which one to use?&lt;/p&gt;

&lt;p&gt;In this video, we will walk through the implementation step by step, demonstrating how functions, scopes, and symbol lookup are built in code using C++. Along the way, you'll gain a deeper understanding of one of the fundamental mechanisms behind modern programming languages. &lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/QT7tyIENfZI" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h4&gt;
  
  
  Let's make a programming language. Evaluator
&lt;/h4&gt;

&lt;p&gt;We're reaching the final stage of our journey of building a programming language in C++!&lt;/p&gt;

&lt;p&gt;So far, we've created a lexer, a parser, and an AST. Now it's time to make our language do what it was designed to do—evaluate expressions.&lt;/p&gt;

&lt;p&gt;In this webinar, we'll explore how to represent the results of computations in our language and learn how to evaluate expressions step by step. By the end of the session, we'll bring all the pieces together and complete our own programming language.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/2-3ytWWhy8s" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Go vet can't go: How to create your own Go analyzer?
&lt;/h3&gt;

&lt;p&gt;A static analyzer is a powerful dev tool, and any Go developer who has worked with go vet knows it. But what if its capabilities aren't enough? Would you look for a new tool, or... build your own?&lt;/p&gt;

&lt;p&gt;In this live talk, PVS-Studio's Developer Advocate walks through Go's built-in tools and code-parsing capabilities, explains the basics of static analysis, unpacks what a semantic model is, shows how to build a syntax tree, and much more.&lt;/p&gt;

&lt;p&gt;The end goal? Build your own static analyzer, tailored to catch what matters most in your projects.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/KAaJT_mUijA" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Bugbusters
&lt;/h2&gt;

&lt;p&gt;This is the first episode of our new podcast, Bugbusters. Our guest is Nathan Baggs, a content creator and YouTuber. We discussed whether it's worth learning C++ in 2026, how the language is evolving, what it's used for, and what its drawbacks are. We hope you enjoy this episode! We look forward to your comments!&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/kd-5hJHvKIY" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If you would like to receive news about PVS-Studio releases, &lt;a href="https://pvs-studio.com/en/subscribe/" rel="noopener noreferrer"&gt;subscribe to our newsletter here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you haven't checked your project using PVS-Studio yet, &lt;a href="https://pvs-studio.com/en/pvs-studio/try-free/?utm_source=website&amp;amp;utm_medium=devto&amp;amp;utm_campaign=article&amp;amp;utm_content=1420" rel="noopener noreferrer"&gt;start with a trial license&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>news</category>
      <category>cpp</category>
      <category>java</category>
      <category>go</category>
    </item>
    <item>
      <title>When copy-paste goes wrong: Bugs in structurally isomorphic Go code</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Tue, 13 Oct 2026 14:20:32 +0000</pubDate>
      <link>https://dev.to/pvsdev/when-copy-paste-goes-wrong-bugs-in-structurally-isomorphic-go-code-1ng8</link>
      <guid>https://dev.to/pvsdev/when-copy-paste-goes-wrong-bugs-in-structurally-isomorphic-go-code-1ng8</guid>
      <description>&lt;p&gt;You might've done this many times: you found code in a project that seemed like a good fit for your task, copied it, replaced the variables or function calls with the ones you needed, and then got behavior you didn't expect when you ran the code. It's likely that you missed something while making those changes. This is exactly how the errors described in this article occur.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flc2ey8jxn6fvcw3ofz34.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flc2ey8jxn6fvcw3ofz34.png" alt=" " width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;PVS-Studio 8.00 was recently released, introducing several &lt;a href="https://pvs-studio.com/en/blog/posts/1406/" rel="noopener noreferrer"&gt;new major features&lt;/a&gt;, including the Go analyzer that comes with several new and cool diagnostic rules. &lt;/p&gt;

&lt;p&gt;It includes a rule that detects one of the trickiest types of copy-paste bugs, the kind that can easily slip past a regular code review. Okay, now let's take a look at the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProcessName&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProcessName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
   &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProcessName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NameFieldMaxLength&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;kit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CCError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CCErrorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CCErrCommParamsInvalid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        
                              &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BKProcessNameField&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FuncName&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FuncName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
   &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ProcessName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NameFieldMaxLength&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;kit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CCError&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CCErrorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CCErrCommParamsInvalid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                              &lt;span class="n"&gt;common&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BKFuncName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You've probably noticed that the expressions in both &lt;code&gt;if&lt;/code&gt; statements consist of the same checks, but they aren't completely identical: the first one uses &lt;code&gt;process.ProcessName&lt;/code&gt;, while the second one uses &lt;code&gt;process.FuncName&lt;/code&gt; in the same positions. Or... does it?&lt;/p&gt;

&lt;p&gt;The last checks suspiciously break this pattern: they're exactly the same, and both use the &lt;code&gt;process.ProcessName&lt;/code&gt; field. Based on the logic the code has consistently followed so far, the check in the second &lt;code&gt;if&lt;/code&gt; should have used a different field, &lt;code&gt;process.FuncName&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Since such typos can easily slip past manual review, the best solution is to delegate the task of catching them to a static analyzer. But how can we teach a program to compare similar yet distinct code fragments and use those comparisons to detect bugs the way humans do? Is AI necessary for that? In the rest of this article, we'll explore these questions by looking at how the diagnostic rule works in PVS-Studio for Go. &lt;/p&gt;

&lt;h2&gt;
  
  
  How does the analyzer find these bugs?
&lt;/h2&gt;

&lt;p&gt;Modern AI models can indeed detect such bugs. However, integrating artificial intelligence into a static analyzer for such a purpose is too expensive and resource-intensive.&lt;/p&gt;

&lt;p&gt;Fortunately, we don't need AI here. We can handle the task with a relatively simple heuristic algorithm. We'll take a closer look at how it works later, but first, let's go over a few basic concepts from static code analysis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Statements are the elements of code that form its skeleton and describe the execution flow (&lt;code&gt;if&lt;/code&gt;, &lt;code&gt;switch&lt;/code&gt;, &lt;code&gt;for&lt;/code&gt;, and &lt;code&gt;{...}&lt;/code&gt; blocks).&lt;/li&gt;
&lt;li&gt;Expressions are code elements that manage data (function calls, variables, and operators).&lt;/li&gt;
&lt;li&gt;Nodes is a general term for statements, expressions, and other types of code elements.&lt;/li&gt;
&lt;li&gt;Abstract Syntax Tree (AST) represents code as a hierarchical structure where some elements, like folders in a file system, contain other elements. An AST contains the same information you can get from the code itself, but its structured format makes it better suited for program analysis.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're interested in delving deeper into static analysis, we have the perfect &lt;a href="https://pvs-studio.com/en/blog/posts/go/1329/" rel="noopener noreferrer"&gt;article&lt;/a&gt; for you.&lt;/p&gt;

&lt;p&gt;Well, now that we have enough context, we're ready to face the &lt;del&gt;boss&lt;/del&gt; algorithm. Here's how the &lt;a href="https://pvs-studio.com/en/docs/warnings/v8033/" rel="noopener noreferrer"&gt;V8033&lt;/a&gt; diagnostic rule in PVS-Studio's Go analyzer works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Within a function, the analyzer takes individual statements and groups of statements, separated by blank lines (hereinafter referred to as code fragments) and builds a simplified AST for them. Unlike a regular AST, it contains only the information needed to describe the code structure and omits specific names of variables, functions, and other semantic information.&lt;/li&gt;
&lt;li&gt;The fragments are grouped by their simplified AST. This is how fragments with similar structure are identified, even though they may still differ in their details (for example, in the variables they use).&lt;/li&gt;
&lt;li&gt;Within each group, the fragments are paired and compared with one another. Let's look at how the algorithm works for a single pair. For convenience, let's call the two fragments in one pair A and B.&lt;/li&gt;
&lt;li&gt;The analyzer identifies the variables that appear in both A and B (common variables) as well as the variables that appear in only one of the fragments (specific variables).&lt;/li&gt;
&lt;li&gt;Let's assume that A is higher in the code than B. If one of the common variables occurs less frequently in B than in A, but still at the same relative positions, the uses of that variable in B are treated as potential typos.&lt;/li&gt;
&lt;li&gt;Next, a replacement candidate is sought among the B variables. This variable must be used in the same relative position as the previously considered general variable in A, but not in B.&lt;/li&gt;
&lt;li&gt;If the analyzer finds such a candidate, it performs a series of final checks to determine whether the variables are interchangeable. If all the checks pass, the developer receives warnings about possible typos in the code.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Of course, this is just a conceptual outline. A significant amount of important logic remains behind the scenes, especially the logic that filters out false positives. Without it, the diagnostic rule would be far less useful.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is only 5% of the task to create the diagnostic. It's not hard for the analyzer to complain about suspicious code, it's much harder to not complain about the correct code. We spend 95% of our time "teaching" the analyzer to detect various programming techniques, which may seem suspicious for the diagnostic, but in reality they are correct.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From the &lt;a href="https://pvs-studio.com/en/blog/posts/cpp/0466/" rel="noopener noreferrer"&gt;article&lt;/a&gt; "How PVS-Studio does the bug search: methods and technologies"&lt;/p&gt;

&lt;p&gt;Now that we've taken a quick look at how the analyzer works, let's exercise in looking for similar errors on our own.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find an error
&lt;/h2&gt;

&lt;p&gt;I invite you to challenge yourselves by finding errors in this code, which was taken from real open-source projects. The closer you get to the end, the harder the examples become. &lt;/p&gt;

&lt;p&gt;Are you up for the challenge? Let's get started, then!&lt;/p&gt;

&lt;h3&gt;
  
  
  Yao Agents
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/YaoApp/yao" rel="noopener noreferrer"&gt;Yao Agents&lt;/a&gt; is an open-source platform for creating and running autonomous AI agents. Its key feature is that the agents run directly on users' devices, while all operations are centralized and controlled via a single interface.&lt;/p&gt;

&lt;p&gt;We found this code in the &lt;a href="https://github.com/YaoApp/yao/releases/tag/v1.0.0-rc15" rel="noopener noreferrer"&gt;v1.0.0-rc15&lt;/a&gt; release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;Generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;option&lt;/span&gt; &lt;span class="n"&gt;Option&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Width&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;240&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Height&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lang&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;option&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lang&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"zh"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;/p&gt;
  The analyzer's hint
  &lt;br&gt;
V8033 Two similar code fragments were found. The second fragment may contain a typo: the "option.Height" variable should be used instead of the "option.Width". &lt;a href="https://github.com/YaoApp/yao/blob/8999225a4ca612cb665f81f47bd65b2c89a10cd3/utils/captcha/captcha.go#L48" rel="noopener noreferrer"&gt;captcha.go 48&lt;/a&gt;



&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  CDS
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/ovh/cds" rel="noopener noreferrer"&gt;CDS&lt;/a&gt; is an enterprise-grade platform for automating DevOps processes, continuous integration (CI), and continuous delivery (CD).&lt;/p&gt;

&lt;p&gt;We found this code in the &lt;a href="https://github.com/ovh/cds/releases/tag/v0.54.1" rel="noopener noreferrer"&gt;0.54.1&lt;/a&gt; release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GraylogFieldCDSServiceName&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;extra&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"CDSName"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GraylogFieldCDSServiceName&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GraylogFieldCDSServiceName&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;extra&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"CDSService"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GraylogFieldCDSServiceType&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GraylogFieldCDSVersion&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;extra&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"CDSVersion"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GraylogFieldCDSVersion&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GraylogFieldCDSOS&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;extra&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"CDSOS"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GraylogFieldCDSOS&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GraylogFieldCDSArch&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;extra&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"CDSArch"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GraylogFieldCDSArch&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;/p&gt;
  The analyzer's hint
  &lt;br&gt;
V8033 Two similar code fragments were found. The second fragment may contain a typo: the "conf.GraylogFieldCDSServiceType" variable should be used instead of the "conf.GraylogFieldCDSServiceName". &lt;a href="https://github.com/ovh/cds/blob/a58c0035cb4fc99830d5604e4657d4a1d577e2c5/sdk/log/log.go#L160" rel="noopener noreferrer"&gt;log.go 107&lt;/a&gt;



&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  BFE
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/bfenetworks/bfe" rel="noopener noreferrer"&gt;BFE&lt;/a&gt; is a high-performance, application-level load balancer and reverse proxy server.&lt;/p&gt;

&lt;p&gt;We found this code in the &lt;a href="https://github.com/bfenetworks/bfe/releases/tag/v1.8.4" rel="noopener noreferrer"&gt;1.8.4&lt;/a&gt; release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Basic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WasmPluginPath&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Basic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WasmPluginPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mod_wasm"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Basic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WasmPluginPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bfe_util&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConfPathProc&lt;/span&gt;&lt;span class="p"&gt;(....)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Basic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataPath&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Basic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WasmPluginPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"mod_wasm/wasm.data"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Basic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;bfe_util&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConfPathProc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Basic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                                           &lt;span class="n"&gt;confRoot&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;/p&gt;
  The analyzer's hint
  &lt;br&gt;
V8033 Two similar code fragments were found. The second fragment may contain a typo: the "cfg.Basic.DataPath" variable should be used instead of the "cfg.Basic.WasmPluginPath". &lt;a href="https://github.com/bfenetworks/bfe/blob/b9fb26f3e7be27b4caf6b1a5540fb2dcb9b5659a/bfe_modules/mod_wasmplugin/conf_mod_wasmplugin.go#L63" rel="noopener noreferrer"&gt;conf_mod_wasmplugin.go 63&lt;/a&gt;



&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Hertz
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/cloudwego/hertz" rel="noopener noreferrer"&gt;Hertz&lt;/a&gt; is a high-performance HTTP framework written in Go by ByteDance (the creators of TikTok), designed for building high-load microservices. It combined the concepts of popular Go frameworks (Gin, FastHTTP) with ByteDance's internal requirements.&lt;/p&gt;

&lt;p&gt;We found this code in the &lt;a href="https://github.com/cloudwego/hertz/releases/tag/v0.10.6" rel="noopener noreferrer"&gt;0.10.6&lt;/a&gt; release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;goOptMapAlias&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetOptions&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;GetGoPackage&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;reqName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;goOptMapAlias&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetOptions&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;GetGoPackage&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
            &lt;span class="s"&gt;"."&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;inputGoType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GoIdent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GoName&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;goOptMapAlias&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetOptions&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;GetGoPackage&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;respName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;goOptMapAlias&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetOptions&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;GetGoPackage&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
             &lt;span class="s"&gt;"."&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;outputGoType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GoIdent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GoName&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;/p&gt;
  The analyzer's hint
  &lt;br&gt;
V8033 Two similar code fragments were found. The second fragment may contain a typo: the "st" variable should be used instead of the "sb". &lt;a href="https://github.com/cloudwego/hertz/blob/3415de4ca25f550996dab49d62839ebc6165d6b9/cmd/hz/protobuf/ast.go#L233" rel="noopener noreferrer"&gt;ast.go 233&lt;/a&gt;



&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Nuclei
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/projectdiscovery/nuclei/tree/dev" rel="noopener noreferrer"&gt;Nuclei&lt;/a&gt; is a modern, high-performance vulnerability scanner that uses simple YAML-based templates. It enables users to create their own vulnerability detection scenarios that simulate real-world conditions, which eliminates false positives.&lt;/p&gt;

&lt;p&gt;We found this code in the &lt;a href="https://github.com/projectdiscovery/nuclei/releases/tag/v3.11.1" rel="noopener noreferrer"&gt;3.11.1&lt;/a&gt; release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExcludeTags&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="n"&gt;splitCommaTrim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Severities&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;severities&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;severities&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExcludeProtocols&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;excludeTypes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;excludeTypes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ExcludeIds&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="n"&gt;splitCommaTrim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;excludeIds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;/p&gt;
  The analyzer's hint
  &lt;br&gt;
V8033 Two similar code fragments were found. The second fragment may contain a typo: the "filter.excludeIds" variable should be used instead of the "filter.block". &lt;a href="https://github.com/projectdiscovery/nuclei/blob/bb79d8ed71fcb71b49ca0563ecadbb3083857cd9/pkg/templates/tag_filter.go#L434" rel="noopener noreferrer"&gt;tag_filter.go 434&lt;/a&gt;



&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  LakeFS
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/treeverse/lakeFS" rel="noopener noreferrer"&gt;LakeFS&lt;/a&gt; is an open-source data version control system for managing data stored in an object storage system. It enables Git-like operations like branching, committing, merging, and rolling back for large-scale data, stored in systems including Amazon S3, Azure Blob Storage, and Google Cloud Storage, as well as on other S3-compatible object storage platforms.&lt;/p&gt;

&lt;p&gt;We found this code in the &lt;a href="https://github.com/treeverse/lakeFS/releases/tag/v1.86.0" rel="noopener noreferrer"&gt;1.86.0&lt;/a&gt; release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;usersKey&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GroupUserPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;groupID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;kv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewSecondaryIterator&lt;/span&gt;&lt;span class="p"&gt;(....)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entry&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;policiesKey&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GroupPolicyPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;groupID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;itr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;kv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewSecondaryIterator&lt;/span&gt;&lt;span class="p"&gt;(....)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;itr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;itr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Entry&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;policy&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PolicyData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;itr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;/p&gt;
  The analyzer's hint
  &lt;br&gt;
V8033 Two similar code fragments were found. The second fragment may contain a typo: the "itr" variable should be used instead of the "it". &lt;a href="https://github.com/treeverse/lakeFS/blob/4bb11638e95637e853d9680abf072b14f09e32fb/contrib/auth/acl/service.go#L476" rel="noopener noreferrer"&gt;service.go 476&lt;/a&gt;



&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Vault
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/hashicorp/vault" rel="noopener noreferrer"&gt;Vault&lt;/a&gt; is an open-source (BSL) tool for centralized secret management, data encryption, and for the protection of confidential information in cloud and hybrid infrastructures.&lt;/p&gt;

&lt;p&gt;We found this code in the &lt;a href="https://github.com/hashicorp/vault/releases/tag/v2.0.4" rel="noopener noreferrer"&gt;2.0.4&lt;/a&gt; release:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;crl&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CRLs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CRLExpiryPercentage&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;used&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;expWhen&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;crl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ThisUpdate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ResultCritical&lt;/span&gt;
    &lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;....,&lt;/span&gt; 
      &lt;span class="n"&gt;crl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NextUpdate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2006-01-02"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
      &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CRLExpiryPercentage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   
      &lt;span class="n"&gt;crl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ThisUpdate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2006-01-02"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
      &lt;span class="n"&gt;expWhen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2006-01-02"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;crl&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;range&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DeltaCRLs&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DeltaCRLExpiryPercentage&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;int64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;used&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;ratio&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;expWhen&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;crl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ThisUpdate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ratio&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ResultCritical&lt;/span&gt;
    &lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;....,&lt;/span&gt; 
      &lt;span class="n"&gt;crl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NextUpdate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2006-01-02"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CRLExpiryPercentage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;crl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ThisUpdate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2006-01-02"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
      &lt;span class="n"&gt;expWhen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2006-01-02"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;/p&gt;
  The analyzer's hint
  &lt;br&gt;
V8033 Two similar code fragments were found. The second fragment may contain a typo: the "h.DeltaCRLExpiryPercentage" variable should be used instead of the "h.CRLExpiryPercentage". &lt;a href="https://github.com/hashicorp/vault/blob/2beda6097e3409b0ffc56c4bd23965daa661a112/command/healthcheck/pki_crl_validity_period.go#L195" rel="noopener noreferrer"&gt;pki_crl_validity_period.go 195&lt;/a&gt;



&lt;p&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Did you spot all the errors without looking at the hints? If so, that's great! If not, don't worry—that's where a static code analyzer comes into play!&lt;/p&gt;

&lt;p&gt;By the way, you can download it from our &lt;a href="https://pvs-studio.com/en/pvs-studio/try-free/?utm_source=website&amp;amp;utm_medium=devto&amp;amp;utm_campaign=article&amp;amp;utm_content=1419" rel="noopener noreferrer"&gt;official website&lt;/a&gt; and try it for free on your own projects. &lt;/p&gt;

&lt;p&gt;In addition to the Go analyzer, PVS-Studio 8.00 brought several other exciting features, including an analyzer for JavaScript and TypeScript. You can find more details about them in our &lt;a href="https://pvs-studio.com/en/blog/posts/1406/" rel="noopener noreferrer"&gt;article&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>go</category>
      <category>programming</category>
      <category>debugging</category>
    </item>
    <item>
      <title>How we made JavaScript analyzer understand control flow</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Fri, 09 Oct 2026 12:31:28 +0000</pubDate>
      <link>https://dev.to/pvsdev/how-we-made-javascript-analyzer-understand-control-flow-4ghl</link>
      <guid>https://dev.to/pvsdev/how-we-made-javascript-analyzer-understand-control-flow-4ghl</guid>
      <description>&lt;p&gt;We recently added JavaScript/TypeScript support to PVS-Studio analyzer. From its first release, the analyzer can detect control-flow bugs in code. In this article, we'll learn about the control flow graph (CFG), how we've implemented it, and why it's useful.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjcbezezdpcuyy82jk8cl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjcbezezdpcuyy82jk8cl.png" alt="1418_js_cfg/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Control Flow Graph?
&lt;/h2&gt;

&lt;p&gt;I've touched on this topic before, in my &lt;a href="https://pvs-studio.com/en/blog/posts/java/1198/" rel="noopener noreferrer"&gt;series&lt;/a&gt; on taint analysis in Java, but let's quickly recap it here. A static analyzer starts by converting source code into an abstract syntax tree (AST). It almost completely mirrors the structure of the code as you write it in the editor. That makes it a poor fit for anything involving control flow analysis, such as finding unreachable code. It's possible to write a check for unreachable code on the AST, but:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;this would be unreliable in corner cases;&lt;/li&gt;
&lt;li&gt;this wouldn't scale well to similar rules;&lt;/li&gt;
&lt;li&gt;this would be hard to maintain. Every bug fix or new language version would mean revisiting all of these diagnostic rules.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Control Flow Graph (CFG) exists to address these issues; it maps out all possible execution paths in a program.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3i2c6uwamxp5x60yj4u1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3i2c6uwamxp5x60yj4u1.png" alt="1418_js_cfg/image2.png" width="800" height="773"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The CFG consists of three components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;entry and exit nodes;&lt;/li&gt;
&lt;li&gt;Basic blocks nodes, each containing linear instructions;

&lt;ul&gt;
&lt;li&gt;Each basic block ends with a terminator (or with nothing). A terminator is a special instruction that determines specific semantics for the execution flow: branching, &lt;code&gt;break&lt;/code&gt;/&lt;code&gt;continue&lt;/code&gt;, and so on.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Edges between nodes that represent possible control flow transitions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1q0epm8x6l22n82uldds.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1q0epm8x6l22n82uldds.png" alt="1418_js_cfg/image3.png" width="800" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How did we do it?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Common CFG
&lt;/h3&gt;

&lt;p&gt;In our &lt;a href="https://pvs-studio.com/en/blog/posts/js/1363/" rel="noopener noreferrer"&gt;article&lt;/a&gt; on developing the JavaScript/TypeScript analyzer, we &lt;a href="https://pvs-studio.com/en/blog/posts/js/1363/#IDC01AE1A5F1" rel="noopener noreferrer"&gt;mentioned&lt;/a&gt; that the tool includes not only a syntax tree for each specific language, but also a common one for multilingual analysis. We named it CAT (Common Abstract Tree).&lt;/p&gt;

&lt;p&gt;No other languages have joined JavaScript/TypeScript yet, but we've already made the CFG extensible: the core engine doesn't depend on any specific language. We define a set of multiple semantics and just combine them like building blocks into a CFG for a specific language we need. It'll save time when it comes to supporting other languages in the future.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1nv51v8zxi50tn31i7m0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1nv51v8zxi50tn31i7m0.png" alt="1418_js_cfg/image4.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are two examples of language-specific semantics for JavaScript/TypeScript:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;try&lt;/code&gt; blocks in which exceptions are untyped, and only one &lt;code&gt;catch&lt;/code&gt; is allowed.&lt;/li&gt;
&lt;li&gt;Labels are attached to a specific statement, and you can jump to them only from the &lt;code&gt;break&lt;/code&gt; statement nested within that statement. You can also jump to the label using &lt;code&gt;continue&lt;/code&gt; if it is inside a loop.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing approach
&lt;/h3&gt;

&lt;p&gt;Checking that a CFG is correct is quite an adventure of its own. The first thing that comes to mind is to serialize the graph in &lt;a href="https://en.wikipedia.org/wiki/Graphviz" rel="noopener noreferrer"&gt;Graphviz&lt;/a&gt; (or some other way), check it visually, and save it as a reference. Spoiler: that was a trap, and we fell into it. Here's why it doesn't work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The graph changes constantly during development. You end up manually rewriting the failing tests or burning through AI agents' tokens.&lt;/li&gt;
&lt;li&gt;It's very easy to miss a bug in the reference. If people didn't make mistakes, the static analysis industry wouldn't exist.&lt;/li&gt;
&lt;li&gt;A neat-looking topology doesn't guarantee that the graph captures the full semantics of the control flow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So we changed the approach and wrote a mini-interpreter for our CAT, driven by the CFG. The idea is simple: if our interpreter, after traversing the graph, produces the same result as the JavaScript interpreter, the graph is constructed correctly. We verify this with a simple assertion API, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;branching&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;EvaluationAssert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"branching"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;withParam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"param"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;EvaluationAssert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"branching"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;withParam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"param"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This test runs the interpreter and compares the execution results with the reference, which you can get by running the TypeScript code beforehand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;branching&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We didn't have to implement the entire JavaScript specification—a tiny subset was enough. Cutting corners actually worked in our favor: if you don't clear variables when they go out of scope, you can inspect the state of the code at different points.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx5z9cohoov6ho8trmcct.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx5z9cohoov6ho8trmcct.png" alt="1418_js_cfg/image5.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Another nice bonus: the minimalist interpreter is a full-fledged proof of concept for graph processing. It can serve both as a reference for using the API and as groundwork for upcoming data-flow analysis.&lt;/p&gt;

&lt;p&gt;The result is a working graph builder for JavaScript/TypeScript that constructs each graph in a single AST traversal. It's quite fast: for &lt;a href="https://www.google.com/search?client=firefox-b-d&amp;amp;q=react&amp;amp;sei=_ymVao7PAuev5NoPzafroAY" rel="noopener noreferrer"&gt;React&lt;/a&gt;, all graphs are built in a quarter of a second.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it can catch today
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Linear code
&lt;/h3&gt;

&lt;p&gt;The most basic typos, the kind the AST could catch too, come first, of course:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;curveLengths&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;curveLengths&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;curve&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curves&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;curve&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLength&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;curve&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getPointAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7039/" rel="noopener noreferrer"&gt;V7039&lt;/a&gt; Unreachable code detected. Control flow never reaches this statement. &lt;a href="https://github.com/juice-shop/juice-shop/blob/1618a611b173b4bf114028e6e02549950606e29d/frontend/src/assets/private/three.js#L29417" rel="noopener noreferrer"&gt;three.js 29417&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That's the graph built by the analyzer:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvde0qpy2n2qllh8x1bt9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvde0qpy2n2qllh8x1bt9.png" alt="1418_js_cfg/image6.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
  What are merge nodes?
  &lt;br&gt;
A merge node is an auxiliary node used during graph construction. It makes the graph easier to work with, because nodes with multiple predecessors are cumbersome to handle. The analysis doesn't use merge nodes (yet). 

&lt;p&gt;In the example above, the merge has only one incoming edge instead of two, as in the previous scheme, because the &lt;code&gt;true&lt;/code&gt; branch contains a &lt;code&gt;return&lt;/code&gt;, which requires an edge to be created straight to the exit node. &lt;/p&gt;



&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The graph shows clearly no path lead to &lt;code&gt;break&lt;/code&gt;, so the analyzer marks it as unreachable. &lt;/p&gt;

&lt;p&gt;It's unlikely that this error has any effect, and the unreachable &lt;code&gt;break&lt;/code&gt; is probably just redundant. But here's the interesting part: this file is the &lt;a href="https://github.com/mrdoob/three.js/" rel="noopener noreferrer"&gt;Three.js&lt;/a&gt; library, copied into &lt;a href="https://github.com/juice-shop/juice-shop/" rel="noopener noreferrer"&gt;Juice Shop&lt;/a&gt;, and we couldn't find the same error in the current Three.js repository.&lt;/p&gt;

&lt;p&gt;By the way, here's a classic bug involving automatic semicolon insertion (ASI):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="c1"&gt;// asi happens here&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bar&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The analyzer catches it the same way. The inserted &lt;code&gt;;&lt;/code&gt; creates a terminator in the block containing the &lt;code&gt;return&lt;/code&gt; and moves &lt;code&gt;this.bar&lt;/code&gt; to the next block:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsbticptxa0qnl49ahtu5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsbticptxa0qnl49ahtu5.png" alt="1418_js_cfg/image7.png" width="798" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conditions
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/phaserjs/phaser" rel="noopener noreferrer"&gt;Phaser&lt;/a&gt; gives us a good example of "defensive programming":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;childA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parentContainer&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;childB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parentContainer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;displayList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;childB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;displayList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;childA&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;childA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parentContainer&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;childB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parentContainer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="c1"&gt;// more branches ending with return statements here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;listA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;childA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getIndexList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;listB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;childB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getIndexList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;listA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;listB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;indexA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;listA&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;indexB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;listB&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;indexA&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;indexB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;indexB&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;indexA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;listB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;listA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;//  Technically this shouldn't happen, but ...&lt;/span&gt;
&lt;span class="c1"&gt;// eslint-disable-next-line no-unreachable&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7039/" rel="noopener noreferrer"&gt;V7039&lt;/a&gt; Unreachable code detected. Control flow never reaches this statement. &lt;a href="https://github.com/phaserjs/phaser/blob/02d8931b626d9764c133cbb3fbf99966c03c757c/src/input/InputPlugin.js#L2981" rel="noopener noreferrer"&gt;InputPlugin.js 2981&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There were more &lt;code&gt;else-if&lt;/code&gt; branches, but I removed them to keep the example short and to the graph small:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F70khqudzojphu4lf16z3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F70khqudzojphu4lf16z3.png" alt="1418_js_cfg/image9.png" width="800" height="555"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you peruse the comment and look at the code, the programmers' concern starts making sense: the logic above is complex, merging more than 5 branches, each of which terminates the execution flow. Devs decided to play it safe, not even trusting ESLint. Following its trail, the analyzer saw from the graph's topology that there is simply no path to &lt;code&gt;return 0&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Loops
&lt;/h3&gt;

&lt;p&gt;As a bonus, we also get the ability to identify loops that run infinitely or, conversely, only once. I found such a case in the already mentioned Three.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="nl"&gt;loop:&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(;&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;                 &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;needleLength&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;haystack&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="n"&gt;needle&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt; &lt;span class="n"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v7039/" rel="noopener noreferrer"&gt;V7039&lt;/a&gt; Unreachable code detected. Control flow never reaches this statement. &lt;a href="https://github.com/mrdoob/three.js/blob/aa625d502d4920a84975c80a6438c108678fb4ac/examples/jsm/libs/opentype.module.js#L6109" rel="noopener noreferrer"&gt;opentype.module.js 6109&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is the control flow graph:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhezcj7ih79480niueo53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhezcj7ih79480niueo53.png" alt="1418_js_cfg/image10.png" width="800" height="725"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The diagnostic rule warns that the increment of the &lt;code&gt;pos&lt;/code&gt; variable in the loop is unreachable. Looking at the code, you can easily see that all the branches indeed terminate the second &lt;code&gt;for&lt;/code&gt; loop, so it runs only once. The graph confirms this—there is no path to the increment.&lt;/p&gt;

&lt;p&gt;This code originally came from &lt;a href="https://github.com/opentypejs/opentype.js" rel="noopener noreferrer"&gt;OpenType&lt;/a&gt;, but the copied dependency was removed at the time of the writing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exception handling
&lt;/h3&gt;

&lt;p&gt;Nested &lt;code&gt;try&lt;/code&gt; blocks and execution flow interruptions from &lt;code&gt;finally&lt;/code&gt; are rare andoften considered a code smell, so I couldn't find any instances in open-source code right away.&lt;/p&gt;

&lt;p&gt;Still, this was one of the trickiest cases to handle due to the complexity of the &lt;code&gt;try-catch-finally&lt;/code&gt; semantics. The analyzer has to handle several things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check if the &lt;code&gt;try&lt;/code&gt; block contains a &lt;code&gt;catch&lt;/code&gt;, a &lt;code&gt;finally&lt;/code&gt;, or both;&lt;/li&gt;
&lt;li&gt;Track explicit &lt;code&gt;throw&lt;/code&gt; statements and also handle where implicit exceptions lead.&lt;/li&gt;
&lt;li&gt;Override the control flow interruption within the &lt;code&gt;finally&lt;/code&gt; block when the control flow interruption occurs in &lt;code&gt;try&lt;/code&gt; or &lt;code&gt;catch&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Propagate the control flow interruption that occurs in &lt;code&gt;finally&lt;/code&gt; up through the &lt;code&gt;try&lt;/code&gt; block. &lt;/li&gt;
&lt;li&gt;Cover many other edge cases and their combinations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since I still want to show this case, here's a synthetic example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;tryCatchFinallyCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Whoops"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"inner"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;// V7039&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"outer"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// V7039&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this function, the analyzer will construct the following graph:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjh1f7p0gkjv1flxlzqso.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjh1f7p0gkjv1flxlzqso.png" alt="1418_js_cfg/image11.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The diagram clearly shows that the edges themselves carry information about which operation they "remembered" before exiting the function. The analyzer also identifies the unreachable &lt;code&gt;return&lt;/code&gt; nodes. &lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;We've walked through the errors that the analyzer can now detect thanks to control flow graph support. It has already proven its capabilities, making it fairly straightforward to implement diagnostic rules &lt;a href="https://pvs-studio.com/en/docs/warnings/v7039/" rel="noopener noreferrer"&gt;V7039&lt;/a&gt; (unreachable code) and &lt;a href="https://pvs-studio.com/en/docs/warnings/v7040/" rel="noopener noreferrer"&gt;V7040&lt;/a&gt; (infinite recursion) by the time PVS-Studio 8.00 was released. Beyond adding new diagnostic rules, other opportunities are opening up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extend the CFG construction by applying it to short-circuit expressions.&lt;/li&gt;
&lt;li&gt;Find dead code as well as unreachable code, using conditional constant propagation. Once we have laid the groundwork for the data-flow analysis engine, we can implement &lt;a href="https://pvs-studio.com/en/blog/terms/6496/" rel="noopener noreferrer"&gt;taint analysis&lt;/a&gt; (tracking tainted data throughout the program).&lt;/li&gt;
&lt;li&gt;Extend the same engine to other kinds of &lt;a href="https://pvs-studio.com/en/blog/terms/7004/" rel="noopener noreferrer"&gt;data-flow analysis&lt;/a&gt;, such as detecting null dereference, division by zero, and so on.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, CAT grows the analyzer wider, and the CFG lets us grow it deeper. The ground for developing the new analyzer is now even more productive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;That's the end of the brief overview of the analyzer's technology. I hope you enjoyed seeing how static analysis works and what kinds of errors control flow analysis can find. If you've worked with similar technologies, share your experience in the comments. I'd love to read your stories. The promised article on the inner workings of CAT is still on the way, along with more articles on code quality. Follow us to stay tuned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PVS-Studio in &lt;a href="https://x.com/pvs_studio" rel="noopener noreferrer"&gt;X&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/subscribe/" rel="noopener noreferrer"&gt;monthly newsletter&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;my personal &lt;a href="https://twitter.com/kvolokhovskii" rel="noopener noreferrer"&gt;blog&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>Go vet can't go: How to create your own Go analyzer?—Key points</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Thu, 08 Oct 2026 11:48:24 +0000</pubDate>
      <link>https://dev.to/pvsdev/go-vet-cant-go-how-to-create-your-own-go-analyzer-key-points-f3b</link>
      <guid>https://dev.to/pvsdev/go-vet-cant-go-how-to-create-your-own-go-analyzer-key-points-f3b</guid>
      <description>&lt;p&gt;In this live talk, PVS-Studio's Developer Advocate walks through Go's built-in tools and code-parsing capabilities, explains the basics of static analysis, unpacks what a semantic model is, shows how to build a syntax tree, and much more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why build a custom analyzer?
&lt;/h2&gt;

&lt;p&gt;Go already includes static analysis via go vet, but it can't detect every issue. Real-world projects contain errors that may look obvious to a developer yet remain invisible to standard tools. Other tools can also produce false positives or miss errors. A custom analyzer lets you focus on problems specific to your code and control exactly what the tool checks. The trade-off is that it needs to be maintained and tested. The diagnostic rules also need to be refined to minimize false positives and negatives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Syntax and semantics
&lt;/h2&gt;

&lt;p&gt;Static analysis relies on two main sources of information: syntax and semantics. The syntax tree shows the code structure and can reveal issues based on this structure. However, some cases require understanding what expressions and identifiers mean. Go/types provide this semantic information, including expression types and the declarations they refer to.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building an analyzer
&lt;/h2&gt;

&lt;p&gt;The Go analysis framework handles routine work such as collecting files, parsing them, and checking types. The analysis pass provides parsed files, type information, the current package, diagnostic rules, and source positions. A rule can then traverse the syntax tree, inspect relevant nodes, and report issues to the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  From rule to diagnostic
&lt;/h2&gt;

&lt;p&gt;The speaker demonstrates this process with a rule that detects empty &lt;code&gt;if&lt;/code&gt; statements and then applies the same approach to a more complex value-receiver case. The result is a custom diagnostic rule tailored to a specific problem that existing tools may miss.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want more?
&lt;/h2&gt;

&lt;p&gt;If you want to watch the full talk, follow this &lt;a href="https://pvs-studio.com/en/blog/video/11828/" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And if you'd like to learn more about PVS-Studio analyzer, check out our &lt;a href="https://pvs-studio.com/en/" rel="noopener noreferrer"&gt;website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;See ya!&lt;/p&gt;

</description>
      <category>go</category>
      <category>webinar</category>
      <category>programming</category>
    </item>
    <item>
      <title>I found some bugs in Create mod and checked them in Minecraft</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Tue, 29 Sep 2026 13:29:42 +0000</pubDate>
      <link>https://dev.to/pvsdev/i-found-some-bugs-in-create-mod-and-checked-them-in-minecraft-2cbk</link>
      <guid>https://dev.to/pvsdev/i-found-some-bugs-in-create-mod-and-checked-them-in-minecraft-2cbk</guid>
      <description>&lt;p&gt;This article covers bugs in Create, one of the most popular Minecraft mods. Let's see how they impact the game and then submit pull requests with the necessary fixes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvxhx3qbwtnjyfouq4sjh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvxhx3qbwtnjyfouq4sjh.png" alt="1417_Create/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://modrinth.com/mod/create" rel="noopener noreferrer"&gt;Create&lt;/a&gt; is a Minecraft mod that adds shafts, gears, and other mechanical components. You can combine them to build machines powered by rotational force, from a simple windmill to a fully automated &lt;a href="https://www.youtube.com/watch?v=rR8W-f9YhYA" rel="noopener noreferrer"&gt;cake factory&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The mod is hugely popular: it has more than 206 million &lt;a href="https://www.curseforge.com/minecraft/mc-mods/create" rel="noopener noreferrer"&gt;downloads on CurseForge&lt;/a&gt; alone. That doesn't even include &lt;a href="https://modrinth.com/mod/create" rel="noopener noreferrer"&gt;Modrinth&lt;/a&gt;, and the mod keeps getting updates for new versions of the game. I'm pretty sure almost everyone who opened the article has played this mod. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fepukcd2je4wlo2xmc2di.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fepukcd2je4wlo2xmc2di.png" alt="1417_Create/image2.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's check the project
&lt;/h2&gt;

&lt;p&gt;&lt;/p&gt;
  Some important info
  &lt;ul&gt;
&lt;li&gt;To check the project, I used PVS-Studio static analyzer. The article author is one of its developers.&lt;/li&gt;
&lt;li&gt;You'll see code examples as you read. Most of them have been shortened to avoid overwhelming the reader. I've also put an ellipsis to mark the shortened code: "....".&lt;/li&gt;
&lt;li&gt;At the time of the check, the latest revision was the &lt;a href="https://github.com/Creators-of-Create/Create/tree/87b3c6a65fd00c023a07b37b0353144bc7e6a5bf" rel="noopener noreferrer"&gt;87b3c6a&lt;/a&gt; commit. I checked it using the static analyzer.&lt;/li&gt;
&lt;li&gt;All analyzed source files and any conclusions based on other source files, include a permanent link that you can use to find them.&lt;/li&gt;
&lt;li&gt;The article includes only the bugs that the author found interesting (yes, it's a matter of personal taste). If you want to see the rest, you can always download the analyzer and check the project yourself.&lt;/li&gt;
&lt;/ul&gt;



&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Ctrl + V doesn't work
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/Creators-of-Create/Create/blob/0924e93639ad5f61cfc39a221d909e16f2893df1/src/main/java/com/simibubi/create/content/schematics/client/SchematicEditScreen.java#L130" rel="noopener noreferrer"&gt;SchematicEditScreen.java(130)&lt;/a&gt; file&lt;/p&gt;

&lt;p&gt;Let's take a look at the menu for pasting a schematic.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
  What's a schematic?
  &lt;br&gt;
A schematic is a part of the game world saved as a separate file. This lets you move your house from one world to another, for example.



&lt;br&gt;
&lt;p&gt;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;keyPressed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;....)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isPaste&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;coords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;minecraft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keyboardHandler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getClipboard&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coords&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replaceAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;             &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
      &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;split&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NumberFormatException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;xInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
          &lt;span class="n"&gt;yInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
          &lt;span class="n"&gt;zInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/docs/warnings/v6010/" rel="noopener noreferrer"&gt;V6010&lt;/a&gt; The return value of function 'replaceAll' is required to be utilized. SchematicEditScreen.java 130&lt;/p&gt;

&lt;p&gt;The idea is simple: the player copies the coordinates, presses Ctrl + V in a dedicated window, and the fields fill in automatically.&lt;/p&gt;

&lt;p&gt;But the &lt;code&gt;replaceAll&lt;/code&gt; call marked &lt;code&gt;// &amp;lt;=&lt;/code&gt; serves no purpose. Strings in Java are immutable, so the method doesn't modify the original string; it returns a new one instead. The new string is immediately discarded, leaving the spaces instead.&lt;/p&gt;

&lt;p&gt;The code then splits the string by commas, leaving a space at the beginning of the second and third elements, and &lt;code&gt;Integer.parseInt(" 67")&lt;/code&gt; throws a &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/lang/NumberFormatException.html" rel="noopener noreferrer"&gt;&lt;code&gt;NumberFormatException&lt;/code&gt;&lt;/a&gt;. As a result, the fields remain empty.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F86f9wkzjz8sb04jpuqh3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F86f9wkzjz8sb04jpuqh3.png" alt="1417_Create/image3.png" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After opening the menu, I saw the expected behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-156, 67, 204&lt;/code&gt; doesn't work;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-156,67,204&lt;/code&gt; works.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The fix fits on a single line. We just add an assignment before the &lt;code&gt;replaceAll&lt;/code&gt; operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;coords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;coords&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;replaceAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Unnecessary maximum
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/Creators-of-Create/Create/blob/0924e93639ad5f61cfc39a221d909e16f2893df1/src/main/java/com/simibubi/create/content/trains/schedule/ScheduleScreen.java#L557" rel="noopener noreferrer"&gt;ScheduleScreen.java(557)&lt;/a&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ScheduleWaitCondition&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conditions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;maxWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getConditionColumnWidth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ScheduleWaitCondition&lt;/span&gt; &lt;span class="n"&gt;scheduleWaitCondition&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxWidth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;renderInput&lt;/span&gt;&lt;span class="p"&gt;(....));&lt;/span&gt;   &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
    &lt;span class="n"&gt;scheduleWaitCondition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;renderSpecialIcon&lt;/span&gt;&lt;span class="p"&gt;(....);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;AllGuiTextures&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SCHEDULE_CONDITION_APPEND&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;graphics&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;xOffset&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;maxWidth&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;29&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;xOffset&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;maxWidth&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/docs/warnings/v6010/" rel="noopener noreferrer"&gt;V6010&lt;/a&gt; The return value of function 'max' is required to be utilized. ScheduleScreen.java 557&lt;/p&gt;

&lt;p&gt;The analyzer warning clearly explains the error: the result of the &lt;code&gt;Math.max(....)&lt;/code&gt; call isn't written anywhere. &lt;/p&gt;

&lt;p&gt;I looked through the commit history, expecting to find some traces of refactoring. I thought the developers might have moved the width calculation to a separate method and removed the assignment to &lt;code&gt;maxWidth&lt;/code&gt; but left the &lt;code&gt;Math#max&lt;/code&gt; call untouched. There was nothing like that, though. The file first appeared on February 1, 2022, in a &lt;a href="https://github.com/Creators-of-Create/Create/commit/576d00d3a0e502d418488ef463ad7eb4237560ab#diff-59b447844d14ec067c0449bccbecf6179277ee5603f60cc4cb682911967f0bc8" rel="noopener noreferrer"&gt;single 941-line commit&lt;/a&gt;, and the &lt;code&gt;Math#max&lt;/code&gt; call without an assignment had been there all along. The original initialization of &lt;code&gt;maxWidth&lt;/code&gt; with a call to &lt;code&gt;getConditionColumnWidth()&lt;/code&gt; was there too.&lt;/p&gt;

&lt;p&gt;What would change if the devs added &lt;code&gt;maxWidth = Math.max(....)&lt;/code&gt;? Nothing. The column width where the text appears (see the image below) is calculated in advance with some extra room: &lt;code&gt;getConditionColumnWidth()&lt;/code&gt; goes through the entire column and takes the maximum width, so no line can extend beyond it. I checked this using the debugger: in every case I was able to test, it returned the same width. So, the code is searching for the maximum of two identical numbers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2esdg9vuu69hek5cwfeg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2esdg9vuu69hek5cwfeg.png" alt="1417_Create/image4.png" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The line didn't break over time, nor was it affected by any refactoring. From day one, it had done nothing—for four years and through several updates to newer Minecraft versions.&lt;/p&gt;

&lt;p&gt;I'd suggest removing the unnecessary wrapper and leaving &lt;code&gt;renderInput&lt;/code&gt; on its own.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ignore error handling
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/Creators-of-Create/Create/blob/0924e93639ad5f61cfc39a221d909e16f2893df1/src/main/java/com/simibubi/create/content/kinetics/crafter/MechanicalCrafterBlockEntity.java#L535" rel="noopener noreferrer"&gt;MechanicalCrafterBlockEntity.java(535)&lt;/a&gt; file&lt;/p&gt;

&lt;p&gt;First of all, let me show you what the mechanical crafter looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx81148burhwvnszks1g9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx81148burhwvnszks1g9.png" alt="1417_Create/image5.png" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
  Image explanation
  &lt;br&gt;
In vanilla Minecraft, players craft items at a crafting table by manually placing ingredients in specific slots. A mechanical crafter does the same thing automatically. You build a grid from several blocks, with each block corresponding to one slot in the recipe, and place the required ingredient in each one. The screenshot shows the recipe for an iron pickaxe: three ingots in the top row and two sticks down the middle.

&lt;p&gt;The arrows on the front indicate the route. The crafters pass items from one to another along the chain until everything reaches the final block. That's where the recipe gets assembled, and the finished item moves on to a conveyor belt or into a chest.&lt;/p&gt;

&lt;p&gt;The whole system runs on rotational power, so it needs a drive connected to the side. In the screenshot, a creative motor powers the grid.&lt;/p&gt;



&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Let's take a look at a method in its logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;continueIfAllPrecedingFinished&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MechanicalCrafterBlockEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;preceding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="n"&gt;RecipeGridHandler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getPrecedingCrafters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;preceding&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
    &lt;span class="n"&gt;ejectWholeGrid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MechanicalCrafterBlockEntity&lt;/span&gt; &lt;span class="n"&gt;blockEntity&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;preceding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blockEntity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;phase&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;Phase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WAITING&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;phase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Phase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ASSEMBLING&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;countDown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/docs/warnings/v6007/" rel="noopener noreferrer"&gt;V6007&lt;/a&gt; Expression 'preceding == null' is always false. New returns not-null reference. MechanicalCrafterBlockEntity.java 535&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;getPrecedingCrafters&lt;/code&gt; method returns the crafters that come earlier in the chain. In other words, the ones that feed items into the current crafter. It can never return &lt;code&gt;null&lt;/code&gt;. A list is created at the start, and both method exits return it. Even if the block isn't a crafter, the method returns an empty list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MechanicalCrafterBlockEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getPrecedingCrafters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;MechanicalCrafterBlockEntity&lt;/span&gt; &lt;span class="n"&gt;crafter&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;BlockPos&lt;/span&gt; &lt;span class="n"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;crafter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getBlockPos&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;Level&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;crafter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLevel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MechanicalCrafterBlockEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;crafters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;BlockState&lt;/span&gt; &lt;span class="n"&gt;blockState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;crafter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getBlockState&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;isCrafter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blockState&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;crafters&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;crafters&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means the branch with &lt;code&gt;ejectWholeGrid()&lt;/code&gt; is unreachable.  The &lt;code&gt;preceding&lt;/code&gt; list can never be &lt;code&gt;null&lt;/code&gt;, but it can be empty, and often is. What if we replace the check with &lt;code&gt;isEmpty()&lt;/code&gt; and test it in the game? Let's see what happens.&lt;/p&gt;

&lt;p&gt;Before the fix:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe56epbgnosl4m2pzkzgp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe56epbgnosl4m2pzkzgp.gif" alt="1417_Create/image6.gif" width="480" height="253"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the fix with &lt;code&gt;isEmpty&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4e19b4kq954irv4kuk38.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4e19b4kq954irv4kuk38.gif" alt="1417_Create/image7.gif" width="600" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The video shows that, before the fix, items entering the loop were passed from one crafter to another indefinitely. That could potentially cause trouble and break someone's factory :)&lt;/p&gt;

&lt;p&gt;However, after the check was replaced with &lt;code&gt;isEmpty()&lt;/code&gt;, the loop didn't even have a chance to form. The method determined that there was nowhere else to expect items from, so it ejected them.&lt;/p&gt;

&lt;p&gt;However, as soon as I added two more crafters to the chain, the fix stopped working:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd2vs9nnzk5j087hjol2r.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd2vs9nnzk5j087hjol2r.gif" alt="1417_Create/image8.gif" width="200" height="107"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two options are possible here. Either the mechanical crafter needs to detect loops differently, then simply replacing the check with &lt;code&gt;isEmpty()&lt;/code&gt; isn't enough. Or this looping behavior isn't a bug at all. In that case, we can just remove the &lt;code&gt;null&lt;/code&gt; check.&lt;/p&gt;

&lt;h3&gt;
  
  
  The logging crash
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/Creators-of-Create/Create/blob/0924e93639ad5f61cfc39a221d909e16f2893df1/src/main/java/com/simibubi/create/content/trains/entity/TrainRelocationPacket.java#L52" rel="noopener noreferrer"&gt;TrainRelocationPacket.java(52)&lt;/a&gt; file&lt;/p&gt;

&lt;p&gt;Here's the client-server train movement package handler:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ServerPlayer&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Train&lt;/span&gt; &lt;span class="n"&gt;train&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RAILWAYS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trains&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trainId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Entity&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;getEntity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entityId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;messagePrefix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" could not relocate Train "&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;train&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
    &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="n"&gt;instanceof&lt;/span&gt; &lt;span class="n"&gt;CarriageContraptionEntity&lt;/span&gt; &lt;span class="n"&gt;cce&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LOGGER&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messagePrefix&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;train&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;": not present on server"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;train&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cce&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;trainId&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/docs/warnings/v6008/" rel="noopener noreferrer"&gt;V6008&lt;/a&gt; Potential null dereference of 'train'. TrainRelocationPacket.java 52&lt;/p&gt;

&lt;p&gt;The condition triggers in two cases: either the train can't be found, or the entity is of the wrong class. The second case is fine: it logs a proper warning. However, in the first case, the code accesses &lt;code&gt;train.id&lt;/code&gt; when &lt;code&gt;train&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The funny part is that the message we're trying to log ends with &lt;code&gt;not present on server&lt;/code&gt;. The branch was created for a missing train, but it fails because of it.&lt;/p&gt;

&lt;p&gt;The packet comes from the client, meaning it chooses the train ID. A modified client build can send requests to transfer nonexistent trains and make the server fill its log with stack traces.&lt;/p&gt;

&lt;p&gt;The server won't crash: Create registers its packets so they execute safely, and even if an exception occurs, it gets logged, while the packet simply goes unhandled.&lt;/p&gt;

&lt;p&gt;We can fix this by including the identifier in the package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;messagePrefix&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;trainId&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;substring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The two-state theory
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/Creators-of-Create/Create/blob/0924e93639ad5f61cfc39a221d909e16f2893df1/src/main/java/com/simibubi/create/content/kinetics/mixer/MechanicalMixerBlockEntity.java#L238" rel="noopener noreferrer"&gt;MechanicalMixerBlockEntity.java(238)&lt;/a&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Recipe&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getMatchingRecipes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Recipe&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;matchingRecipes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getMatchingRecipes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;AllConfigs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;recipes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;allowBrewingInMixer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;matchingRecipes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BasinBlockEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;basin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getBasin&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;basin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isPresent&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;matchingRecipes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;BasinBlockEntity&lt;/span&gt; &lt;span class="n"&gt;basinBlockEntity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;basin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basin&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;isEmpty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;= &lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;matchingRecipes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;IItemHandler&lt;/span&gt; &lt;span class="n"&gt;availableItems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getCapability&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;Capabilities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ItemHandler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BLOCK&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="n"&gt;basinBlockEntity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getBlockPos&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;availableItems&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;matchingRecipes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;availableItems&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getSlots&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;matchingRecipes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/docs/warnings/v6007/" rel="noopener noreferrer"&gt;V6007&lt;/a&gt; Expression 'basin.isEmpty()' is always true. MechanicalMixerBlockEntity.java 238&lt;/p&gt;

&lt;p&gt;Here, &lt;code&gt;basin.isEmpty()&lt;/code&gt; can never return &lt;code&gt;true&lt;/code&gt;, so &lt;code&gt;return&lt;/code&gt; in this branch is unreachable. Most likely, the developers meant to check &lt;code&gt;basinBlockEntity&lt;/code&gt; rather than &lt;code&gt;Optional&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This doesn't affect gameplay in any way. Further down, the code has other checks that work with the same block, and if the basin is empty, either the loop doesn't run or &lt;code&gt;availableItems&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But a dead &lt;code&gt;if&lt;/code&gt; is more dangerous than it looks. It's a safeguard that doesn't really protect against anything. Rewriting the checks below leaves a hole that no one will think to look for because the check is kind of there.&lt;/p&gt;

&lt;h3&gt;
  
  
  Method contracts must be followed
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/Creators-of-Create/Create/blob/0924e93639ad5f61cfc39a221d909e16f2893df1/src/main/java/com/simibubi/create/content/contraptions/Contraption.java#L230" rel="noopener noreferrer"&gt;Contraption.java(230)&lt;/a&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Contraption&lt;/span&gt; &lt;span class="nf"&gt;fromNBT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Level&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CompoundTag&lt;/span&gt; &lt;span class="n"&gt;nbt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                  &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;spawnData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nbt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;Contraption&lt;/span&gt; &lt;span class="n"&gt;contraption&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ContraptionType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;contraption&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;readNBT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;world&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nbt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;spawnData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can you see the error? What if we take a look inside &lt;code&gt;ContraptionType#fromType&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Lookup the ContraptionType with the given ID, 
 * and create a new Contraption from it if present.
 * If it doesn't exist, returns null.
 */&lt;/span&gt;
&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;Nullable&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Contraption&lt;/span&gt; &lt;span class="nf"&gt;fromType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;typeId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;ContraptionType&lt;/span&gt; &lt;span class="n"&gt;legacy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AllContraptionTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BY_LEGACY_NAME&lt;/span&gt;
                        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;typeId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;legacy&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;legacy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;ResourceLocation&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ResourceLocation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tryParse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;typeId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;ContraptionType&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CreateBuiltInRegistries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CONTRAPTION_TYPE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it's clear. The method explicitly warns about &lt;code&gt;null&lt;/code&gt; twice: with an annotation and a comment. However, the caller code doesn't check anything.&lt;/p&gt;

&lt;p&gt;The PVS-Studio warning:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/docs/warnings/v6008/" rel="noopener noreferrer"&gt;V6008&lt;/a&gt; Potential null dereference of 'contraption'. Contraption.java 230&lt;/p&gt;

&lt;p&gt;It's easier to break than it seems. The very first line calls &lt;code&gt;nbt.getString("Type")&lt;/code&gt;, and if the key doesn't exist, an empty string is returned. This type isn't in the registry either, so the code returns &lt;code&gt;null&lt;/code&gt; again.&lt;/p&gt;

&lt;p&gt;We can verify this pretty easily by giving ourselves a minecart with a nonexistent contraption type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;give&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;
&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;minecart_contraption&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;minecart_contraption_data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"create:does_not_exist"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;InitialOrientation&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s"&gt;"north"&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;/p&gt;
  What's a contraption?
  &lt;br&gt;
A contraption is a structure that the mod detaches from the world and turns into a single movable object: a platform on a minecart, a piston carrying a load, or a rotating bridge. The blocks inside stop being part of the world and are stored as data belonging to a single entity instead.



&lt;p&gt;&lt;/p&gt;

&lt;p&gt;The command won't break anything, and the item will go into the inventory without a problem. But once we put the minecart on the rails, &lt;code&gt;MinecartContraptionItem&lt;/code&gt; will try to build a contraption from this data, and that's where we'll get a &lt;a href="https://gist.github.com/TheLivan/ad251e6a4357230f1181eb59ae06d7c3" rel="noopener noreferrer"&gt;stack trace with &lt;code&gt;NullPointerException&lt;/code&gt;&lt;/a&gt;. Minecraft will replace the player's contraption with a vanilla minecart.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw4le7qtjt9u72iu5l8zi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw4le7qtjt9u72iu5l8zi.png" alt="1417_Create/image9.png" width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can easily add the check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;Contraption&lt;/span&gt; &lt;span class="n"&gt;contraption&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ContraptionType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contraption&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LOGGER&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unknown contraption type: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But then &lt;code&gt;null&lt;/code&gt; will need to be handled in both code snippets that call it. That raises the question of what to do with a minecart whose contents the mod can no longer understand. Should we leave it as an empty minecart, or simply not load the entity at all? I think it's worth asking the mod developers. They clearly know better than anyone else what to do here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interruption
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://github.com/Creators-of-Create/Create/blob/0924e93639ad5f61cfc39a221d909e16f2893df1/src/main/java/com/simibubi/create/infrastructure/command/ServerLagger.java#L14" rel="noopener noreferrer"&gt;ServerLagger.java(14)&lt;/a&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;tick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;isLagging&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;tickTime&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tickTime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InterruptedException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;printStackTrace&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/docs/warnings/v6103/" rel="noopener noreferrer"&gt;V6103&lt;/a&gt; Ignored InterruptedException could lead to delayed thread shutdown. ServerLagger.java 14&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ServerLagger&lt;/code&gt; is a helper class for the &lt;code&gt;killtps start &amp;lt;tickTime&amp;gt;&lt;/code&gt; debug command that puts the server to sleep for the specified number of milliseconds on every tick, allowing to see how the mod behaves when the TPS drops. It's available only in debug builds and only to operators (that's what server administrators are called), so there's no need to worry. However, the code is still incorrect, and it's worth explaining why.&lt;/p&gt;

&lt;p&gt;When the thread is interrupted, &lt;code&gt;sleep&lt;/code&gt; immediately throws an &lt;code&gt;InterruptedException&lt;/code&gt; and also clears the interrupt flag. In other words, after &lt;code&gt;catch&lt;/code&gt;, it seems like nothing's left: no flag, no exception, just a line in &lt;code&gt;System.err&lt;/code&gt;. The method returns control without issue, and the server continues running as if it had never been called.&lt;/p&gt;

&lt;p&gt;An &lt;a href="https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html" rel="noopener noreferrer"&gt;interrupt&lt;/a&gt; is a request for the entire thread to stop, not just the part where you catch it. By interrupting the thread and doing nothing, you take that request and throw it away. The &lt;a href="https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/lang/InterruptedException.html" rel="noopener noreferrer"&gt;Javadoc&lt;/a&gt; explicitly points this out. One line is enough to pass the interrupt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;InterruptedException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;currentThread&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;interrupt&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That's all for today. I collected all the bugs both in this article and in pull requests for the project's developers (&lt;a href="https://github.com/Creators-of-Create/Create/pull/10696" rel="noopener noreferrer"&gt;click&lt;/a&gt;, &lt;a href="https://github.com/Creators-of-Create/Create/pull/10721" rel="noopener noreferrer"&gt;click&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;Want to try static analysis too? You can always integrate it into your own project with PVS-Studio. You can download a trial version &lt;a href="https://pvs-studio.com/en/pvs-studio/try-free/?utm_source=website&amp;amp;utm_medium=devto&amp;amp;utm_campaign=article&amp;amp;utm_content=1417" rel="noopener noreferrer"&gt;here&lt;/a&gt;. The license is &lt;a href="https://pvs-studio.com/en/order/open-source-license/" rel="noopener noreferrer"&gt;free for open-source projects&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>java</category>
      <category>gamedev</category>
      <category>minecraft</category>
      <category>programming</category>
    </item>
    <item>
      <title>Let's make a programming language. Functions—Key points</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Wed, 23 Sep 2026 12:35:34 +0000</pubDate>
      <link>https://dev.to/pvsdev/lets-make-a-programming-language-functions-key-points-19p6</link>
      <guid>https://dev.to/pvsdev/lets-make-a-programming-language-functions-key-points-19p6</guid>
      <description>&lt;p&gt;We continue the development of our toy programming language. In this episode, our speaker Yuri demonstrates how to implement functions and explains how functions, scopes, and symbol lookup are built in code using C++. &lt;/p&gt;

&lt;h2&gt;
  
  
  About the speaker
&lt;/h2&gt;

&lt;p&gt;Yuri Minaev is an experienced C++ developer, architect at PVS-Studio, and a recognized voice in the C++ community who has spoken at CppCast, C++ on Sea, and CppCon. Over the course of ten sessions, he'll guide you through each stage of building your own programming language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing scopes
&lt;/h2&gt;

&lt;p&gt;Functions introduce multiple scopes and different levels of name visibility. Unlike variables, which previously existed only in the global scope, functions create their own scope. Names declared inside a function are not visible outside it, while names from parent scopes remain accessible. Compound statements can also create nested scopes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing the symbol table
&lt;/h2&gt;

&lt;p&gt;To resolve names, the semantic analyzer uses a symbol table that associates names with their declarators and the scopes where they appear. Two lookup methods are used. An unscoped lookup searches the current scope and then moves upward through parent scopes until it finds the name. A scoped lookup checks only a specified scope. The latter also prevents duplicate names from being declared within the same scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parsing functions
&lt;/h2&gt;

&lt;p&gt;A function consists of the &lt;code&gt;fn&lt;/code&gt; keyword, a name, parameters, an optional return type, and a compound statement containing its body. Parameters have a type and a unique name. Functions are parsed in two stages: the declaration is parsed and registered in the symbol table before the body is processed. This allows the function to reference itself recursively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling return types
&lt;/h2&gt;

&lt;p&gt;The semantic analyzer determines a function's return type from its return statements when no type is specified. It also checks that return expressions are compatible with the function's return type and adds implicit casts when necessary. An empty function with no return statements gets the &lt;code&gt;void&lt;/code&gt; type. Incompatible return types make the function invalid.&lt;/p&gt;

&lt;p&gt;The talk concludes with functions implemented and introduces the evaluator as the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Want more?
&lt;/h2&gt;

&lt;p&gt;If you want to watch other talks, follow this &lt;a href="https://www.youtube.com/playlist?app=desktop&amp;amp;list=PLGVoaOmC1PBw&amp;amp;si=WyndGLWrXYvY75YG" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also sign up for our upcoming webinars: &lt;a href="https://pvs-studio.com/en/webinar/34/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=web8" rel="noopener noreferrer"&gt;Let's make a programming language. Evaluator&lt;/a&gt;. We hope to see you there!&lt;/p&gt;

&lt;p&gt;If you'd like to learn more about PVS-Studio analyzer, check out our &lt;a href="https://pvs-studio.com/en/" rel="noopener noreferrer"&gt;website&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;See ya!&lt;/p&gt;

</description>
      <category>cpp</category>
      <category>programming</category>
      <category>webinar</category>
    </item>
    <item>
      <title>Live talk on how to create your own Go analyzer</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Fri, 18 Sep 2026 12:48:45 +0000</pubDate>
      <link>https://dev.to/pvsdev/live-talk-on-how-to-create-your-own-go-analyzer-4b1n</link>
      <guid>https://dev.to/pvsdev/live-talk-on-how-to-create-your-own-go-analyzer-4b1n</guid>
      <description>&lt;p&gt;Static analyzers are powerful tools, and any Go developer who has worked with go vet knows how useful they can be. What happens when the tools you have at your disposal don't catch the most important issues in your projects, though? You could look for another solution... or you could build your own!&lt;/p&gt;

&lt;p&gt;In our upcoming live talk, we'll explore how Go's built-in tools and code-parsing capabilities can help you take the first steps toward creating a static analyzer tailored to your needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Go's built-in tools to your own analyzer
&lt;/h2&gt;

&lt;p&gt;A PVS-Studio Developer Advocate will walk you through the foundations needed to understand before building a Go analyzer. We'll start with Go's built-in tools and code-parsing capabilities, then move on to the basics of static analysis. From there, we'll look at what a semantic model is and how it fits into the analysis process. Another important part of the talk will be building a syntax tree. &lt;/p&gt;

&lt;p&gt;The goal of this talk is to bring all the pieces together and show how they can be used to create your own static analyzer. Instead of relying solely on existing tools, you can tailor an analyzer to catch the issues that matter most in your projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Join us live
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/webinar/35/?utm_source=devto&amp;amp;utm_medium=pvs&amp;amp;utm_campaign=webinar&amp;amp;utm_content=go_mistakes2" rel="noopener noreferrer"&gt;Join us&lt;/a&gt; on &lt;strong&gt;September 30, 2026, at 1:00 PM UTC+1&lt;/strong&gt; for &lt;em&gt;"Go vet can't go: How to create your own Go analyzer?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Register for the live talk and start exploring how to create a Go analyzer tailored to your projects!&lt;/p&gt;

</description>
      <category>go</category>
      <category>webinar</category>
      <category>software</category>
      <category>programming</category>
    </item>
    <item>
      <title>PVS-Studio for Go: Quick overview of new diagnostic rules</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Thu, 17 Sep 2026 11:41:35 +0000</pubDate>
      <link>https://dev.to/pvsdev/pvs-studio-for-go-quick-overview-of-new-diagnostic-rules-eej</link>
      <guid>https://dev.to/pvsdev/pvs-studio-for-go-quick-overview-of-new-diagnostic-rules-eej</guid>
      <description>&lt;p&gt;PVS-Studio 8.0 is here! We added support for Go project analysis and much more. This article discusses some of the new diagnostic rules for Go that we developed for the latest version of our analyzer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4zpi83oul8q6yca1z0ij.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4zpi83oul8q6yca1z0ij.png" alt="1413_New_For_Go/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;PVS-Studio 8.0 officially introduced support for analyzing Go projects, as well as the option to work directly from &lt;a href="https://pvs-studio.com/en/docs/manual/7190/" rel="noopener noreferrer"&gt;GoLand&lt;/a&gt; and &lt;a href="https://pvs-studio.com/en/docs/manual/6646/" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt; when using Go. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Visual Studio Code plugin also received a major overhaul. It now supports Go project analysis and all the new analyzers introduced in PVS-Studio 8.0. You can learn about other new features in the &lt;a href="https://pvs-studio.com/en/blog/posts/1406/" rel="noopener noreferrer"&gt;press release&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The new release also added 40 new diagnostic rules for Go to the analyzer. In this article, we'll take a look at some of the most interesting ones, explore different use cases, and compare them with traditional tools. Enjoy the read!&lt;/p&gt;

&lt;h2&gt;
  
  
  Classic errors
&lt;/h2&gt;

&lt;p&gt;We'll start with something that isn't specific to the Go language. Instead, let's focus on more universal and familiar territory: the mistakes that anyone can make when coding or communicating, regardless of the language used.&lt;/p&gt;

&lt;p&gt;I should mention that our approach to the "typical developer mistakes" is somewhat different. In addition to studying Go projects, developer forums, and other resources, we used our "secret weapon" to develop diagnostic rules that detect common issues. &lt;/p&gt;

&lt;p&gt;That's 18 years of experience searching for issues in code :)&lt;/p&gt;

&lt;p&gt;Thanks to this experience in developing analyzers for C, C++, C#, and Java, we've built solid expertise in detecting common mistakes that developers can make regardless of the language they use. This enables us to consider more error cases and scenarios when designing a new analyzer. &lt;/p&gt;

&lt;p&gt;Mistakes like typos, copy-paste errors, and other patterns inherent to human behavior may seem simple...&lt;/p&gt;

&lt;p&gt;Let's look at a few examples.&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessing by constant index within a loop
&lt;/h3&gt;

&lt;p&gt;The example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     &lt;span class="c1"&gt;// &amp;lt;= It should most likely be arr[i]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v8008/" rel="noopener noreferrer"&gt;V8008&lt;/a&gt;. Suspicious access to a collection element by a constant index inside a loop.&lt;/p&gt;

&lt;p&gt;This diagnostic rule is interesting because the issue isn't a syntax error, but rather a logical one—a mistake that developers of any skill level can make. &lt;/p&gt;

&lt;p&gt;The index is syntactically valid, so the compiler doesn't report the error, but it remains. Situations like "Oops, I forgot to change &lt;code&gt;i&lt;/code&gt; to &lt;code&gt;j&lt;/code&gt;" or "I forgot that &lt;code&gt;i&lt;/code&gt; even existed" are far more common than you might think. At this point, it becomes a pattern rather than an isolated issue.&lt;/p&gt;

&lt;p&gt;We cover this because we know firsthand that developers make such mistakes! Each of our "classic" analyzers has equivalent rules (&lt;a href="https://pvs-studio.com/en/docs/warnings/v3102/" rel="noopener noreferrer"&gt;V3102&lt;/a&gt; is for C#, &lt;a href="https://pvs-studio.com/en/docs/warnings/v767/" rel="noopener noreferrer"&gt;V767&lt;/a&gt; is for C++, and &lt;a href="https://pvs-studio.com/en/docs/warnings/v6016/" rel="noopener noreferrer"&gt;V6016&lt;/a&gt; is for Java) and includes examples of such mistakes found in popular open-source projects. So, these issues shouldn't be underestimated. You can find examples of errors here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/examples/v3102/" rel="noopener noreferrer"&gt;C# examples&lt;/a&gt; (.NET 8, Orleans, PascalABC.NET, etc.);&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/examples/v767/" rel="noopener noreferrer"&gt;C++ examples&lt;/a&gt; (Godot Engine, RT-Thread, etc.);&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pvs-studio.com/en/blog/examples/v6016/" rel="noopener noreferrer"&gt;Java examples&lt;/a&gt; (Apache Solr, Bouncy Castle, Apache Dubbo, etc.).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recurring condition check
&lt;/h3&gt;

&lt;p&gt;The example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;A&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;B&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v8020/" rel="noopener noreferrer"&gt;V8020&lt;/a&gt;. Recurring check. This condition was already verified on a previous line.&lt;/p&gt;

&lt;p&gt;As you can see, I wasn't lying when I said these mistakes look simple... almost too simple.&lt;/p&gt;

&lt;p&gt;And that's the scary part! You get this strong feeling, "I'd never, ever make a mistake like that. I'm not that silly." Then a fly buzzes by, a bug slips through, a colleague walks over, and suddenly there's a couple of checks doing the same thing.&lt;/p&gt;

&lt;p&gt;Here's a real-world example from the &lt;a href="https://github.com/lxc/incus" rel="noopener noreferrer"&gt;Incus&lt;/a&gt; project, which we covered in one of our &lt;a href="https://pvs-studio.com/en/blog/posts/go/1371/" rel="noopener noreferrer"&gt;articles&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pidPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;err2&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;        &lt;span class="c1"&gt;// &amp;lt;= It looks like it should be err2&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"...: %s: %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v8020/" rel="noopener noreferrer"&gt;V8020&lt;/a&gt; Recurring check. The 'err != nil' condition was already verified on line 407 &lt;a href="https://github.com/lxc/incus/blob/321c40f963e9c1e7b68736fb4941431cccac3d60/internal/server/device/proxy.go#L407" rel="noopener noreferrer"&gt;proxy.go 407&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second condition should check &lt;code&gt;err2&lt;/code&gt; instead of &lt;code&gt;err&lt;/code&gt;, as &lt;code&gt;err&lt;/code&gt; has already been checked and hasn't changed since.&lt;/p&gt;

&lt;p&gt;However, there's more to it because &lt;code&gt;err2&lt;/code&gt; appears in the error handling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"....: %s: %s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first, you might not see anything unusual about this context. Although, the answer is obvious: if a problem occurs while handling errors, it becomes more difficult to detect and fix them.&lt;/p&gt;

&lt;p&gt;Here's one more point worth mentioning. Go's error-handling philosophy follows a simple principle: "an error is a value." The caller must explicitly handle an ordinary value that a function explicitly returns. Such code is common and &lt;a href="https://en.wikipedia.org/wiki/Boilerplate_code" rel="noopener noreferrer"&gt;boilerplate&lt;/a&gt;, so it's easy to make mistakes with it! &lt;/p&gt;

&lt;p&gt;We designed one of our new diagnostic rules with this particular aspect of Go in mind:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/docs/warnings/v8023/" rel="noopener noreferrer"&gt;V8023&lt;/a&gt;. It is possible that a wrong variable of the 'error' type is checked for 'nil'.&lt;/p&gt;

&lt;p&gt;The example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="n"&gt;processOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orderID&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;fetchOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orderID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"fetch order: %w"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;errPay&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;chargePayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;          
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"charge payment: %w"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;savePayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's return to the topic of common developer mistakes and discuss copy-pasting. You can notice that &lt;code&gt;err&lt;/code&gt; is used instead of &lt;code&gt;errPay&lt;/code&gt; in the second case. The result of &lt;code&gt;chargePayment&lt;/code&gt; is assigned to a different variable, but developers forgot to change the variable name.&lt;/p&gt;

&lt;p&gt;It's easy to spot most of the errors in the context of this article. However, during a code review or while writing code, when we're not looking at a single function but rather going through hundreds or thousands of code lines without a break, it's easy to miss such issues.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We discussed this and other issues related to error handling in Go in the "&lt;a href="https://pvs-studio.com/en/blog/posts/go/1371/" rel="noopener noreferrer"&gt;Error handling in Go: Common pitfalls&lt;/a&gt;" article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The parameter is overwritten before it is used
&lt;/h3&gt;

&lt;p&gt;The example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;Translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;numericValue&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;numericValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadInt32&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;   &lt;span class="c1"&gt;// &amp;lt;= the initial parameter value &lt;/span&gt;
                                        &lt;span class="c1"&gt;//    isn't used anywhere&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v8038/" rel="noopener noreferrer"&gt;V8038&lt;/a&gt;. A parameter is always rewritten in the function body before being used.&lt;/p&gt;

&lt;p&gt;This is a rather unfortunate error because the value passed to the function parameter is never read; it's immediately overwritten inside the function body. &lt;/p&gt;

&lt;p&gt;Technically, this isn't a compilation error, so everything should work as expected. However, it usually indicates one of two things: either the input value wasn't used, or the variables got mixed up during refactoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic tools aren't always enough
&lt;/h2&gt;

&lt;p&gt;Having a nice set of tools right out of the box—and, of course, various open-source solutions—is always great, but they might not be enough for more demanding tasks.&lt;/p&gt;

&lt;p&gt;Let's take the very first diagnostic rule of our Go analyzer as an example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pvs-studio.com/en/docs/warnings/v8001/" rel="noopener noreferrer"&gt;V8001&lt;/a&gt;. Identical sub-expressions to the left and to the right of the 'foo' operator.&lt;/p&gt;

&lt;p&gt;Look at the example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;rgb1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="n"&gt;float32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;float32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;float32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The error lies in the identical sub-expressions within the binary expression. This issue may arise from carelessly copying code. Such errors are common and nothing out of the ordinary; so, go vet can spot them.&lt;/p&gt;

&lt;p&gt;However, things aren't always that simple... Let's take a look at this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="n"&gt;float32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="n"&gt;float32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;float32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only change is that &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;r&lt;/code&gt; have switched places. Here's the catch, though: go vet doesn't issue any warnings, but the problem remains, since the &lt;code&gt;r &amp;gt; 1&lt;/code&gt; sub-expression is equivalent to &lt;code&gt;1 &amp;lt; r&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Impossible type assertion
&lt;/h3&gt;

&lt;p&gt;Here's another case involving the &lt;a href="https://pvs-studio.com/en/docs/warnings/v8035/" rel="noopener noreferrer"&gt;V8035&lt;/a&gt; diagnostic rule: an impossible type assertion.&lt;/p&gt;

&lt;p&gt;Check out this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;Read2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;Read3&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;Read4&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;Read5&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idea is simple: &lt;code&gt;v&lt;/code&gt; is declared as an anonymous interface with the &lt;code&gt;Read()&lt;/code&gt; method, whose signature doesn't match &lt;code&gt;Read([]byte) (int, error)&lt;/code&gt; from &lt;code&gt;io.Reader/io.ReadCloser&lt;/code&gt; (in the example, &lt;code&gt;Read()&lt;/code&gt; has no arguments). &lt;/p&gt;

&lt;p&gt;So, no specific type can implement both the &lt;code&gt;v&lt;/code&gt; anonymous interface and &lt;code&gt;io.Reader/io.ReadCloser&lt;/code&gt; simultaneously. So, this implementation guarantees that &lt;code&gt;assertion&lt;/code&gt; will throw a panic at runtime. The compiler doesn't catch this because it's technically valid Go code, and everything runs smoothly.&lt;/p&gt;

&lt;p&gt;Now wait for it... Go vet can detect it! This is a well-known and well-documented issue, so it should come as no surprise.&lt;/p&gt;

&lt;p&gt;By the way, PVS-Studio issues the following message for such code:&lt;/p&gt;

&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v8035/" rel="noopener noreferrer"&gt;V8035&lt;/a&gt;. Type assertion is always false. Check the 'interface{Read(); Read2(); Read3(); Read4(); Read5()}' and 'io.Reader' interfaces, as they contain methods with incompatible signatures.&lt;/p&gt;

&lt;p&gt;Here's another example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="n"&gt;interface&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReadCloser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nl"&gt;default:&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v8035/" rel="noopener noreferrer"&gt;V8035&lt;/a&gt;. Type assertion is always false. Check the 'interface{Read()}' and 'io.ReadCloser' interfaces, as they contain methods with incompatible signatures.&lt;/p&gt;

&lt;p&gt;In fact, it's exactly the same impossible &lt;code&gt;assertion&lt;/code&gt;. The only difference is that the assignment is now done using &lt;code&gt;case&lt;/code&gt; in the &lt;code&gt;switch&lt;/code&gt; statement and via &lt;code&gt;v.(type)&lt;/code&gt;, rather than via &lt;code&gt;v.(io.ReadCloser)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is where I'm supposed to say that go vet can't detect it... but no! It can, but that's not the point here. A popular open-source analyzer won't detect the issue here, but it will spot it in the first case. This is a &lt;a href="https://pvs-studio.com/en/blog/terms/6460/" rel="noopener noreferrer"&gt;false negative&lt;/a&gt; that occurs when a warning isn't issued when it should be.&lt;/p&gt;

&lt;p&gt;This presents a dilemma: you can either look for a tool that covers all use cases and spend time trying out different options, or you can take a closer look at PVS-Studio. It's designed for in-depth analysis and comes with guaranteed support for many years to come. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you have any doubts about our claims, feel free to &lt;a href="https://pvs-studio.com/en/pvs-studio/try-free/?utm_source=website&amp;amp;utm_medium=devto&amp;amp;utm_campaign=article&amp;amp;utm_content=1413" rel="noopener noreferrer"&gt;try our tool&lt;/a&gt; and draw your own conclusions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well, enough with the synthetic code. Will we show some real code, though?&lt;/p&gt;

&lt;h3&gt;
  
  
  Some real code
&lt;/h3&gt;

&lt;p&gt;Do you remember the very first Go analyzer diagnostic rule I covered at the beginning of this section? Here's a real example of the warning from the &lt;a href="https://github.com/projectdiscovery/nuclei" rel="noopener noreferrer"&gt;Nuclei&lt;/a&gt; project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;NewEntityParser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dir&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;EntityParser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="n"&gt;cfg&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;Mode:&lt;/span&gt; &lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NeedName&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NeedFiles&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NeedImports&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NeedTypes&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NeedSyntax&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NeedTypes&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NeedModule&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NeedTypesInfo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;Tests:&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;Dir:&lt;/span&gt;   &lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;ParseFile:&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(....)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParseFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ParseComments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v8001/" rel="noopener noreferrer"&gt;V8001&lt;/a&gt; There are identical sub-expressions 'packages.NeedTypes' to the left and to the right of the '|' operator. &lt;a href="https://github.com/projectdiscovery/nuclei/blob/ee8287a7b756d07e09e22b8945cddeb58e727a22/pkg/js/devtools/tsgen/parser.go#L33" rel="noopener noreferrer"&gt;parser.go 33&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we take a closer look, we can see that the &lt;code&gt;packages.NeedTypes&lt;/code&gt; flag is pointlessly repeated here. This error may have occurred due to code autocompletion or a typo. Most likely, there should be the &lt;code&gt;packages.NeedTypesSizes&lt;/code&gt; flag here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="c1"&gt;// NeedTypes adds Types, Fset, and IllTyped.&lt;/span&gt;
  &lt;span class="n"&gt;NeedTypes&lt;/span&gt;

  &lt;span class="c1"&gt;// NeedSyntax adds Syntax and Fset.&lt;/span&gt;
  &lt;span class="n"&gt;NeedSyntax&lt;/span&gt;

  &lt;span class="c1"&gt;// NeedTypesInfo adds TypesInfo and Fset.&lt;/span&gt;
  &lt;span class="n"&gt;NeedTypesInfo&lt;/span&gt;

  &lt;span class="c1"&gt;// NeedTypesSizes adds TypesSizes.&lt;/span&gt;
  &lt;span class="n"&gt;NeedTypesSizes&lt;/span&gt;

  &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It might seem like a simple mistake, but the standard go vet won't catch it. Yet the open-source tool I mentioned in the previous case study does find it. So, I'd like to reiterate the issue: go vet sometimes finds problems that other tools don't, and vice versa.&lt;/p&gt;

&lt;p&gt;We discussed this and other errors that the standard go vet can't detect in the "&lt;a href="https://pvs-studio.com/en/blog/posts/go/1342/" rel="noopener noreferrer"&gt;Go vet can't go: How PVS-Studio analyzes Go projects&lt;/a&gt;" article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Go-specific issues
&lt;/h2&gt;

&lt;p&gt;Of course, Go has its own pitfalls. Even seasoned Go developers may not be familiar with all of the language's unique features and tricky parts (not to mention those coming from other languages).&lt;/p&gt;

&lt;p&gt;For such cases, our comprehensive documentation provides detailed explanations of why this or that error occurred. We also have examples of common mistakes and how to fix them :)&lt;/p&gt;

&lt;p&gt;Well, let's look at a couple of diagnostic rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  recover() inside an anonymous function that isn't wrapped in defer
&lt;/h3&gt;

&lt;p&gt;In Go, &lt;code&gt;recover&lt;/code&gt; resumes execution only if called inside a deferred (&lt;code&gt;defer&lt;/code&gt;) function. &lt;/p&gt;

&lt;p&gt;However, if an anonymous function with &lt;code&gt;recover&lt;/code&gt; is called immediately as &lt;code&gt;(func() { ... }())&lt;/code&gt;, by the time a potential panic occurs, that call will have long since completed—&lt;code&gt;recover&lt;/code&gt; is physically unable to catch it. So, if a panic occurs, the goroutine can't resume execution.&lt;/p&gt;

&lt;p&gt;Here's the example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;recover&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Recovered"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;                        &lt;span class="c1"&gt;// &amp;lt;= recover started and finished immediately&lt;/span&gt;
    &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Div64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// panic, recover won't help here anymore&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After defining the anonymous function and calling it, the &lt;code&gt;bits.Div64&lt;/code&gt; function is called. This function can trigger a panic if &lt;code&gt;y&lt;/code&gt; equals &lt;code&gt;0&lt;/code&gt;. If that panic reaches the top of the stack, the program will crash.&lt;/p&gt;

&lt;p&gt;Of course, the documentation explains how to fix this: the anonymous function call needs to be deferred using the &lt;code&gt;defer&lt;/code&gt; keyword:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;recover&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Recovered"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}()&lt;/span&gt;
  &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Div64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more details, refer to the &lt;a href="https://pvs-studio.com/en/docs/warnings/v8007/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  They couldn't have made such a mistake, right?
&lt;/h3&gt;

&lt;p&gt;Here's an error so interesting that we wrote an article about it titled "&lt;a href="https://pvs-studio.com/en/blog/posts/go/1393/" rel="noopener noreferrer"&gt;One mistake no one has ever made. Right?"&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since the article describes it pretty thoroughly and includes examples from real projects, I'll just give a brief overview:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;SimpleExample&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Collection indices always start at 0. So, for a slice of the &lt;code&gt;n&lt;/code&gt; length, the valid indices range from 0 to &lt;code&gt;n – 1&lt;/code&gt;. Then &lt;code&gt;len(arr)&lt;/code&gt; returns &lt;code&gt;n&lt;/code&gt;. As a result, accessing &lt;code&gt;arr[len(arr)]&lt;/code&gt; always leads to a program panic.&lt;/p&gt;

&lt;p&gt;Here's an interesting thing: when developing this diagnostic rule, we thought it was "far-fetched" and that "no one would make a mistake like that" because any test would catch it. But the results were fascinating! You can check them out in the &lt;a href="https://pvs-studio.com/en/blog/posts/go/1393/" rel="noopener noreferrer"&gt;article&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Confusing XOR (^) with exponentiation
&lt;/h3&gt;

&lt;p&gt;Here's another interesting Go-specific mistake.&lt;/p&gt;

&lt;p&gt;Unlike in Lua, VB.NET, and R, in Go, &lt;code&gt;^&lt;/code&gt; has nothing to do with exponentiation, which can be a trap for developers switching between languages. This mistake is exciting because, if we recall the problem with universal mistakes from the beginning of the article, it results in an unfortunate combination.&lt;/p&gt;

&lt;p&gt;Binary expressions meant for exponentiation become incorrect when a developer chooses &lt;code&gt;^&lt;/code&gt;. This operator actually performs a bitwise exclusive &lt;code&gt;OR&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The example is painfully simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In reality, the value here is 18 instead of the expected 2 to the power of 16 (65,536). As the &lt;a href="https://pvs-studio.com/en/docs/warnings/v8015/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; suggests, we can use the left bitwise shift operator to get the power of &lt;code&gt;2&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;If you're familiar with our work, then you've probably heard that PVS-Studio detects code quality issues and serves as a static application security testing (SAST) solution. This means our analyzer can also spot potential vulnerabilities.&lt;/p&gt;

&lt;p&gt;Our new Go analyzer currently includes only a basic set of diagnostic rules that cover common code quality issues. This is just the beginning, though! &lt;/p&gt;

&lt;p&gt;Consider this an announcement: we've already started working on SAST coverage for our Go analyzer. Stay tuned to &lt;a href="https://pvs-studio.com/en/blog/posts/" rel="noopener noreferrer"&gt;our blog&lt;/a&gt; for updates :)&lt;/p&gt;

&lt;p&gt;To back that up, let me introduce one of the first diagnostic rules in the code security section. &lt;/p&gt;

&lt;h3&gt;
  
  
  Trojan Source
&lt;/h3&gt;

&lt;p&gt;Take a look at this code fragment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;isAuthorized&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;span class="cm"&gt;/* verify before transfer */&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;isAuthorized&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;TransferFunds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="cm"&gt;/* end verify */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What do you think it would look like to the compiler (without all the conventions and low-level details)?&lt;/p&gt;

&lt;p&gt;If you think it should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;isAuthorized&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;isAuthorized&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;TransferFunds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Well, you're almost right... &lt;/p&gt;

&lt;p&gt;It looks as though the funds transfer is indeed protected by the &lt;code&gt;isAuthorized&lt;/code&gt; check.&lt;/p&gt;

&lt;p&gt;However, the issue lurks where we can't see it, because the compiler will interpret this as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;isAuthorized&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;span class="n"&gt;TransferFunds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It doesn't look that great anymore, does it? The &lt;code&gt;isAuthorized&lt;/code&gt; check never runs because the &lt;code&gt;if&lt;/code&gt; statement and &lt;code&gt;{...}&lt;/code&gt; ended up inside what the reviewer considered to be "commented-out" text, so the &lt;code&gt;TransferFunds&lt;/code&gt; call executes unconditionally.&lt;/p&gt;

&lt;p&gt;The code contains special characters that may not be displayed. They can change how the code appears in the development environment. Combinations of such characters can cause a human and a compiler to interpret the code differently.&lt;/p&gt;

&lt;p&gt;Here's what the code actually looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;isAuthorized&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;span class="cm"&gt;/*[RLO] } [LRI] if isAuthorized[PDI] [LRI] verify before transfer */&lt;/span&gt;  
    &lt;span class="n"&gt;TransferFunds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="cm"&gt;/* end verify [RLO]{ [LRI]*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's briefly go over what these characters do here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;[LRI] if isAuthorized[PDI]&lt;/code&gt;: the fragment between &lt;code&gt;LRI&lt;/code&gt; and &lt;code&gt;PDI&lt;/code&gt; is isolated and evaluated from left to right as a single block (&lt;code&gt;if isAuthorized&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[LRI] verify before transfer */&lt;/code&gt;: to the end of the line; this is also an isolated block (&lt;code&gt;verify before transfer */&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;[RLO]&lt;/code&gt;: reverses from right to left everything that follows it, and each of the obtained isolated blocks is treated as a single, indivisible character.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The final order is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;verify&lt;/span&gt; &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="n"&gt;transfer&lt;/span&gt; &lt;span class="err"&gt;*/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;isAuthorized&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;space&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="sc"&gt;'{'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;space&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, lo and behold! With a couple of simple gestures, the closing brace visually turns into an opening one.&lt;/p&gt;

&lt;p&gt;This is an issue that PVS-Studio will highlight:&lt;/p&gt;

&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v5901/" rel="noopener noreferrer"&gt;V5901&lt;/a&gt;. OWASP. Code contains invisible characters that may alter its logic. Consider enabling the display of invisible characters in the code editor.&lt;/p&gt;

&lt;p&gt;This vulnerability is listed in the &lt;a href="https://pvs-studio.com/en/pvs-studio/sast/owasptopten/" rel="noopener noreferrer"&gt;OWASP standard&lt;/a&gt;, and our other analyzers can detect similar issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;V5801 — JS\TS;&lt;/li&gt;
&lt;li&gt;V5340 — Java;&lt;/li&gt;
&lt;li&gt;V5629 — C#;&lt;/li&gt;
&lt;li&gt;V1076 — C++.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We've covered this diagnostic rule in more detail in the &lt;a href="https://pvs-studio.com/en/docs/warnings/v5901/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is this the end? No, it's just the beginning!
&lt;/h2&gt;

&lt;p&gt;The new analyzer for Go projects is here, but this is only the beginning of its story! The 40 diagnostic rules introduced with PVS-Studio 8.0 mark the start of that journey, and your input can make a real difference. If you're a Go developer, we invite you to &lt;a href="https://pvs-studio.com/en/pvs-studio/try-free/?utm_source=website&amp;amp;utm_medium=devto&amp;amp;utm_campaign=article&amp;amp;utm_content=1413" rel="noopener noreferrer"&gt;try our tool for free&lt;/a&gt;. If you have ideas for new diagnostic rules or suggestions for improving the existing ones, feel free to &lt;a href="https://pvs-studio.com/en/about-feedback/" rel="noopener noreferrer"&gt;reach out to us&lt;/a&gt; through the feedback form!&lt;/p&gt;

&lt;p&gt;Thanks for reading. Take care of yourself and your code!&lt;/p&gt;

</description>
      <category>go</category>
      <category>softwaredevelopment</category>
      <category>programming</category>
    </item>
    <item>
      <title>What's new in Java 27</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Tue, 15 Sep 2026 13:22:03 +0000</pubDate>
      <link>https://dev.to/pvsdev/whats-new-in-java-27-8b3</link>
      <guid>https://dev.to/pvsdev/whats-new-in-java-27-8b3</guid>
      <description>&lt;p&gt;Java 27 is here, with four targeted updates and five previews/incubators. We take a closer look at the garbage collector changes, JFR improvements, post-quantum TLS 1.3, and compact object headers (which cut memory usage).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcw2k4qtwof54j6lq4dcw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcw2k4qtwof54j6lq4dcw.png" alt="1412_java27/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Java platform changes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  JEP 534: Compact Object Headers by Default
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://openjdk.org/jeps/534" rel="noopener noreferrer"&gt;Link to JEP&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://pvs-studio.com/en/blog/posts/java/1284/" rel="noopener noreferrer"&gt;article about Java 25,&lt;/a&gt; we already mentioned compact object headers that we could turn on with a flag. Now there's no need to use the flag.&lt;/p&gt;

&lt;p&gt;At that time, we only touched on this topic briefly. Now that it's on by default, we're going to break it down once again, in more depth.&lt;/p&gt;

&lt;p&gt;Every object in the heap begins with a header. In the classic layout (in most JVMs), that's two blocks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lock status, object's age for GC, identity hash;&lt;/li&gt;
&lt;li&gt;a compact pointer to the class's metadata.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In total, we get 96 bits (12 bytes) per object, even if it contains very little useful data. Compact object headers compress all of this into 64 bits: the pointer to the class metadata is compressed down to 22 bits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fijku5fpjhbi0c1hwdavz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fijku5fpjhbi0c1hwdavz.png" alt="1412_java27/image2.png" width="671" height="673"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In theory, saving a few bits is a good thing, though, but what benefits shall we (as JRE users) actually get out of it? &lt;/p&gt;

&lt;p&gt;Not long ago, we &lt;a href="https://pvs-studio.com/en/blog/posts/1406/" rel="noopener noreferrer"&gt;released&lt;/a&gt; a JavaScript/TypeScript analyzer powered by Java 25. We'll use it as a test subject, "set it loose" on the &lt;a href="https://github.com/grafana/grafana" rel="noopener noreferrer"&gt;Grafana source code&lt;/a&gt;, and run it with and without compact object headers.&lt;/p&gt;

&lt;p&gt;Three minutes later, we get this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Benchmark&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;With flag&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Without flag&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Time&lt;/td&gt;
&lt;td&gt;81.4 sec&lt;/td&gt;
&lt;td&gt;79.4 sec&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Committed heap&lt;/td&gt;
&lt;td&gt;1 290 240K (~1.23 GB)&lt;/td&gt;
&lt;td&gt;1 126 400K (~1.07 GB)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Used heap: output&lt;/td&gt;
&lt;td&gt;1 150 092K (~1.1 GB)&lt;/td&gt;
&lt;td&gt;773 062K (~738 MB)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Committed heap represents the amount of memory the virtual machine has allocated from the OS and is keeping reserved. Used heap is the memory in use right now—in other words, the number of bytes occupied by live objects that haven't yet been removed by the garbage collector.&lt;/p&gt;

&lt;p&gt;As a result, analysis time remained almost unchanged (within margin of error), committed heap decreased by 13%, and used heap shrank by 33% in total! Just one flag reduced our app's memory usage by a full third, wow!&lt;/p&gt;

&lt;p&gt;What's the cost of our joy? A 22-bit pointer limits the number of loaded classes to approximately four million. There's no automatic rollback to a non-compact mode—if the limit is exceeded, we'll get an &lt;code&gt;OutOfMemoryError&lt;/code&gt;. If your app really hits this limit, you must really love long-lived streams. But if you want to revert to the previous mode, you can do it with another flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;java&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;XX&lt;/span&gt;&lt;span class="o"&gt;:-&lt;/span&gt;&lt;span class="n"&gt;UseCompactObjectHeaders&lt;/span&gt; &lt;span class="n"&gt;Application&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  JEP 523: Make G1 the Default Garbage Collector in All Environments
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://openjdk.org/jeps/523" rel="noopener noreferrer"&gt;Link to JEP&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Prior to Java 27, the JVM would check the machine at startup, and if it detected fewer than two processors or less than 1,792 MB of memory, it'd just use Serial GC instead of G1. That kind of machine got labeled a "client" machine, and the memory allocator best suited for it was used.&lt;/p&gt;

&lt;p&gt;Now, guess what a modest JVM container with a limit of one CPU and 512 MB of memory looks like?&lt;/p&gt;

&lt;p&gt;Right. A chunk of containerized Java apps has been running on a client-oriented collector all this time, even though no one consciously made that decision. Worse yet, the same app could get different GCs on the server and in the developer's IDE, which turned reproducing pausing issues into a thrilling quest with a touch of manic laughter.&lt;/p&gt;

&lt;p&gt;Java 27 stopped taking the environment into account and now G1 is selected by default:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;# Java 25
&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;java&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;XX&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ActiveProcessorCount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Xmx256m&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Xlog&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;gc&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mx"&gt;0.001s&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;gc&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;Using&lt;/span&gt; &lt;span class="n"&gt;Serial&lt;/span&gt;

&lt;span class="cp"&gt;# Java 27
&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt; &lt;span class="n"&gt;java&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;XX&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ActiveProcessorCount&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Xmx256m&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;Xlog&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;gc&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mx"&gt;0.001s&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;gc&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;Using&lt;/span&gt; &lt;span class="n"&gt;G1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reasoning is simple: improvements to G1's throughput in previous releases have reduced the gap with Serial to almost zero, and G1's pauses are noticeably more pleasant because it can operate concurrently and in parallel. Plus, predictability: the application's behavior no longer depends on how many cores the JVM detected at startup.&lt;/p&gt;

&lt;p&gt;If you specifically want to use &lt;code&gt;Serial&lt;/code&gt;—it still has the lowest memory footprint and faster startup time—you can still use it: &lt;code&gt;-XX:+UseSerialGC&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security
&lt;/h2&gt;

&lt;h3&gt;
  
  
  JEP 527: Post-Quantum Hybrid Key Exchange for TLS 1.3
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://openjdk.org/jeps/527" rel="noopener noreferrer"&gt;Link to JEP&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ever heard of "harvest now, decrypt later"?&lt;/p&gt;

&lt;p&gt;This is an amusing category of threats, though: attackers, having access to your traffic but unable to break the TLS connection, simply save the encrypted traffic for later.&lt;/p&gt;

&lt;p&gt;Why would they do that, what's the purpose? It's very curious: attackers have a strong faith in global progress and are waiting for a quantum computer capable of breaking elliptic curve key exchange. Medical and banking records, encryption keys, personal data—all of these will still be valuable ten years from now, so the scheme is quite viable.&lt;/p&gt;

&lt;p&gt;Following HTTP/3 (see the &lt;a href="https://pvs-studio.com/en/blog/posts/java/1370/#ID6A3D58AEB3" rel="noopener noreferrer"&gt;previous article&lt;/a&gt;), support for TLS 1.3 is now available. The session key in TLS 1.3 now gets generated using two algorithms simultaneously: a classic elliptic curve key exchange plus a quantum-resistant algorithm. Such a pairing is called &lt;em&gt;a hybrid group&lt;/em&gt;, and the point is that the connection remains secure as long as at least one of the two algorithms is still in service. So this update makes it pointless to wait for a quantum computer to arrive.&lt;/p&gt;

&lt;p&gt;For the application, this is free in terms of code: &lt;code&gt;javax.net.ssl&lt;/code&gt; automatically sets the hybrid group as the first in the preference list. If the other side supports it, the exchange gets a hybrid approach; if not, everything works as before. There's nothing to touch, unless you've manually set a list of groups via &lt;code&gt;jdk.tls.namedGroups&lt;/code&gt; or &lt;code&gt;SSLParameters::setNamedGroups&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But in some cases, we'll still have to pay a little extra: a TLS handshake costs about two KB more. For most applications, this goes unnoticed, but with millions of short connections in the traffic, you'll see it.&lt;/p&gt;

&lt;p&gt;An important note: this JEP applies only to key exchange. Certificate signatures are still in the classic format, and this is a deliberate choice: it is impossible to forge a signature retroactively, but it is entirely possible to decrypt recorded traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  JFR enhancements
&lt;/h2&gt;

&lt;h3&gt;
  
  
  JEP 536: JFR In-Process Data Redaction
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://openjdk.org/jeps/536" rel="noopener noreferrer"&gt;Link to JEP&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When recording, &lt;a href="https://openjdk.org/jeps/328" rel="noopener noreferrer"&gt;JFR&lt;/a&gt; carefully preserves the entire process environment: environment variables, system properties, and command-line arguments. And that's where, as we all know, database passwords, tokens, and keys to everything tend to live. That's why sending a &lt;code&gt;.jfr&lt;/code&gt; file to a colleague—and especially attaching it to a public issue—always came with a slight twinge of anxiety. In most cases, you shouldn't make &lt;code&gt;.jfr&lt;/code&gt; files publicly available at all without cleaning them up first.&lt;/p&gt;

&lt;p&gt;Starting with Java 27, JFR scrubs sensitive values within the JVM before they're passed to disk. And what does JFR consider to be sensitive data? By default, any environment variable or system property whose name matches one of these patterns gets replaced with &lt;code&gt;[REDACTED]&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;      &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;        &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;jaas&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;passphrase&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;passwd&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;         &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;  &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pwd&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;         &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;         &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Command-line arguments of the form &lt;code&gt;--db-password qwerty123&lt;/code&gt; are handled in the same way.&lt;/p&gt;

&lt;p&gt;We can expand the list of properties using the &lt;code&gt;-XX:FlightRecorderOptions:redact-key=+&amp;lt;your-pattern&amp;gt;&lt;/code&gt; flag.&lt;/p&gt;

&lt;p&gt;It's worth understanding the limits here: the mechanism covers start events (environment variables, system properties, arguments, and JVM information) and is explicitly described as best-effort. It doesn't filter your app's events, exception messages, or child process command lines. In other words, &lt;code&gt;.jfr&lt;/code&gt; has become significantly safer now, but not sterile in total. We're still worried, but not as much as before.&lt;/p&gt;

&lt;h2&gt;
  
  
  In preview
&lt;/h2&gt;

&lt;p&gt;A few more JEPs have been included in the release as previews. We won't cover them for now, we'll wait for their final versions. Here are some links for you to explore on your own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://openjdk.org/jeps/531" rel="noopener noreferrer"&gt;JEP 531: Lazy Constants (Third Preview)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openjdk.org/jeps/532" rel="noopener noreferrer"&gt;JEP 532: Primitive Types in Patterns, instanceof, and switch (Fifth Preview)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openjdk.org/jeps/533" rel="noopener noreferrer"&gt;JEP 533: Structured Concurrency (Seventh Preview)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openjdk.org/jeps/537" rel="noopener noreferrer"&gt;JEP 537: Vector API (Twelfth Incubator)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://openjdk.org/jeps/538" rel="noopener noreferrer"&gt;JEP 538: PEM Encodings of Cryptographic Objects (Third Preview)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The full list of JEPs is &lt;a href="https://openjdk.org/projects/jdk/27/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This was a minor release, and there was nothing here in the way of earth-shattering, 180-degree changes: they've updated the preview and polished up the platform. And that brings useful thing right out of the box for the JVM: objects on the heap are more compact, the garbage collector is the same for both the server and a tiny pod, JFR logs are no longer brimming with secrets, and TLS is preparing for a quantum future.&lt;/p&gt;

&lt;p&gt;Essentially, this is preparation for the next LTS. &lt;a href="https://openjdk.org/jeps/533" rel="noopener noreferrer"&gt;Structured Concurrency&lt;/a&gt; is now on its seventh preview, &lt;a href="https://openjdk.org/jeps/532" rel="noopener noreferrer"&gt;primitives in patterns&lt;/a&gt; are in their fifth preview, and the &lt;a href="https://openjdk.org/jeps/537" rel="noopener noreferrer"&gt;Vector API&lt;/a&gt; is waiting for &lt;a href="https://openjdk.org/projects/valhalla/" rel="noopener noreferrer"&gt;Valhalla&lt;/a&gt;. All of this is being finalized so that it can be delivered ready to go with Java 29. Well, for now, though, let's just update and get a more compact heap for free.&lt;/p&gt;

</description>
      <category>java</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
      <category>news</category>
    </item>
    <item>
      <title>What popular ORMs for C# hide: Let's check RepoDB and SqlSugar</title>
      <dc:creator>Unicorn Developer</dc:creator>
      <pubDate>Thu, 10 Sep 2026 13:43:08 +0000</pubDate>
      <link>https://dev.to/pvsdev/what-popular-orms-for-c-hide-lets-check-repodb-and-sqlsugar-mck</link>
      <guid>https://dev.to/pvsdev/what-popular-orms-for-c-hide-lets-check-repodb-and-sqlsugar-mck</guid>
      <description>&lt;p&gt;When it comes to ORMs, most C# developers immediately think of the powerful Entity Framework Core or the lightweight Dapper. What about RepoDB and SqlSugar, though? While they may not be as well-known, these ORMs are actually being used in real-world projects and are still developing. Let's take a look at what issues we can uncover in their source code with the help of a static analyzer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fffe2i5v39ffikw4tdodw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fffe2i5v39ffikw4tdodw.png" alt="1411_dotnet_orm_errors/image1.png" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;It's hard to imagine a modern application without an ORM: this technology helps developers by reducing the amount of code they need to write and by eliminating the need to work directly with SQL. &lt;/p&gt;

&lt;p&gt;The ORM manages all interactions with the database, including processing read and write queries, transactions, and object-to-SQL mapping. Errors in such tools can lead to serious consequences: from reduced performance to application malfunctions and even security issues.&lt;/p&gt;

&lt;p&gt;In the .NET world, &lt;a href="https://github.com/dotnet/efcore" rel="noopener noreferrer"&gt;Entity Framework Core&lt;/a&gt; and &lt;a href="https://github.com/DapperLib/Dapper" rel="noopener noreferrer"&gt;Dapper&lt;/a&gt; are the industry standards. However, many less popular tools are also used in real-world projects. &lt;a href="https://github.com/mikependon/RepoDB" rel="noopener noreferrer"&gt;RepoDB&lt;/a&gt; and &lt;a href="https://github.com/DotNetNext/SqlSugar" rel="noopener noreferrer"&gt;SqlSugar&lt;/a&gt; are among these ORMs.&lt;/p&gt;

&lt;p&gt;In this article, we'll look at them through the lens of PVS-Studio static analyzer. Instead of comparing API capabilities or performance, we'll check the projects' source code for potential bugs and suspicious constructs.&lt;/p&gt;

&lt;h2&gt;
  
  
  SqlSugar
&lt;/h2&gt;

&lt;p&gt;Let's move on to discussing the most exciting parts of the SqlSugar code. The source code comes from &lt;a href="https://github.com/DotNetNext/SqlSugar/tree/d221c7b14ab4bc4c81ce53b6a450c96e70091168" rel="noopener noreferrer"&gt;this commit&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The forgotten CancellationToken
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Code fragment 1
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ExecuteCommandAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CancellationToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CancellationToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ExecuteCommandAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3005/" rel="noopener noreferrer"&gt;V3005&lt;/a&gt; The 'this.CancellationToken' variable is assigned to itself. &lt;a href="https://github.com/DotNetNext/SqlSugar/blob/d221c7b14ab4bc4c81ce53b6a450c96e70091168/Src/Asp.Net/SqlSugar/Abstract/AdoProvider/AdoProvider.cs#L1472" rel="noopener noreferrer"&gt;AdoProvider.cs 1472&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;CancellationToken&lt;/code&gt; auto-property is assigned its own value. Most likely, this property should be assigned the value of the &lt;code&gt;cancellationToken&lt;/code&gt; parameter instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  A pointless string check
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Code fragment 2
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;AppColumns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SqlInfo&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="n"&gt;ISugarQueryable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;queryable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;columnName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;selectPkName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;queryable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SqlBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetTranslationColumnName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;columnName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsSelectNav&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;   &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SelectString&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt; 
        &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SelectString&lt;/span&gt;
                  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToLower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="s"&gt;" {selectPkName.ToLower()}&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="s"&gt;                              AS {selectPkName.ToLower()}"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;            &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SelectString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SelectString&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;","&lt;/span&gt; 
        &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selectPkName&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" AS "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;selectPkName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3122/" rel="noopener noreferrer"&gt;V3122&lt;/a&gt; Lowercase string is compared with a different mixed case string. &lt;a href="https://github.com/DotNetNext/SqlSugar/blob/d221c7b14ab4bc4c81ce53b6a450c96e70091168/Src/Asp.Net/SqlSugar/Abstract/QueryableProvider/NavigatManager.cs#L1131" rel="noopener noreferrer"&gt;NavigatManager.cs 1131&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's take a closer look at what's going wrong here. First, the &lt;code&gt;result.SelectString&lt;/code&gt; string is converted to lowercase using the &lt;code&gt;ToLower&lt;/code&gt; method, and then the resulting string is checked whether it contains &lt;code&gt;$" {selectPkName.ToLower()} AS {selectPkName.ToLower()}"&lt;/code&gt;. The substring we're looking for contains uppercase letters (&lt;code&gt;AS&lt;/code&gt;). As a result, the &lt;code&gt;Contains&lt;/code&gt; method will always return &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To fix the code, we can simply convert all the characters to lowercase:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SelectString&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToLower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="s"&gt;" {selectPkName.ToLower()} as {selectPkName.ToLower()}"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Recurring conditions
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Code fragment 3
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;ToSqlString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InsertServerTime&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InsertSql&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HasValue&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; 
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;GetDbColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;   &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; 
           &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; 
           &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;short&lt;/span&gt;                                    &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
           &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;short&lt;/span&gt;                                    &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
           &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;byte&lt;/span&gt; 
           &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;  &lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3001/" rel="noopener noreferrer"&gt;V3001&lt;/a&gt; There are identical sub-expressions 'it.Value is short' to the left and to the right of the '||' operator. &lt;a href="https://github.com/DotNetNext/SqlSugar/blob/d221c7b14ab4bc4c81ce53b6a450c96e70091168/Src/Asp.Net/SqlSugar/Realization/QuestDB/SqlBuilder/QuestDBInsertBuilder.cs#L89" rel="noopener noreferrer"&gt;QuestDBInsertBuilder.cs 89&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;it.Value is short&lt;/code&gt; sub-expression twice is pointless. Perhaps &lt;code&gt;short&lt;/code&gt; should be replaced with another type, such as &lt;code&gt;decimal&lt;/code&gt; or &lt;code&gt;float&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Code fragment 4
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;GetTypeConvert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;   &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; 
      &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;uint&lt;/span&gt; 
      &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; 
      &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;uint&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToInt32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;   &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;short&lt;/span&gt; 
           &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;ushort&lt;/span&gt; 
           &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;short&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; 
           &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;ushort&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToInt16&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;   &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; 
           &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;                                       &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
           &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;ulong&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; 
           &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                                      &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToInt64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3001/" rel="noopener noreferrer"&gt;V3001&lt;/a&gt; There are identical sub-expressions 'value is long?' to the left and to the right of the '||' operator. &lt;a href="https://github.com/DotNetNext/SqlSugar/blob/d221c7b14ab4bc4c81ce53b6a450c96e70091168/Src/Asp.Net/SqlSugar.MySqlConnector/Tools/UtilMethods.cs#L288" rel="noopener noreferrer"&gt;UtilMethods.cs 288&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The developers used the &lt;code&gt;value is long?&lt;/code&gt; condition twice here. Based on the code above, we can assume that the second identical condition should be replaced with &lt;code&gt;value is ulong&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  An unused parameter
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Code fragment 5
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ExpressionParameter&lt;/span&gt; &lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                       &lt;span class="n"&gt;MemberExpression&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                       &lt;span class="kt"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;isLeft&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                       &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isSingle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isSingle&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;GetSingleName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IsLeft&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;GetMultipleName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IsLeft&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3196/" rel="noopener noreferrer"&gt;V3196&lt;/a&gt; The 'isLeft' parameter is not utilized inside the method body, but an identifier with a similar name is used inside the same method. &lt;a href="https://github.com/DotNetNext/SqlSugar/blob/d221c7b14ab4bc4c81ce53b6a450c96e70091168/Src/Asp.Net/SqlSugar/ExpressionsToSql/ResolveItems/MemberExpressionResolve.cs#L770" rel="noopener noreferrer"&gt;MemberExpressionResolve.cs 770&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;isLeft&lt;/code&gt; parameter isn't used, but the method accesses a property whose name differs from the parameter name only in the capitalization of the first letter.&lt;/p&gt;

&lt;p&gt;The developers might have wanted to use &lt;code&gt;isLeft&lt;/code&gt; parameter of the &lt;code&gt;GetName&lt;/code&gt; method intended of the &lt;code&gt;IsLeft&lt;/code&gt; property.&lt;/p&gt;

&lt;h3&gt;
  
  
  The missing num
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Code fragment 6
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Expression&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numExp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt; &lt;span class="n"&gt;as&lt;/span&gt; &lt;span class="n"&gt;MethodCallExpression&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Arguments&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ExpressionTool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetParameters&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numExp&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; 
  &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;copyContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetCopyContextWithMapping&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;copyContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsSingle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;copyContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numExp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ResolveExpressType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WhereMultiple&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;copyContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;                              &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; 
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ExpressionTool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DynamicInvoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numExp&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;ObjToInt&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;take&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt; &lt;span class="n"&gt;as&lt;/span&gt; &lt;span class="n"&gt;MethodCallExpression&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(....)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"TOP "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;OracleExpressionContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HasWhere&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s"&gt;"AND"&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"WHERE"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" ROWNUM&amp;lt;="&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(....)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"limit "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetLimit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Case&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Case&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HasWhere&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HasWhere&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Case&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetLimit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"limit "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3010/" rel="noopener noreferrer"&gt;V3010&lt;/a&gt; The return value of function 'GetString' is required to be utilized.  &lt;a href="https://github.com/DotNetNext/SqlSugar/blob/d221c7b14ab4bc4c81ce53b6a450c96e70091168/Src/Asp.Net/SqlSugar/ExpressionsToSql/Subquery/Items/SubTake.cs#L64" rel="noopener noreferrer"&gt;SubTake.cs 64&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The analyzer reports that the return value of the &lt;code&gt;GetString&lt;/code&gt; method isn't used. At the same time, the &lt;code&gt;GetString&lt;/code&gt; implementation reveals that the method only builds and returns a string representation of &lt;code&gt;_Result&lt;/code&gt;. It doesn't modify the object's state or perform any actions whose results are used later in the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;GetString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_Result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IsUpper&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
  &lt;span class="n"&gt;_Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
         &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToUpper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
         &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UtilConstants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReplaceCommaKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
         &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TrimEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;','&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UtilConstants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ReplaceCommaKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;","&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TrimEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;','&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, the result of the &lt;code&gt;GetString&lt;/code&gt; call is discarded in the current code. The developers probably forgot to use the return value when calculating &lt;code&gt;num&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The surrounding code also supports this assumption: every return from the method uses the &lt;code&gt;num&lt;/code&gt; variable. Following this logic, both branches of the first condition should calculate the same value and assign it to the &lt;code&gt;num&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;The correct code may look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="n"&gt;copyContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numExp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ResolveExpressType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WhereMultiple&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;copyContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  RepoDB
&lt;/h2&gt;

&lt;p&gt;Now let's look at some errors and issues in the RepoDB project. The source code comes from &lt;a href="https://github.com/mikependon/RepoDB/tree/58004d4b05a99b0332e8eb3bbe74d366030b8924" rel="noopener noreferrer"&gt;this commit&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pointless checks
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Code fragment 1
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="nf"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;ConditionalExpression&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;trueValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IfTrue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NodeType&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;ExpressionType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;trueValue&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;trueValue&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IfFalse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NodeType&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;ExpressionType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotEqual&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;trueValue&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="n"&gt;trueValue&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IfFalse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NodeType&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ExpressionType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GreaterThan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NodeType&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ExpressionType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GreaterThanOrEqual&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;....&lt;/span&gt;  
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NodeType&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ExpressionType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LessThan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;          &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NodeType&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ExpressionType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LessThanOrEqual&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NotSupportedException&lt;/span&gt;&lt;span class="p"&gt;(....);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warnings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;V3022 Expression 'expression.Test.NodeType &amp;gt; ExpressionType.GreaterThanOrEqual' is always false. &lt;a href="https://github.com/mikependon/RepoDB/blob/58004d4b05a99b0332e8eb3bbe74d366030b8924/RepoDb.Core/RepoDb/Extensions/ExpressionExtension.cs#L456" rel="noopener noreferrer"&gt;ExpressionExtension.cs 456&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;V3022 Expression 'expression.Test.NodeType &amp;gt; ExpressionType.LessThan' is always false. &lt;a href="https://github.com/mikependon/RepoDB/blob/58004d4b05a99b0332e8eb3bbe74d366030b8924/RepoDb.Core/RepoDb/Extensions/ExpressionExtension.cs#L460" rel="noopener noreferrer"&gt;ExpressionExtension.cs 460&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;V3022 Expression 'expression.Test.NodeType &amp;gt; ExpressionType.LessThanOrEqual' is always false. &lt;a href="https://github.com/mikependon/RepoDB/blob/58004d4b05a99b0332e8eb3bbe74d366030b8924/RepoDb.Core/RepoDb/Extensions/ExpressionExtension.cs#L464" rel="noopener noreferrer"&gt;ExpressionExtension.cs 464&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the &lt;code&gt;GetValue&lt;/code&gt; method, &lt;code&gt;expression.Test.NodeType&lt;/code&gt; is successively compared against different values from the &lt;code&gt;ExpressionType&lt;/code&gt; enumeration. However, the last four checks use the &lt;code&gt;&amp;gt;&lt;/code&gt; operator instead of the equality operator.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;else if&lt;/code&gt; chain executes sequentially, and the enumeration values in the lower branches are greater than those in the branches above them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;ExpressionType&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="n"&gt;GreaterThan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;GreaterThanOrEqual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="n"&gt;LessThan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;LessThanOrEqual&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;expression.Test.NodeType &amp;gt; ExpressionType.GreaterThan&lt;/code&gt; condition covers all the conditions that follow. &lt;/p&gt;

&lt;p&gt;So, if &lt;code&gt;expression.Test.NodeType &amp;gt; ExpressionType.GreaterThan&lt;/code&gt; evaluates to &lt;code&gt;true&lt;/code&gt;, the subsequent conditions aren't checked. If it evaluates to &lt;code&gt;false&lt;/code&gt;, the following conditions are &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  A copy-paste error
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Code fragment 2
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;GetHashCode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Make sure to return if it is already provided&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hashCode&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hashCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Get first the entity hash code&lt;/span&gt;
  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;hashCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HashCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetHashCode&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;".UpdateAll"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Get the fields&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fields&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Fields&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                           &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;hashCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HashCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hashCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Get the qualifier &amp;lt;see cref="Field"/&amp;gt; objects&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Fields&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                                       &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;Qualifiers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;hashCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HashCode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hashCode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3127/" rel="noopener noreferrer"&gt;V3127&lt;/a&gt; Two similar code fragments were found. Perhaps, this is a typo and 'Qualifiers' variable should be used instead of 'Fields'. &lt;a href="https://github.com/mikependon/RepoDB/blob/58004d4b05a99b0332e8eb3bbe74d366030b8924/RepoDb.Core/RepoDb/Requests/UpdateAllRequest.cs#L124" rel="noopener noreferrer"&gt;UpdateAllRequest.cs 124&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Fields&lt;/code&gt; is checked for &lt;code&gt;null&lt;/code&gt; twice. Most likely, the second check should use &lt;code&gt;Qualifiers&lt;/code&gt; instead of &lt;code&gt;Fields&lt;/code&gt;, since this collection is used in &lt;code&gt;foreach&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Code fragment 3
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;UpdateAllAsync&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(....&lt;/span&gt;
    &lt;span class="n"&gt;Expression&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Func&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TEntity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;qualifiers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;....,&lt;/span&gt;
    &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;....)&lt;/span&gt;
    &lt;span class="n"&gt;where&lt;/span&gt; &lt;span class="n"&gt;TEntity&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;UpdateAllAsyncInternal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;tableName:&lt;/span&gt; &lt;span class="n"&gt;tableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;entities:&lt;/span&gt; &lt;span class="n"&gt;entities&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;qualifiers:&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                                      &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
    &lt;span class="nl"&gt;batchSize:&lt;/span&gt; &lt;span class="n"&gt;batchSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;fields:&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                                          &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
    &lt;span class="nl"&gt;hints:&lt;/span&gt; &lt;span class="n"&gt;hints&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;commandTimeout:&lt;/span&gt; &lt;span class="n"&gt;commandTimeout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;traceKey:&lt;/span&gt; &lt;span class="n"&gt;traceKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;transaction:&lt;/span&gt; &lt;span class="n"&gt;transaction&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;trace:&lt;/span&gt; &lt;span class="n"&gt;trace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;statementBuilder:&lt;/span&gt; &lt;span class="n"&gt;statementBuilder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nl"&gt;cancellationToken:&lt;/span&gt; &lt;span class="n"&gt;cancellationToken&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3038/" rel="noopener noreferrer"&gt;V3038&lt;/a&gt; The argument was passed to method several times. It is possible that other argument should be passed instead. &lt;a href="https://github.com/mikependon/RepoDB/blob/58004d4b05a99b0332e8eb3bbe74d366030b8924/RepoDb.Core/RepoDb/Operations/DbConnection/UpdateAll.cs#L619" rel="noopener noreferrer"&gt;UpdateAll.cs 619&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, the &lt;code&gt;fields&lt;/code&gt; parameter is passed to the &lt;code&gt;UpdateAllAsyncInternal&lt;/code&gt; method twice, while the &lt;code&gt;qualifiers&lt;/code&gt; parameter isn't used at all.&lt;/p&gt;

&lt;p&gt;The developers might have wanted to pass &lt;code&gt;qualifiers&lt;/code&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="nl"&gt;qualifiers:&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TEntity&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;qualifiers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  An empty collection
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Code fragment 4
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="nf"&gt;CreateBatchQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;tableName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;rowsPerBatch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OrderField&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;orderBy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;QueryGroup&lt;/span&gt; &lt;span class="n"&gt;where&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;hints&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Ensure with guards&lt;/span&gt;
  &lt;span class="n"&gt;GuardTableName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tableName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Validate the hints&lt;/span&gt;
  &lt;span class="n"&gt;GuardHints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hints&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// There should be fields&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;MissingFieldsException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3191/" rel="noopener noreferrer"&gt;V3191&lt;/a&gt; Iteration through the 'fields' collection makes no sense because it is always empty. &lt;a href="https://github.com/mikependon/RepoDB/blob/58004d4b05a99b0332e8eb3bbe74d366030b8924/RepoDb.SqlServer/RepoDb.SqlServer/StatementBuilders/SqlServerStatementBuilder.cs#L70" rel="noopener noreferrer"&gt;SqlServerStatementBuilder.cs 70&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;fields?.Any() != true&lt;/code&gt; condition is true when the &lt;code&gt;fields&lt;/code&gt; collection is empty or &lt;code&gt;null&lt;/code&gt;. In that case, &lt;code&gt;fields?.Select(f =&amp;gt; f.Name)&lt;/code&gt; serves no purpose, as it will always return an empty collection or &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The treacherous null
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Code fragment 5
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="nf"&gt;GetGuid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;ThrowExceptionIfNotAvailable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3105/" rel="noopener noreferrer"&gt;V3105&lt;/a&gt; The result of null-conditional operator is passed as the first argument to the 'Parse' method and is not expected to be null. &lt;a href="https://github.com/mikependon/RepoDB/blob/58004d4b05a99b0332e8eb3bbe74d366030b8924/RepoDb.Core/RepoDb/DataEntityDataReader.cs#L405" rel="noopener noreferrer"&gt;DataEntityDataReader.cs 405&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, &lt;code&gt;GetValue(i)&lt;/code&gt; may return &lt;code&gt;null&lt;/code&gt;, which will be passed to the &lt;code&gt;Guid.Parse&lt;/code&gt; method because of the &lt;code&gt;?&lt;/code&gt; operator. And &lt;code&gt;Guid.Parse&lt;/code&gt; will throw an &lt;code&gt;ArgumentNullException&lt;/code&gt; when passed the &lt;code&gt;null&lt;/code&gt; argument.&lt;/p&gt;

&lt;h4&gt;
  
  
  Code fragment 6
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;AssertMembersEquality&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="n"&gt;IDictionary&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;dictionary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;value1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;value2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dictionary&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value1&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;b1&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value2&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;b2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;....&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;var&lt;/span&gt; &lt;span class="n"&gt;propertyType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;property&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PropertyType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetUnderlyingType&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;propertyType&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value2&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;dateTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;value2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TimeOfDay&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;propertyType&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value2&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;value1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value1&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;                &lt;span class="c1"&gt;// &amp;lt;=&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;....&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PVS-Studio warning: &lt;a href="https://pvs-studio.com/en/docs/warnings/v3105/" rel="noopener noreferrer"&gt;V3105&lt;/a&gt; The result of null-conditional operator is passed as the first argument to the 'Parse' method and is not expected to be null. &lt;a href="https://github.com/mikependon/RepoDB/blob/58004d4b05a99b0332e8eb3bbe74d366030b8924/RepoDb.SqLite/RepoDb.SqLite.IntegrationTests/Helper.cs#L157" rel="noopener noreferrer"&gt;Helper.cs 157&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, if &lt;code&gt;value1&lt;/code&gt; is &lt;code&gt;null&lt;/code&gt;, the &lt;code&gt;ArgumentNullException&lt;/code&gt; will be thrown.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Despite the substantial amount of code and extensive functionality of the projects, the analysis revealed only a few suspicious code fragments. This suggests that both projects are well written and maintained at a high standard.&lt;/p&gt;

&lt;p&gt;Still, perfect code doesn't exist. Even mature and popular libraries can contain copy-paste errors, forgotten parameters, incorrect conditions, and other minor issues that are easy to overlook during development and testing. This is where static analysis is particularly useful: it can highlight potential issues before they become real problems.&lt;/p&gt;

&lt;p&gt;If you'd like to analyze your own project with PVS-Studio, you can try it via this &lt;a href="https://pvs-studio.com/en/pvs-studio/try-free/?utm_source=website&amp;amp;utm_medium=devto&amp;amp;utm_campaign=article&amp;amp;utm_content=1411" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Take care of yourself and your code!&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>programming</category>
      <category>software</category>
    </item>
  </channel>
</rss>
