Bug Summary

File:clang/lib/Format/AffectedRangeManager.cpp
Warning:line 131, column 20
Access to field 'NewlinesBefore' results in a dereference of a null pointer (loaded from field 'First')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name AffectedRangeManager.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/build-llvm -resource-dir /usr/lib/llvm-14/lib/clang/14.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/clang/lib/Format -I /build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/clang/lib/Format -I /build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/clang/include -I tools/clang/include -I include -I /build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/llvm/include -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/build-llvm=build-llvm -fmacro-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/build-llvm=build-llvm -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/= -O3 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/build-llvm=build-llvm -fdebug-prefix-map=/build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-01-19-134126-35450-1 -x c++ /build/llvm-toolchain-snapshot-14~++20220119111520+da61cb019eb2/clang/lib/Format/AffectedRangeManager.cpp
1//===--- AffectedRangeManager.cpp - Format C++ code -----------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file implements AffectRangeManager class.
11///
12//===----------------------------------------------------------------------===//
13
14#include "AffectedRangeManager.h"
15
16#include "FormatToken.h"
17#include "TokenAnnotator.h"
18
19namespace clang {
20namespace format {
21
22bool AffectedRangeManager::computeAffectedLines(
23 SmallVectorImpl<AnnotatedLine *> &Lines) {
24 SmallVectorImpl<AnnotatedLine *>::iterator I = Lines.begin();
25 SmallVectorImpl<AnnotatedLine *>::iterator E = Lines.end();
26 bool SomeLineAffected = false;
27 const AnnotatedLine *PreviousLine = nullptr;
28 while (I != E) {
1
Assuming 'I' is not equal to 'E'
2
Loop condition is true. Entering loop body
6
Loop condition is true. Entering loop body
29 AnnotatedLine *Line = *I;
30 Line->LeadingEmptyLinesAffected = affectsLeadingEmptyLines(*Line->First);
31
32 // If a line is part of a preprocessor directive, it needs to be formatted
33 // if any token within the directive is affected.
34 if (Line->InPPDirective) {
3
Assuming field 'InPPDirective' is false
4
Taking false branch
7
Assuming field 'InPPDirective' is false
8
Taking false branch
35 FormatToken *Last = Line->Last;
36 SmallVectorImpl<AnnotatedLine *>::iterator PPEnd = I + 1;
37 while (PPEnd != E && !(*PPEnd)->First->HasUnescapedNewline) {
38 Last = (*PPEnd)->Last;
39 ++PPEnd;
40 }
41
42 if (affectsTokenRange(*Line->First, *Last,
43 /*IncludeLeadingNewlines=*/false)) {
44 SomeLineAffected = true;
45 markAllAsAffected(I, PPEnd);
46 }
47 I = PPEnd;
48 continue;
49 }
50
51 if (nonPPLineAffected(Line, PreviousLine, Lines))
5
Taking false branch
9
Calling 'AffectedRangeManager::nonPPLineAffected'
52 SomeLineAffected = true;
53
54 PreviousLine = Line;
55 ++I;
56 }
57 return SomeLineAffected;
58}
59
60bool AffectedRangeManager::affectsCharSourceRange(
61 const CharSourceRange &Range) {
62 for (const CharSourceRange &R : Ranges)
63 if (!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), R.getBegin()) &&
64 !SourceMgr.isBeforeInTranslationUnit(R.getEnd(), Range.getBegin()))
65 return true;
66 return false;
67}
68
69bool AffectedRangeManager::affectsTokenRange(const FormatToken &First,
70 const FormatToken &Last,
71 bool IncludeLeadingNewlines) {
72 SourceLocation Start = First.WhitespaceRange.getBegin();
73 if (!IncludeLeadingNewlines)
74 Start = Start.getLocWithOffset(First.LastNewlineOffset);
75 SourceLocation End = Last.getStartOfNonWhitespace();
76 End = End.getLocWithOffset(Last.TokenText.size());
77 CharSourceRange Range = CharSourceRange::getCharRange(Start, End);
78 return affectsCharSourceRange(Range);
79}
80
81bool AffectedRangeManager::affectsLeadingEmptyLines(const FormatToken &Tok) {
82 CharSourceRange EmptyLineRange = CharSourceRange::getCharRange(
83 Tok.WhitespaceRange.getBegin(),
84 Tok.WhitespaceRange.getBegin().getLocWithOffset(Tok.LastNewlineOffset));
85 return affectsCharSourceRange(EmptyLineRange);
86}
87
88void AffectedRangeManager::markAllAsAffected(
89 SmallVectorImpl<AnnotatedLine *>::iterator I,
90 SmallVectorImpl<AnnotatedLine *>::iterator E) {
91 while (I != E) {
92 (*I)->Affected = true;
93 markAllAsAffected((*I)->Children.begin(), (*I)->Children.end());
94 ++I;
95 }
96}
97
98bool AffectedRangeManager::nonPPLineAffected(
99 AnnotatedLine *Line, const AnnotatedLine *PreviousLine,
100 SmallVectorImpl<AnnotatedLine *> &Lines) {
101 bool SomeLineAffected = false;
102 Line->ChildrenAffected = computeAffectedLines(Line->Children);
10
Value assigned to field 'First'
103 if (Line->ChildrenAffected)
11
Assuming field 'ChildrenAffected' is false
12
Taking false branch
104 SomeLineAffected = true;
105
106 // Stores whether one of the line's tokens is directly affected.
107 bool SomeTokenAffected = false;
108 // Stores whether we need to look at the leading newlines of the next token
109 // in order to determine whether it was affected.
110 bool IncludeLeadingNewlines = false;
111
112 // Stores whether the first child line of any of this line's tokens is
113 // affected.
114 bool SomeFirstChildAffected = false;
115
116 for (FormatToken *Tok = Line->First; Tok; Tok = Tok->Next) {
13
Assuming pointer value is null
117 // Determine whether 'Tok' was affected.
118 if (affectsTokenRange(*Tok, *Tok, IncludeLeadingNewlines))
119 SomeTokenAffected = true;
120
121 // Determine whether the first child of 'Tok' was affected.
122 if (!Tok->Children.empty() && Tok->Children.front()->Affected)
123 SomeFirstChildAffected = true;
124
125 IncludeLeadingNewlines = Tok->Children.empty();
126 }
127
128 // Was this line moved, i.e. has it previously been on the same line as an
129 // affected line?
130 bool LineMoved = PreviousLine
13.1
'PreviousLine' is non-null
&& PreviousLine->Affected &&
14
Assuming field 'Affected' is true
131 Line->First->NewlinesBefore == 0;
15
Access to field 'NewlinesBefore' results in a dereference of a null pointer (loaded from field 'First')
132
133 bool IsContinuedComment =
134 Line->First->is(tok::comment) && Line->First->Next == nullptr &&
135 Line->First->NewlinesBefore < 2 && PreviousLine &&
136 PreviousLine->Affected && PreviousLine->Last->is(tok::comment);
137
138 bool IsAffectedClosingBrace =
139 Line->First->is(tok::r_brace) &&
140 Line->MatchingOpeningBlockLineIndex != UnwrappedLine::kInvalidIndex &&
141 Lines[Line->MatchingOpeningBlockLineIndex]->Affected;
142
143 if (SomeTokenAffected || SomeFirstChildAffected || LineMoved ||
144 IsContinuedComment || IsAffectedClosingBrace) {
145 Line->Affected = true;
146 SomeLineAffected = true;
147 }
148 return SomeLineAffected;
149}
150
151} // namespace format
152} // namespace clang