Bug Summary

File:tools/clang/lib/Sema/ParsedAttr.cpp
Warning:line 31, 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 ParsedAttr.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 -analyzer-config-compatibility-mode=true -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-9/lib/clang/9.0.0 -D CLANG_VENDOR="Debian " -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-9~svn361465/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-9~svn361465/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-9~svn361465/tools/clang/include -I /build/llvm-toolchain-snapshot-9~svn361465/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-9~svn361465/build-llvm/include -I /build/llvm-toolchain-snapshot-9~svn361465/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/9.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-9/lib/clang/9.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-9~svn361465/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-9~svn361465=. -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -stack-protector 2 -fobjc-runtime=gcc -fno-common -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2019-05-24-031927-21217-1 -x c++ /build/llvm-toolchain-snapshot-9~svn361465/tools/clang/lib/Sema/ParsedAttr.cpp -faddrsig
1//======- ParsedAttr.cpp --------------------------------------------------===//
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// This file defines the ParsedAttr class implementation
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/Sema/ParsedAttr.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/Basic/AttrSubjectMatchRules.h"
16#include "clang/Basic/IdentifierTable.h"
17#include "clang/Basic/TargetInfo.h"
18#include "clang/Sema/SemaInternal.h"
19#include "llvm/ADT/SmallString.h"
20#include "llvm/ADT/SmallVector.h"
21#include "llvm/ADT/StringRef.h"
22#include <cassert>
23#include <cstddef>
24#include <utility>
25
26using namespace clang;
27
28IdentifierLoc *IdentifierLoc::create(ASTContext &Ctx, SourceLocation Loc,
29 IdentifierInfo *Ident) {
30 IdentifierLoc *Result = new (Ctx) IdentifierLoc;
1
'Result' initialized to a null pointer value
31 Result->Loc = Loc;
2
Called C++ object pointer is null
32 Result->Ident = Ident;
33 return Result;
34}
35
36size_t ParsedAttr::allocated_size() const {
37 if (IsAvailability) return AttributeFactory::AvailabilityAllocSize;
38 else if (IsTypeTagForDatatype)
39 return AttributeFactory::TypeTagForDatatypeAllocSize;
40 else if (IsProperty)
41 return AttributeFactory::PropertyAllocSize;
42 else if (HasParsedType)
43 return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
44 detail::TypeTagForDatatypeData, ParsedType,
45 detail::PropertyData>(0, 0, 0, 1, 0);
46 return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
47 detail::TypeTagForDatatypeData, ParsedType,
48 detail::PropertyData>(NumArgs, 0, 0, 0, 0);
49}
50
51AttributeFactory::AttributeFactory() {
52 // Go ahead and configure all the inline capacity. This is just a memset.
53 FreeLists.resize(InlineFreeListsCapacity);
54}
55AttributeFactory::~AttributeFactory() = default;
56
57static size_t getFreeListIndexForSize(size_t size) {
58 assert(size >= sizeof(ParsedAttr))((size >= sizeof(ParsedAttr)) ? static_cast<void> (0
) : __assert_fail ("size >= sizeof(ParsedAttr)", "/build/llvm-toolchain-snapshot-9~svn361465/tools/clang/lib/Sema/ParsedAttr.cpp"
, 58, __PRETTY_FUNCTION__))
;
59 assert((size % sizeof(void*)) == 0)(((size % sizeof(void*)) == 0) ? static_cast<void> (0) :
__assert_fail ("(size % sizeof(void*)) == 0", "/build/llvm-toolchain-snapshot-9~svn361465/tools/clang/lib/Sema/ParsedAttr.cpp"
, 59, __PRETTY_FUNCTION__))
;
60 return ((size - sizeof(ParsedAttr)) / sizeof(void *));
61}
62
63void *AttributeFactory::allocate(size_t size) {
64 // Check for a previously reclaimed attribute.
65 size_t index = getFreeListIndexForSize(size);
66 if (index < FreeLists.size() && !FreeLists[index].empty()) {
67 ParsedAttr *attr = FreeLists[index].back();
68 FreeLists[index].pop_back();
69 return attr;
70 }
71
72 // Otherwise, allocate something new.
73 return Alloc.Allocate(size, alignof(AttributeFactory));
74}
75
76void AttributeFactory::deallocate(ParsedAttr *Attr) {
77 size_t size = Attr->allocated_size();
78 size_t freeListIndex = getFreeListIndexForSize(size);
79
80 // Expand FreeLists to the appropriate size, if required.
81 if (freeListIndex >= FreeLists.size())
82 FreeLists.resize(freeListIndex + 1);
83
84#ifndef NDEBUG
85 // In debug mode, zero out the attribute to help find memory overwriting.
86 memset(Attr, 0, size);
87#endif
88
89 // Add 'Attr' to the appropriate free-list.
90 FreeLists[freeListIndex].push_back(Attr);
91}
92
93void AttributeFactory::reclaimPool(AttributePool &cur) {
94 for (ParsedAttr *AL : cur.Attrs)
95 deallocate(AL);
96}
97
98void AttributePool::takePool(AttributePool &pool) {
99 Attrs.insert(Attrs.end(), pool.Attrs.begin(), pool.Attrs.end());
100 pool.Attrs.clear();
101}
102
103#include "clang/Sema/AttrParsedAttrKinds.inc"
104
105static StringRef normalizeAttrScopeName(StringRef ScopeName,
106 ParsedAttr::Syntax SyntaxUsed) {
107 // Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name
108 // to be "clang".
109 if (SyntaxUsed == ParsedAttr::AS_CXX11 ||
110 SyntaxUsed == ParsedAttr::AS_C2x) {
111 if (ScopeName == "__gnu__")
112 ScopeName = "gnu";
113 else if (ScopeName == "_Clang")
114 ScopeName = "clang";
115 }
116 return ScopeName;
117}
118
119static StringRef normalizeAttrName(StringRef AttrName,
120 StringRef NormalizedScopeName,
121 ParsedAttr::Syntax SyntaxUsed) {
122 // Normalize the attribute name, __foo__ becomes foo. This is only allowable
123 // for GNU attributes, and attributes using the double square bracket syntax.
124 bool ShouldNormalize =
125 SyntaxUsed == ParsedAttr::AS_GNU ||
126 ((SyntaxUsed == ParsedAttr::AS_CXX11 ||
127 SyntaxUsed == ParsedAttr::AS_C2x) &&
128 (NormalizedScopeName == "gnu" || NormalizedScopeName == "clang"));
129 if (ShouldNormalize && AttrName.size() >= 4 && AttrName.startswith("__") &&
130 AttrName.endswith("__"))
131 AttrName = AttrName.slice(2, AttrName.size() - 2);
132
133 return AttrName;
134}
135
136ParsedAttr::Kind ParsedAttr::getKind(const IdentifierInfo *Name,
137 const IdentifierInfo *ScopeName,
138 Syntax SyntaxUsed) {
139 StringRef AttrName = Name->getName();
140
141 SmallString<64> FullName;
142 if (ScopeName)
143 FullName += normalizeAttrScopeName(ScopeName->getName(), SyntaxUsed);
144
145 AttrName = normalizeAttrName(AttrName, FullName, SyntaxUsed);
146
147 // Ensure that in the case of C++11 attributes, we look for '::foo' if it is
148 // unscoped.
149 if (ScopeName || SyntaxUsed == AS_CXX11 || SyntaxUsed == AS_C2x)
150 FullName += "::";
151 FullName += AttrName;
152
153 return ::getAttrKind(FullName, SyntaxUsed);
154}
155
156unsigned ParsedAttr::getAttributeSpellingListIndex() const {
157 // Both variables will be used in tablegen generated
158 // attribute spell list index matching code.
159 auto Syntax = static_cast<ParsedAttr::Syntax>(SyntaxUsed);
160 StringRef Scope =
161 ScopeName ? normalizeAttrScopeName(ScopeName->getName(), Syntax) : "";
162 StringRef Name = normalizeAttrName(AttrName->getName(), Scope, Syntax);
163
164#include "clang/Sema/AttrSpellingListIndex.inc"
165
166}
167
168struct ParsedAttrInfo {
169 unsigned NumArgs : 4;
170 unsigned OptArgs : 4;
171 unsigned HasCustomParsing : 1;
172 unsigned IsTargetSpecific : 1;
173 unsigned IsType : 1;
174 unsigned IsStmt : 1;
175 unsigned IsKnownToGCC : 1;
176 unsigned IsSupportedByPragmaAttribute : 1;
177
178 bool (*DiagAppertainsToDecl)(Sema &S, const ParsedAttr &Attr, const Decl *);
179 bool (*DiagLangOpts)(Sema &S, const ParsedAttr &Attr);
180 bool (*ExistsInTarget)(const TargetInfo &Target);
181 unsigned (*SpellingIndexToSemanticSpelling)(const ParsedAttr &Attr);
182 void (*GetPragmaAttributeMatchRules)(
183 llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
184 const LangOptions &LangOpts);
185};
186
187namespace {
188
189#include "clang/Sema/AttrParsedAttrImpl.inc"
190
191} // namespace
192
193static const ParsedAttrInfo &getInfo(const ParsedAttr &A) {
194 return AttrInfoMap[A.getKind()];
195}
196
197unsigned ParsedAttr::getMinArgs() const { return getInfo(*this).NumArgs; }
198
199unsigned ParsedAttr::getMaxArgs() const {
200 return getMinArgs() + getInfo(*this).OptArgs;
201}
202
203bool ParsedAttr::hasCustomParsing() const {
204 return getInfo(*this).HasCustomParsing;
205}
206
207bool ParsedAttr::diagnoseAppertainsTo(Sema &S, const Decl *D) const {
208 return getInfo(*this).DiagAppertainsToDecl(S, *this, D);
209}
210
211bool ParsedAttr::appliesToDecl(const Decl *D,
212 attr::SubjectMatchRule MatchRule) const {
213 return checkAttributeMatchRuleAppliesTo(D, MatchRule);
214}
215
216void ParsedAttr::getMatchRules(
217 const LangOptions &LangOpts,
218 SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
219 const {
220 return getInfo(*this).GetPragmaAttributeMatchRules(MatchRules, LangOpts);
221}
222
223bool ParsedAttr::diagnoseLangOpts(Sema &S) const {
224 return getInfo(*this).DiagLangOpts(S, *this);
225}
226
227bool ParsedAttr::isTargetSpecificAttr() const {
228 return getInfo(*this).IsTargetSpecific;
229}
230
231bool ParsedAttr::isTypeAttr() const { return getInfo(*this).IsType; }
232
233bool ParsedAttr::isStmtAttr() const { return getInfo(*this).IsStmt; }
234
235bool ParsedAttr::existsInTarget(const TargetInfo &Target) const {
236 return getInfo(*this).ExistsInTarget(Target);
237}
238
239bool ParsedAttr::isKnownToGCC() const { return getInfo(*this).IsKnownToGCC; }
240
241bool ParsedAttr::isSupportedByPragmaAttribute() const {
242 return getInfo(*this).IsSupportedByPragmaAttribute;
243}
244
245unsigned ParsedAttr::getSemanticSpelling() const {
246 return getInfo(*this).SpellingIndexToSemanticSpelling(*this);
247}
248
249bool ParsedAttr::hasVariadicArg() const {
250 // If the attribute has the maximum number of optional arguments, we will
251 // claim that as being variadic. If we someday get an attribute that
252 // legitimately bumps up against that maximum, we can use another bit to track
253 // whether it's truly variadic or not.
254 return getInfo(*this).OptArgs == 15;
255}