Bug Summary

File:tools/clang/lib/Sema/AttributeList.cpp
Warning:line 32, column 3
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name AttributeList.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -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 -mrelocation-model pic -pic-level 2 -mthread-model posix -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn325874/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-7~svn325874/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-7~svn325874/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn325874/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn325874/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn325874/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn325874/build-llvm/tools/clang/lib/Sema -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-02-23-163436-368-1 -x c++ /build/llvm-toolchain-snapshot-7~svn325874/tools/clang/lib/Sema/AttributeList.cpp
1//===- AttributeList.cpp --------------------------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the AttributeList class implementation
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Sema/AttributeList.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/Basic/AttrSubjectMatchRules.h"
17#include "clang/Basic/IdentifierTable.h"
18#include "clang/Basic/TargetInfo.h"
19#include "clang/Sema/SemaInternal.h"
20#include "llvm/ADT/SmallString.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/StringRef.h"
23#include <cassert>
24#include <cstddef>
25#include <utility>
26
27using namespace clang;
28
29IdentifierLoc *IdentifierLoc::create(ASTContext &Ctx, SourceLocation Loc,
30 IdentifierInfo *Ident) {
31 IdentifierLoc *Result = new (Ctx) IdentifierLoc;
1
'Result' initialized to a null pointer value
32 Result->Loc = Loc;
2
Called C++ object pointer is null
33 Result->Ident = Ident;
34 return Result;
35}
36
37size_t AttributeList::allocated_size() const {
38 if (IsAvailability) return AttributeFactory::AvailabilityAllocSize;
39 else if (IsTypeTagForDatatype)
40 return AttributeFactory::TypeTagForDatatypeAllocSize;
41 else if (IsProperty)
42 return AttributeFactory::PropertyAllocSize;
43 return (sizeof(AttributeList) + NumArgs * sizeof(ArgsUnion));
44}
45
46AttributeFactory::AttributeFactory() {
47 // Go ahead and configure all the inline capacity. This is just a memset.
48 FreeLists.resize(InlineFreeListsCapacity);
49}
50AttributeFactory::~AttributeFactory() = default;
51
52static size_t getFreeListIndexForSize(size_t size) {
53 assert(size >= sizeof(AttributeList))(static_cast <bool> (size >= sizeof(AttributeList)) ?
void (0) : __assert_fail ("size >= sizeof(AttributeList)"
, "/build/llvm-toolchain-snapshot-7~svn325874/tools/clang/lib/Sema/AttributeList.cpp"
, 53, __extension__ __PRETTY_FUNCTION__))
;
54 assert((size % sizeof(void*)) == 0)(static_cast <bool> ((size % sizeof(void*)) == 0) ? void
(0) : __assert_fail ("(size % sizeof(void*)) == 0", "/build/llvm-toolchain-snapshot-7~svn325874/tools/clang/lib/Sema/AttributeList.cpp"
, 54, __extension__ __PRETTY_FUNCTION__))
;
55 return ((size - sizeof(AttributeList)) / sizeof(void*));
56}
57
58void *AttributeFactory::allocate(size_t size) {
59 // Check for a previously reclaimed attribute.
60 size_t index = getFreeListIndexForSize(size);
61 if (index < FreeLists.size()) {
62 if (AttributeList *attr = FreeLists[index]) {
63 FreeLists[index] = attr->NextInPool;
64 return attr;
65 }
66 }
67
68 // Otherwise, allocate something new.
69 return Alloc.Allocate(size, alignof(AttributeFactory));
70}
71
72void AttributeFactory::reclaimPool(AttributeList *cur) {
73 assert(cur && "reclaiming empty pool!")(static_cast <bool> (cur && "reclaiming empty pool!"
) ? void (0) : __assert_fail ("cur && \"reclaiming empty pool!\""
, "/build/llvm-toolchain-snapshot-7~svn325874/tools/clang/lib/Sema/AttributeList.cpp"
, 73, __extension__ __PRETTY_FUNCTION__))
;
74 do {
75 // Read this here, because we're going to overwrite NextInPool
76 // when we toss 'cur' into the appropriate queue.
77 AttributeList *next = cur->NextInPool;
78
79 size_t size = cur->allocated_size();
80 size_t freeListIndex = getFreeListIndexForSize(size);
81
82 // Expand FreeLists to the appropriate size, if required.
83 if (freeListIndex >= FreeLists.size())
84 FreeLists.resize(freeListIndex+1);
85
86 // Add 'cur' to the appropriate free-list.
87 cur->NextInPool = FreeLists[freeListIndex];
88 FreeLists[freeListIndex] = cur;
89
90 cur = next;
91 } while (cur);
92}
93
94void AttributePool::takePool(AttributeList *pool) {
95 assert(pool)(static_cast <bool> (pool) ? void (0) : __assert_fail (
"pool", "/build/llvm-toolchain-snapshot-7~svn325874/tools/clang/lib/Sema/AttributeList.cpp"
, 95, __extension__ __PRETTY_FUNCTION__))
;
96
97 // Fast path: this pool is empty.
98 if (!Head) {
99 Head = pool;
100 return;
101 }
102
103 // Reverse the pool onto the current head. This optimizes for the
104 // pattern of pulling a lot of pools into a single pool.
105 do {
106 AttributeList *next = pool->NextInPool;
107 pool->NextInPool = Head;
108 Head = pool;
109 pool = next;
110 } while (pool);
111}
112
113#include "clang/Sema/AttrParsedAttrKinds.inc"
114
115static StringRef normalizeAttrName(StringRef AttrName, StringRef ScopeName,
116 AttributeList::Syntax SyntaxUsed) {
117 // Normalize the attribute name, __foo__ becomes foo. This is only allowable
118 // for GNU attributes.
119 bool IsGNU = SyntaxUsed == AttributeList::AS_GNU ||
120 ((SyntaxUsed == AttributeList::AS_CXX11 ||
121 SyntaxUsed == AttributeList::AS_C2x) && ScopeName == "gnu");
122 if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") &&
123 AttrName.endswith("__"))
124 AttrName = AttrName.slice(2, AttrName.size() - 2);
125
126 return AttrName;
127}
128
129AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name,
130 const IdentifierInfo *ScopeName,
131 Syntax SyntaxUsed) {
132 StringRef AttrName = Name->getName();
133
134 SmallString<64> FullName;
135 if (ScopeName)
136 FullName += ScopeName->getName();
137
138 AttrName = normalizeAttrName(AttrName, FullName, SyntaxUsed);
139
140 // Ensure that in the case of C++11 attributes, we look for '::foo' if it is
141 // unscoped.
142 if (ScopeName || SyntaxUsed == AS_CXX11 || SyntaxUsed == AS_C2x)
143 FullName += "::";
144 FullName += AttrName;
145
146 return ::getAttrKind(FullName, SyntaxUsed);
147}
148
149unsigned AttributeList::getAttributeSpellingListIndex() const {
150 // Both variables will be used in tablegen generated
151 // attribute spell list index matching code.
152 StringRef Scope = ScopeName ? ScopeName->getName() : "";
153 StringRef Name = normalizeAttrName(AttrName->getName(), Scope,
154 (AttributeList::Syntax)SyntaxUsed);
155
156#include "clang/Sema/AttrSpellingListIndex.inc"
157
158}
159
160struct ParsedAttrInfo {
161 unsigned NumArgs : 4;
162 unsigned OptArgs : 4;
163 unsigned HasCustomParsing : 1;
164 unsigned IsTargetSpecific : 1;
165 unsigned IsType : 1;
166 unsigned IsStmt : 1;
167 unsigned IsKnownToGCC : 1;
168 unsigned IsSupportedByPragmaAttribute : 1;
169
170 bool (*DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr,
171 const Decl *);
172 bool (*DiagLangOpts)(Sema &S, const AttributeList &Attr);
173 bool (*ExistsInTarget)(const TargetInfo &Target);
174 unsigned (*SpellingIndexToSemanticSpelling)(const AttributeList &Attr);
175 void (*GetPragmaAttributeMatchRules)(
176 llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
177 const LangOptions &LangOpts);
178};
179
180namespace {
181
182#include "clang/Sema/AttrParsedAttrImpl.inc"
183
184} // namespace
185
186static const ParsedAttrInfo &getInfo(const AttributeList &A) {
187 return AttrInfoMap[A.getKind()];
188}
189
190unsigned AttributeList::getMinArgs() const {
191 return getInfo(*this).NumArgs;
192}
193
194unsigned AttributeList::getMaxArgs() const {
195 return getMinArgs() + getInfo(*this).OptArgs;
196}
197
198bool AttributeList::hasCustomParsing() const {
199 return getInfo(*this).HasCustomParsing;
200}
201
202bool AttributeList::diagnoseAppertainsTo(Sema &S, const Decl *D) const {
203 return getInfo(*this).DiagAppertainsToDecl(S, *this, D);
204}
205
206bool AttributeList::appliesToDecl(const Decl *D,
207 attr::SubjectMatchRule MatchRule) const {
208 return checkAttributeMatchRuleAppliesTo(D, MatchRule);
209}
210
211void AttributeList::getMatchRules(
212 const LangOptions &LangOpts,
213 SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
214 const {
215 return getInfo(*this).GetPragmaAttributeMatchRules(MatchRules, LangOpts);
216}
217
218bool AttributeList::diagnoseLangOpts(Sema &S) const {
219 return getInfo(*this).DiagLangOpts(S, *this);
220}
221
222bool AttributeList::isTargetSpecificAttr() const {
223 return getInfo(*this).IsTargetSpecific;
224}
225
226bool AttributeList::isTypeAttr() const {
227 return getInfo(*this).IsType;
228}
229
230bool AttributeList::isStmtAttr() const {
231 return getInfo(*this).IsStmt;
232}
233
234bool AttributeList::existsInTarget(const TargetInfo &Target) const {
235 return getInfo(*this).ExistsInTarget(Target);
236}
237
238bool AttributeList::isKnownToGCC() const {
239 return getInfo(*this).IsKnownToGCC;
240}
241
242bool AttributeList::isSupportedByPragmaAttribute() const {
243 return getInfo(*this).IsSupportedByPragmaAttribute;
244}
245
246unsigned AttributeList::getSemanticSpelling() const {
247 return getInfo(*this).SpellingIndexToSemanticSpelling(*this);
248}
249
250bool AttributeList::hasVariadicArg() const {
251 // If the attribute has the maximum number of optional arguments, we will
252 // claim that as being variadic. If we someday get an attribute that
253 // legitimately bumps up against that maximum, we can use another bit to track
254 // whether it's truly variadic or not.
255 return getInfo(*this).OptArgs == 15;
256}