Bug Summary

File:clang/lib/Sema/SemaDeclAttr.cpp
Warning:line 5876, column 24
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SemaDeclAttr.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 -fhalf-no-semantic-interposition -mframe-pointer=none -relaxed-aliasing -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/build-llvm/tools/clang/lib/Sema -resource-dir /usr/lib/llvm-13/lib/clang/13.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/build-llvm/tools/clang/lib/Sema -I /build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema -I /build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/include -I /build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/build-llvm/tools/clang/include -I /build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/build-llvm/include -I /build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/llvm/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/local/include -internal-isystem /usr/lib/llvm-13/lib/clang/13.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++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/build-llvm/tools/clang/lib/Sema -fdebug-prefix-map=/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c=. -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2021-03-08-182450-10039-1 -x c++ /build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp
1//===--- SemaDeclAttr.cpp - Declaration Attribute Handling ----------------===//
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 implements decl-related attribute processing.
10//
11//===----------------------------------------------------------------------===//
12
13#include "clang/AST/ASTConsumer.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/ASTMutationListener.h"
16#include "clang/AST/CXXInheritance.h"
17#include "clang/AST/DeclCXX.h"
18#include "clang/AST/DeclObjC.h"
19#include "clang/AST/DeclTemplate.h"
20#include "clang/AST/Expr.h"
21#include "clang/AST/ExprCXX.h"
22#include "clang/AST/Mangle.h"
23#include "clang/AST/RecursiveASTVisitor.h"
24#include "clang/AST/Type.h"
25#include "clang/Basic/CharInfo.h"
26#include "clang/Basic/SourceLocation.h"
27#include "clang/Basic/SourceManager.h"
28#include "clang/Basic/TargetBuiltins.h"
29#include "clang/Basic/TargetInfo.h"
30#include "clang/Lex/Preprocessor.h"
31#include "clang/Sema/DeclSpec.h"
32#include "clang/Sema/DelayedDiagnostic.h"
33#include "clang/Sema/Initialization.h"
34#include "clang/Sema/Lookup.h"
35#include "clang/Sema/ParsedAttr.h"
36#include "clang/Sema/Scope.h"
37#include "clang/Sema/ScopeInfo.h"
38#include "clang/Sema/SemaInternal.h"
39#include "llvm/ADT/Optional.h"
40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/StringExtras.h"
42#include "llvm/IR/Assumptions.h"
43#include "llvm/Support/Error.h"
44#include "llvm/Support/MathExtras.h"
45#include "llvm/Support/raw_ostream.h"
46
47using namespace clang;
48using namespace sema;
49
50namespace AttributeLangSupport {
51 enum LANG {
52 C,
53 Cpp,
54 ObjC
55 };
56} // end namespace AttributeLangSupport
57
58//===----------------------------------------------------------------------===//
59// Helper functions
60//===----------------------------------------------------------------------===//
61
62/// isFunctionOrMethod - Return true if the given decl has function
63/// type (function or function-typed variable) or an Objective-C
64/// method.
65static bool isFunctionOrMethod(const Decl *D) {
66 return (D->getFunctionType() != nullptr) || isa<ObjCMethodDecl>(D);
67}
68
69/// Return true if the given decl has function type (function or
70/// function-typed variable) or an Objective-C method or a block.
71static bool isFunctionOrMethodOrBlock(const Decl *D) {
72 return isFunctionOrMethod(D) || isa<BlockDecl>(D);
73}
74
75/// Return true if the given decl has a declarator that should have
76/// been processed by Sema::GetTypeForDeclarator.
77static bool hasDeclarator(const Decl *D) {
78 // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
79 return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) || isa<TypedefNameDecl>(D) ||
80 isa<ObjCPropertyDecl>(D);
81}
82
83/// hasFunctionProto - Return true if the given decl has a argument
84/// information. This decl should have already passed
85/// isFunctionOrMethod or isFunctionOrMethodOrBlock.
86static bool hasFunctionProto(const Decl *D) {
87 if (const FunctionType *FnTy = D->getFunctionType())
88 return isa<FunctionProtoType>(FnTy);
89 return isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D);
90}
91
92/// getFunctionOrMethodNumParams - Return number of function or method
93/// parameters. It is an error to call this on a K&R function (use
94/// hasFunctionProto first).
95static unsigned getFunctionOrMethodNumParams(const Decl *D) {
96 if (const FunctionType *FnTy = D->getFunctionType())
97 return cast<FunctionProtoType>(FnTy)->getNumParams();
98 if (const auto *BD = dyn_cast<BlockDecl>(D))
99 return BD->getNumParams();
100 return cast<ObjCMethodDecl>(D)->param_size();
101}
102
103static const ParmVarDecl *getFunctionOrMethodParam(const Decl *D,
104 unsigned Idx) {
105 if (const auto *FD = dyn_cast<FunctionDecl>(D))
106 return FD->getParamDecl(Idx);
107 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
108 return MD->getParamDecl(Idx);
109 if (const auto *BD = dyn_cast<BlockDecl>(D))
110 return BD->getParamDecl(Idx);
111 return nullptr;
112}
113
114static QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) {
115 if (const FunctionType *FnTy = D->getFunctionType())
116 return cast<FunctionProtoType>(FnTy)->getParamType(Idx);
117 if (const auto *BD = dyn_cast<BlockDecl>(D))
118 return BD->getParamDecl(Idx)->getType();
119
120 return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType();
121}
122
123static SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx) {
124 if (auto *PVD = getFunctionOrMethodParam(D, Idx))
125 return PVD->getSourceRange();
126 return SourceRange();
127}
128
129static QualType getFunctionOrMethodResultType(const Decl *D) {
130 if (const FunctionType *FnTy = D->getFunctionType())
131 return FnTy->getReturnType();
132 return cast<ObjCMethodDecl>(D)->getReturnType();
133}
134
135static SourceRange getFunctionOrMethodResultSourceRange(const Decl *D) {
136 if (const auto *FD = dyn_cast<FunctionDecl>(D))
137 return FD->getReturnTypeSourceRange();
138 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
139 return MD->getReturnTypeSourceRange();
140 return SourceRange();
141}
142
143static bool isFunctionOrMethodVariadic(const Decl *D) {
144 if (const FunctionType *FnTy = D->getFunctionType())
145 return cast<FunctionProtoType>(FnTy)->isVariadic();
146 if (const auto *BD = dyn_cast<BlockDecl>(D))
147 return BD->isVariadic();
148 return cast<ObjCMethodDecl>(D)->isVariadic();
149}
150
151static bool isInstanceMethod(const Decl *D) {
152 if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(D))
153 return MethodDecl->isInstance();
154 return false;
155}
156
157static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
158 const auto *PT = T->getAs<ObjCObjectPointerType>();
159 if (!PT)
160 return false;
161
162 ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
163 if (!Cls)
164 return false;
165
166 IdentifierInfo* ClsName = Cls->getIdentifier();
167
168 // FIXME: Should we walk the chain of classes?
169 return ClsName == &Ctx.Idents.get("NSString") ||
170 ClsName == &Ctx.Idents.get("NSMutableString");
171}
172
173static inline bool isCFStringType(QualType T, ASTContext &Ctx) {
174 const auto *PT = T->getAs<PointerType>();
175 if (!PT)
176 return false;
177
178 const auto *RT = PT->getPointeeType()->getAs<RecordType>();
179 if (!RT)
180 return false;
181
182 const RecordDecl *RD = RT->getDecl();
183 if (RD->getTagKind() != TTK_Struct)
184 return false;
185
186 return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
187}
188
189static unsigned getNumAttributeArgs(const ParsedAttr &AL) {
190 // FIXME: Include the type in the argument list.
191 return AL.getNumArgs() + AL.hasParsedType();
192}
193
194template <typename Compare>
195static bool checkAttributeNumArgsImpl(Sema &S, const ParsedAttr &AL,
196 unsigned Num, unsigned Diag,
197 Compare Comp) {
198 if (Comp(getNumAttributeArgs(AL), Num)) {
199 S.Diag(AL.getLoc(), Diag) << AL << Num;
200 return false;
201 }
202
203 return true;
204}
205
206/// Check if the attribute has exactly as many args as Num. May
207/// output an error.
208static bool checkAttributeNumArgs(Sema &S, const ParsedAttr &AL, unsigned Num) {
209 return checkAttributeNumArgsImpl(S, AL, Num,
210 diag::err_attribute_wrong_number_arguments,
211 std::not_equal_to<unsigned>());
212}
213
214/// Check if the attribute has at least as many args as Num. May
215/// output an error.
216static bool checkAttributeAtLeastNumArgs(Sema &S, const ParsedAttr &AL,
217 unsigned Num) {
218 return checkAttributeNumArgsImpl(S, AL, Num,
219 diag::err_attribute_too_few_arguments,
220 std::less<unsigned>());
221}
222
223/// Check if the attribute has at most as many args as Num. May
224/// output an error.
225static bool checkAttributeAtMostNumArgs(Sema &S, const ParsedAttr &AL,
226 unsigned Num) {
227 return checkAttributeNumArgsImpl(S, AL, Num,
228 diag::err_attribute_too_many_arguments,
229 std::greater<unsigned>());
230}
231
232/// A helper function to provide Attribute Location for the Attr types
233/// AND the ParsedAttr.
234template <typename AttrInfo>
235static std::enable_if_t<std::is_base_of<Attr, AttrInfo>::value, SourceLocation>
236getAttrLoc(const AttrInfo &AL) {
237 return AL.getLocation();
238}
239static SourceLocation getAttrLoc(const ParsedAttr &AL) { return AL.getLoc(); }
240
241/// If Expr is a valid integer constant, get the value of the integer
242/// expression and return success or failure. May output an error.
243///
244/// Negative argument is implicitly converted to unsigned, unless
245/// \p StrictlyUnsigned is true.
246template <typename AttrInfo>
247static bool checkUInt32Argument(Sema &S, const AttrInfo &AI, const Expr *Expr,
248 uint32_t &Val, unsigned Idx = UINT_MAX(2147483647 *2U +1U),
249 bool StrictlyUnsigned = false) {
250 Optional<llvm::APSInt> I = llvm::APSInt(32);
251 if (Expr->isTypeDependent() || Expr->isValueDependent() ||
252 !(I = Expr->getIntegerConstantExpr(S.Context))) {
253 if (Idx != UINT_MAX(2147483647 *2U +1U))
254 S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
255 << &AI << Idx << AANT_ArgumentIntegerConstant
256 << Expr->getSourceRange();
257 else
258 S.Diag(getAttrLoc(AI), diag::err_attribute_argument_type)
259 << &AI << AANT_ArgumentIntegerConstant << Expr->getSourceRange();
260 return false;
261 }
262
263 if (!I->isIntN(32)) {
264 S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
265 << I->toString(10, false) << 32 << /* Unsigned */ 1;
266 return false;
267 }
268
269 if (StrictlyUnsigned && I->isSigned() && I->isNegative()) {
270 S.Diag(getAttrLoc(AI), diag::err_attribute_requires_positive_integer)
271 << &AI << /*non-negative*/ 1;
272 return false;
273 }
274
275 Val = (uint32_t)I->getZExtValue();
276 return true;
277}
278
279/// Wrapper around checkUInt32Argument, with an extra check to be sure
280/// that the result will fit into a regular (signed) int. All args have the same
281/// purpose as they do in checkUInt32Argument.
282template <typename AttrInfo>
283static bool checkPositiveIntArgument(Sema &S, const AttrInfo &AI, const Expr *Expr,
284 int &Val, unsigned Idx = UINT_MAX(2147483647 *2U +1U)) {
285 uint32_t UVal;
286 if (!checkUInt32Argument(S, AI, Expr, UVal, Idx))
287 return false;
288
289 if (UVal > (uint32_t)std::numeric_limits<int>::max()) {
290 llvm::APSInt I(32); // for toString
291 I = UVal;
292 S.Diag(Expr->getExprLoc(), diag::err_ice_too_large)
293 << I.toString(10, false) << 32 << /* Unsigned */ 0;
294 return false;
295 }
296
297 Val = UVal;
298 return true;
299}
300
301/// Diagnose mutually exclusive attributes when present on a given
302/// declaration. Returns true if diagnosed.
303template <typename AttrTy>
304static bool checkAttrMutualExclusion(Sema &S, Decl *D, const ParsedAttr &AL) {
305 if (const auto *A = D->getAttr<AttrTy>()) {
306 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << A;
307 S.Diag(A->getLocation(), diag::note_conflicting_attribute);
308 return true;
309 }
310 return false;
311}
312
313template <typename AttrTy>
314static bool checkAttrMutualExclusion(Sema &S, Decl *D, const Attr &AL) {
315 if (const auto *A = D->getAttr<AttrTy>()) {
316 S.Diag(AL.getLocation(), diag::err_attributes_are_not_compatible) << &AL
317 << A;
318 S.Diag(A->getLocation(), diag::note_conflicting_attribute);
319 return true;
320 }
321 return false;
322}
323
324/// Check if IdxExpr is a valid parameter index for a function or
325/// instance method D. May output an error.
326///
327/// \returns true if IdxExpr is a valid index.
328template <typename AttrInfo>
329static bool checkFunctionOrMethodParameterIndex(
330 Sema &S, const Decl *D, const AttrInfo &AI, unsigned AttrArgNum,
331 const Expr *IdxExpr, ParamIdx &Idx, bool CanIndexImplicitThis = false) {
332 assert(isFunctionOrMethodOrBlock(D))((isFunctionOrMethodOrBlock(D)) ? static_cast<void> (0)
: __assert_fail ("isFunctionOrMethodOrBlock(D)", "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 332, __PRETTY_FUNCTION__))
;
333
334 // In C++ the implicit 'this' function parameter also counts.
335 // Parameters are counted from one.
336 bool HP = hasFunctionProto(D);
337 bool HasImplicitThisParam = isInstanceMethod(D);
338 bool IV = HP && isFunctionOrMethodVariadic(D);
339 unsigned NumParams =
340 (HP ? getFunctionOrMethodNumParams(D) : 0) + HasImplicitThisParam;
341
342 Optional<llvm::APSInt> IdxInt;
343 if (IdxExpr->isTypeDependent() || IdxExpr->isValueDependent() ||
344 !(IdxInt = IdxExpr->getIntegerConstantExpr(S.Context))) {
345 S.Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type)
346 << &AI << AttrArgNum << AANT_ArgumentIntegerConstant
347 << IdxExpr->getSourceRange();
348 return false;
349 }
350
351 unsigned IdxSource = IdxInt->getLimitedValue(UINT_MAX(2147483647 *2U +1U));
352 if (IdxSource < 1 || (!IV && IdxSource > NumParams)) {
353 S.Diag(getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds)
354 << &AI << AttrArgNum << IdxExpr->getSourceRange();
355 return false;
356 }
357 if (HasImplicitThisParam && !CanIndexImplicitThis) {
358 if (IdxSource == 1) {
359 S.Diag(getAttrLoc(AI), diag::err_attribute_invalid_implicit_this_argument)
360 << &AI << IdxExpr->getSourceRange();
361 return false;
362 }
363 }
364
365 Idx = ParamIdx(IdxSource, D);
366 return true;
367}
368
369/// Check if the argument \p ArgNum of \p Attr is a ASCII string literal.
370/// If not emit an error and return false. If the argument is an identifier it
371/// will emit an error with a fixit hint and treat it as if it was a string
372/// literal.
373bool Sema::checkStringLiteralArgumentAttr(const ParsedAttr &AL, unsigned ArgNum,
374 StringRef &Str,
375 SourceLocation *ArgLocation) {
376 // Look for identifiers. If we have one emit a hint to fix it to a literal.
377 if (AL.isArgIdent(ArgNum)) {
378 IdentifierLoc *Loc = AL.getArgAsIdent(ArgNum);
379 Diag(Loc->Loc, diag::err_attribute_argument_type)
380 << AL << AANT_ArgumentString
381 << FixItHint::CreateInsertion(Loc->Loc, "\"")
382 << FixItHint::CreateInsertion(getLocForEndOfToken(Loc->Loc), "\"");
383 Str = Loc->Ident->getName();
384 if (ArgLocation)
385 *ArgLocation = Loc->Loc;
386 return true;
387 }
388
389 // Now check for an actual string literal.
390 Expr *ArgExpr = AL.getArgAsExpr(ArgNum);
391 const auto *Literal = dyn_cast<StringLiteral>(ArgExpr->IgnoreParenCasts());
392 if (ArgLocation)
393 *ArgLocation = ArgExpr->getBeginLoc();
394
395 if (!Literal || !Literal->isAscii()) {
396 Diag(ArgExpr->getBeginLoc(), diag::err_attribute_argument_type)
397 << AL << AANT_ArgumentString;
398 return false;
399 }
400
401 Str = Literal->getString();
402 return true;
403}
404
405/// Applies the given attribute to the Decl without performing any
406/// additional semantic checking.
407template <typename AttrType>
408static void handleSimpleAttribute(Sema &S, Decl *D,
409 const AttributeCommonInfo &CI) {
410 D->addAttr(::new (S.Context) AttrType(S.Context, CI));
411}
412
413template <typename... DiagnosticArgs>
414static const Sema::SemaDiagnosticBuilder&
415appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr) {
416 return Bldr;
417}
418
419template <typename T, typename... DiagnosticArgs>
420static const Sema::SemaDiagnosticBuilder&
421appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr, T &&ExtraArg,
422 DiagnosticArgs &&... ExtraArgs) {
423 return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
424 std::forward<DiagnosticArgs>(ExtraArgs)...);
425}
426
427/// Add an attribute {@code AttrType} to declaration {@code D}, provided that
428/// {@code PassesCheck} is true.
429/// Otherwise, emit diagnostic {@code DiagID}, passing in all parameters
430/// specified in {@code ExtraArgs}.
431template <typename AttrType, typename... DiagnosticArgs>
432static void handleSimpleAttributeOrDiagnose(Sema &S, Decl *D,
433 const AttributeCommonInfo &CI,
434 bool PassesCheck, unsigned DiagID,
435 DiagnosticArgs &&... ExtraArgs) {
436 if (!PassesCheck) {
437 Sema::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
438 appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
439 return;
440 }
441 handleSimpleAttribute<AttrType>(S, D, CI);
442}
443
444template <typename AttrType>
445static void handleSimpleAttributeWithExclusions(Sema &S, Decl *D,
446 const ParsedAttr &AL) {
447 handleSimpleAttribute<AttrType>(S, D, AL);
448}
449
450/// Applies the given attribute to the Decl so long as the Decl doesn't
451/// already have one of the given incompatible attributes.
452template <typename AttrType, typename IncompatibleAttrType,
453 typename... IncompatibleAttrTypes>
454static void handleSimpleAttributeWithExclusions(Sema &S, Decl *D,
455 const ParsedAttr &AL) {
456 if (checkAttrMutualExclusion<IncompatibleAttrType>(S, D, AL))
457 return;
458 handleSimpleAttributeWithExclusions<AttrType, IncompatibleAttrTypes...>(S, D,
459 AL);
460}
461
462/// Check if the passed-in expression is of type int or bool.
463static bool isIntOrBool(Expr *Exp) {
464 QualType QT = Exp->getType();
465 return QT->isBooleanType() || QT->isIntegerType();
466}
467
468
469// Check to see if the type is a smart pointer of some kind. We assume
470// it's a smart pointer if it defines both operator-> and operator*.
471static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
472 auto IsOverloadedOperatorPresent = [&S](const RecordDecl *Record,
473 OverloadedOperatorKind Op) {
474 DeclContextLookupResult Result =
475 Record->lookup(S.Context.DeclarationNames.getCXXOperatorName(Op));
476 return !Result.empty();
477 };
478
479 const RecordDecl *Record = RT->getDecl();
480 bool foundStarOperator = IsOverloadedOperatorPresent(Record, OO_Star);
481 bool foundArrowOperator = IsOverloadedOperatorPresent(Record, OO_Arrow);
482 if (foundStarOperator && foundArrowOperator)
483 return true;
484
485 const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record);
486 if (!CXXRecord)
487 return false;
488
489 for (auto BaseSpecifier : CXXRecord->bases()) {
490 if (!foundStarOperator)
491 foundStarOperator = IsOverloadedOperatorPresent(
492 BaseSpecifier.getType()->getAsRecordDecl(), OO_Star);
493 if (!foundArrowOperator)
494 foundArrowOperator = IsOverloadedOperatorPresent(
495 BaseSpecifier.getType()->getAsRecordDecl(), OO_Arrow);
496 }
497
498 if (foundStarOperator && foundArrowOperator)
499 return true;
500
501 return false;
502}
503
504/// Check if passed in Decl is a pointer type.
505/// Note that this function may produce an error message.
506/// \return true if the Decl is a pointer type; false otherwise
507static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
508 const ParsedAttr &AL) {
509 const auto *VD = cast<ValueDecl>(D);
510 QualType QT = VD->getType();
511 if (QT->isAnyPointerType())
512 return true;
513
514 if (const auto *RT = QT->getAs<RecordType>()) {
515 // If it's an incomplete type, it could be a smart pointer; skip it.
516 // (We don't want to force template instantiation if we can avoid it,
517 // since that would alter the order in which templates are instantiated.)
518 if (RT->isIncompleteType())
519 return true;
520
521 if (threadSafetyCheckIsSmartPointer(S, RT))
522 return true;
523 }
524
525 S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_pointer) << AL << QT;
526 return false;
527}
528
529/// Checks that the passed in QualType either is of RecordType or points
530/// to RecordType. Returns the relevant RecordType, null if it does not exit.
531static const RecordType *getRecordType(QualType QT) {
532 if (const auto *RT = QT->getAs<RecordType>())
533 return RT;
534
535 // Now check if we point to record type.
536 if (const auto *PT = QT->getAs<PointerType>())
537 return PT->getPointeeType()->getAs<RecordType>();
538
539 return nullptr;
540}
541
542template <typename AttrType>
543static bool checkRecordDeclForAttr(const RecordDecl *RD) {
544 // Check if the record itself has the attribute.
545 if (RD->hasAttr<AttrType>())
546 return true;
547
548 // Else check if any base classes have the attribute.
549 if (const auto *CRD = dyn_cast<CXXRecordDecl>(RD)) {
550 CXXBasePaths BPaths(false, false);
551 if (CRD->lookupInBases(
552 [](const CXXBaseSpecifier *BS, CXXBasePath &) {
553 const auto &Ty = *BS->getType();
554 // If it's type-dependent, we assume it could have the attribute.
555 if (Ty.isDependentType())
556 return true;
557 return Ty.castAs<RecordType>()->getDecl()->hasAttr<AttrType>();
558 },
559 BPaths, true))
560 return true;
561 }
562 return false;
563}
564
565static bool checkRecordTypeForCapability(Sema &S, QualType Ty) {
566 const RecordType *RT = getRecordType(Ty);
567
568 if (!RT)
569 return false;
570
571 // Don't check for the capability if the class hasn't been defined yet.
572 if (RT->isIncompleteType())
573 return true;
574
575 // Allow smart pointers to be used as capability objects.
576 // FIXME -- Check the type that the smart pointer points to.
577 if (threadSafetyCheckIsSmartPointer(S, RT))
578 return true;
579
580 return checkRecordDeclForAttr<CapabilityAttr>(RT->getDecl());
581}
582
583static bool checkTypedefTypeForCapability(QualType Ty) {
584 const auto *TD = Ty->getAs<TypedefType>();
585 if (!TD)
586 return false;
587
588 TypedefNameDecl *TN = TD->getDecl();
589 if (!TN)
590 return false;
591
592 return TN->hasAttr<CapabilityAttr>();
593}
594
595static bool typeHasCapability(Sema &S, QualType Ty) {
596 if (checkTypedefTypeForCapability(Ty))
597 return true;
598
599 if (checkRecordTypeForCapability(S, Ty))
600 return true;
601
602 return false;
603}
604
605static bool isCapabilityExpr(Sema &S, const Expr *Ex) {
606 // Capability expressions are simple expressions involving the boolean logic
607 // operators &&, || or !, a simple DeclRefExpr, CastExpr or a ParenExpr. Once
608 // a DeclRefExpr is found, its type should be checked to determine whether it
609 // is a capability or not.
610
611 if (const auto *E = dyn_cast<CastExpr>(Ex))
612 return isCapabilityExpr(S, E->getSubExpr());
613 else if (const auto *E = dyn_cast<ParenExpr>(Ex))
614 return isCapabilityExpr(S, E->getSubExpr());
615 else if (const auto *E = dyn_cast<UnaryOperator>(Ex)) {
616 if (E->getOpcode() == UO_LNot || E->getOpcode() == UO_AddrOf ||
617 E->getOpcode() == UO_Deref)
618 return isCapabilityExpr(S, E->getSubExpr());
619 return false;
620 } else if (const auto *E = dyn_cast<BinaryOperator>(Ex)) {
621 if (E->getOpcode() == BO_LAnd || E->getOpcode() == BO_LOr)
622 return isCapabilityExpr(S, E->getLHS()) &&
623 isCapabilityExpr(S, E->getRHS());
624 return false;
625 }
626
627 return typeHasCapability(S, Ex->getType());
628}
629
630/// Checks that all attribute arguments, starting from Sidx, resolve to
631/// a capability object.
632/// \param Sidx The attribute argument index to start checking with.
633/// \param ParamIdxOk Whether an argument can be indexing into a function
634/// parameter list.
635static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
636 const ParsedAttr &AL,
637 SmallVectorImpl<Expr *> &Args,
638 unsigned Sidx = 0,
639 bool ParamIdxOk = false) {
640 if (Sidx == AL.getNumArgs()) {
641 // If we don't have any capability arguments, the attribute implicitly
642 // refers to 'this'. So we need to make sure that 'this' exists, i.e. we're
643 // a non-static method, and that the class is a (scoped) capability.
644 const auto *MD = dyn_cast<const CXXMethodDecl>(D);
645 if (MD && !MD->isStatic()) {
646 const CXXRecordDecl *RD = MD->getParent();
647 // FIXME -- need to check this again on template instantiation
648 if (!checkRecordDeclForAttr<CapabilityAttr>(RD) &&
649 !checkRecordDeclForAttr<ScopedLockableAttr>(RD))
650 S.Diag(AL.getLoc(),
651 diag::warn_thread_attribute_not_on_capability_member)
652 << AL << MD->getParent();
653 } else {
654 S.Diag(AL.getLoc(), diag::warn_thread_attribute_not_on_non_static_member)
655 << AL;
656 }
657 }
658
659 for (unsigned Idx = Sidx; Idx < AL.getNumArgs(); ++Idx) {
660 Expr *ArgExp = AL.getArgAsExpr(Idx);
661
662 if (ArgExp->isTypeDependent()) {
663 // FIXME -- need to check this again on template instantiation
664 Args.push_back(ArgExp);
665 continue;
666 }
667
668 if (const auto *StrLit = dyn_cast<StringLiteral>(ArgExp)) {
669 if (StrLit->getLength() == 0 ||
670 (StrLit->isAscii() && StrLit->getString() == StringRef("*"))) {
671 // Pass empty strings to the analyzer without warnings.
672 // Treat "*" as the universal lock.
673 Args.push_back(ArgExp);
674 continue;
675 }
676
677 // We allow constant strings to be used as a placeholder for expressions
678 // that are not valid C++ syntax, but warn that they are ignored.
679 S.Diag(AL.getLoc(), diag::warn_thread_attribute_ignored) << AL;
680 Args.push_back(ArgExp);
681 continue;
682 }
683
684 QualType ArgTy = ArgExp->getType();
685
686 // A pointer to member expression of the form &MyClass::mu is treated
687 // specially -- we need to look at the type of the member.
688 if (const auto *UOp = dyn_cast<UnaryOperator>(ArgExp))
689 if (UOp->getOpcode() == UO_AddrOf)
690 if (const auto *DRE = dyn_cast<DeclRefExpr>(UOp->getSubExpr()))
691 if (DRE->getDecl()->isCXXInstanceMember())
692 ArgTy = DRE->getDecl()->getType();
693
694 // First see if we can just cast to record type, or pointer to record type.
695 const RecordType *RT = getRecordType(ArgTy);
696
697 // Now check if we index into a record type function param.
698 if(!RT && ParamIdxOk) {
699 const auto *FD = dyn_cast<FunctionDecl>(D);
700 const auto *IL = dyn_cast<IntegerLiteral>(ArgExp);
701 if(FD && IL) {
702 unsigned int NumParams = FD->getNumParams();
703 llvm::APInt ArgValue = IL->getValue();
704 uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
705 uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
706 if (!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
707 S.Diag(AL.getLoc(),
708 diag::err_attribute_argument_out_of_bounds_extra_info)
709 << AL << Idx + 1 << NumParams;
710 continue;
711 }
712 ArgTy = FD->getParamDecl(ParamIdxFromZero)->getType();
713 }
714 }
715
716 // If the type does not have a capability, see if the components of the
717 // expression have capabilities. This allows for writing C code where the
718 // capability may be on the type, and the expression is a capability
719 // boolean logic expression. Eg) requires_capability(A || B && !C)
720 if (!typeHasCapability(S, ArgTy) && !isCapabilityExpr(S, ArgExp))
721 S.Diag(AL.getLoc(), diag::warn_thread_attribute_argument_not_lockable)
722 << AL << ArgTy;
723
724 Args.push_back(ArgExp);
725 }
726}
727
728//===----------------------------------------------------------------------===//
729// Attribute Implementations
730//===----------------------------------------------------------------------===//
731
732static void handlePtGuardedVarAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
733 if (!threadSafetyCheckIsPointer(S, D, AL))
734 return;
735
736 D->addAttr(::new (S.Context) PtGuardedVarAttr(S.Context, AL));
737}
738
739static bool checkGuardedByAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
740 Expr *&Arg) {
741 SmallVector<Expr *, 1> Args;
742 // check that all arguments are lockable objects
743 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
744 unsigned Size = Args.size();
745 if (Size != 1)
746 return false;
747
748 Arg = Args[0];
749
750 return true;
751}
752
753static void handleGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
754 Expr *Arg = nullptr;
755 if (!checkGuardedByAttrCommon(S, D, AL, Arg))
756 return;
757
758 D->addAttr(::new (S.Context) GuardedByAttr(S.Context, AL, Arg));
759}
760
761static void handlePtGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
762 Expr *Arg = nullptr;
763 if (!checkGuardedByAttrCommon(S, D, AL, Arg))
764 return;
765
766 if (!threadSafetyCheckIsPointer(S, D, AL))
767 return;
768
769 D->addAttr(::new (S.Context) PtGuardedByAttr(S.Context, AL, Arg));
770}
771
772static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
773 SmallVectorImpl<Expr *> &Args) {
774 if (!checkAttributeAtLeastNumArgs(S, AL, 1))
775 return false;
776
777 // Check that this attribute only applies to lockable types.
778 QualType QT = cast<ValueDecl>(D)->getType();
779 if (!QT->isDependentType() && !typeHasCapability(S, QT)) {
780 S.Diag(AL.getLoc(), diag::warn_thread_attribute_decl_not_lockable) << AL;
781 return false;
782 }
783
784 // Check that all arguments are lockable objects.
785 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
786 if (Args.empty())
787 return false;
788
789 return true;
790}
791
792static void handleAcquiredAfterAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
793 SmallVector<Expr *, 1> Args;
794 if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
795 return;
796
797 Expr **StartArg = &Args[0];
798 D->addAttr(::new (S.Context)
799 AcquiredAfterAttr(S.Context, AL, StartArg, Args.size()));
800}
801
802static void handleAcquiredBeforeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
803 SmallVector<Expr *, 1> Args;
804 if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
805 return;
806
807 Expr **StartArg = &Args[0];
808 D->addAttr(::new (S.Context)
809 AcquiredBeforeAttr(S.Context, AL, StartArg, Args.size()));
810}
811
812static bool checkLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
813 SmallVectorImpl<Expr *> &Args) {
814 // zero or more arguments ok
815 // check that all arguments are lockable objects
816 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 0, /*ParamIdxOk=*/true);
817
818 return true;
819}
820
821static void handleAssertSharedLockAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
822 SmallVector<Expr *, 1> Args;
823 if (!checkLockFunAttrCommon(S, D, AL, Args))
824 return;
825
826 unsigned Size = Args.size();
827 Expr **StartArg = Size == 0 ? nullptr : &Args[0];
828 D->addAttr(::new (S.Context)
829 AssertSharedLockAttr(S.Context, AL, StartArg, Size));
830}
831
832static void handleAssertExclusiveLockAttr(Sema &S, Decl *D,
833 const ParsedAttr &AL) {
834 SmallVector<Expr *, 1> Args;
835 if (!checkLockFunAttrCommon(S, D, AL, Args))
836 return;
837
838 unsigned Size = Args.size();
839 Expr **StartArg = Size == 0 ? nullptr : &Args[0];
840 D->addAttr(::new (S.Context)
841 AssertExclusiveLockAttr(S.Context, AL, StartArg, Size));
842}
843
844/// Checks to be sure that the given parameter number is in bounds, and
845/// is an integral type. Will emit appropriate diagnostics if this returns
846/// false.
847///
848/// AttrArgNo is used to actually retrieve the argument, so it's base-0.
849template <typename AttrInfo>
850static bool checkParamIsIntegerType(Sema &S, const FunctionDecl *FD,
851 const AttrInfo &AI, unsigned AttrArgNo) {
852 assert(AI.isArgExpr(AttrArgNo) && "Expected expression argument")((AI.isArgExpr(AttrArgNo) && "Expected expression argument"
) ? static_cast<void> (0) : __assert_fail ("AI.isArgExpr(AttrArgNo) && \"Expected expression argument\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 852, __PRETTY_FUNCTION__))
;
853 Expr *AttrArg = AI.getArgAsExpr(AttrArgNo);
854 ParamIdx Idx;
855 if (!checkFunctionOrMethodParameterIndex(S, FD, AI, AttrArgNo + 1, AttrArg,
856 Idx))
857 return false;
858
859 const ParmVarDecl *Param = FD->getParamDecl(Idx.getASTIndex());
860 if (!Param->getType()->isIntegerType() && !Param->getType()->isCharType()) {
861 SourceLocation SrcLoc = AttrArg->getBeginLoc();
862 S.Diag(SrcLoc, diag::err_attribute_integers_only)
863 << AI << Param->getSourceRange();
864 return false;
865 }
866 return true;
867}
868
869static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
870 if (!checkAttributeAtLeastNumArgs(S, AL, 1) ||
871 !checkAttributeAtMostNumArgs(S, AL, 2))
872 return;
873
874 const auto *FD = cast<FunctionDecl>(D);
875 if (!FD->getReturnType()->isPointerType()) {
876 S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only) << AL;
877 return;
878 }
879
880 const Expr *SizeExpr = AL.getArgAsExpr(0);
881 int SizeArgNoVal;
882 // Parameter indices are 1-indexed, hence Index=1
883 if (!checkPositiveIntArgument(S, AL, SizeExpr, SizeArgNoVal, /*Idx=*/1))
884 return;
885 if (!checkParamIsIntegerType(S, FD, AL, /*AttrArgNo=*/0))
886 return;
887 ParamIdx SizeArgNo(SizeArgNoVal, D);
888
889 ParamIdx NumberArgNo;
890 if (AL.getNumArgs() == 2) {
891 const Expr *NumberExpr = AL.getArgAsExpr(1);
892 int Val;
893 // Parameter indices are 1-based, hence Index=2
894 if (!checkPositiveIntArgument(S, AL, NumberExpr, Val, /*Idx=*/2))
895 return;
896 if (!checkParamIsIntegerType(S, FD, AL, /*AttrArgNo=*/1))
897 return;
898 NumberArgNo = ParamIdx(Val, D);
899 }
900
901 D->addAttr(::new (S.Context)
902 AllocSizeAttr(S.Context, AL, SizeArgNo, NumberArgNo));
903}
904
905static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
906 SmallVectorImpl<Expr *> &Args) {
907 if (!checkAttributeAtLeastNumArgs(S, AL, 1))
908 return false;
909
910 if (!isIntOrBool(AL.getArgAsExpr(0))) {
911 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
912 << AL << 1 << AANT_ArgumentIntOrBool;
913 return false;
914 }
915
916 // check that all arguments are lockable objects
917 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, 1);
918
919 return true;
920}
921
922static void handleSharedTrylockFunctionAttr(Sema &S, Decl *D,
923 const ParsedAttr &AL) {
924 SmallVector<Expr*, 2> Args;
925 if (!checkTryLockFunAttrCommon(S, D, AL, Args))
926 return;
927
928 D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(
929 S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
930}
931
932static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
933 const ParsedAttr &AL) {
934 SmallVector<Expr*, 2> Args;
935 if (!checkTryLockFunAttrCommon(S, D, AL, Args))
936 return;
937
938 D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(
939 S.Context, AL, AL.getArgAsExpr(0), Args.data(), Args.size()));
940}
941
942static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
943 // check that the argument is lockable object
944 SmallVector<Expr*, 1> Args;
945 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
946 unsigned Size = Args.size();
947 if (Size == 0)
948 return;
949
950 D->addAttr(::new (S.Context) LockReturnedAttr(S.Context, AL, Args[0]));
951}
952
953static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
954 if (!checkAttributeAtLeastNumArgs(S, AL, 1))
955 return;
956
957 // check that all arguments are lockable objects
958 SmallVector<Expr*, 1> Args;
959 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
960 unsigned Size = Args.size();
961 if (Size == 0)
962 return;
963 Expr **StartArg = &Args[0];
964
965 D->addAttr(::new (S.Context)
966 LocksExcludedAttr(S.Context, AL, StartArg, Size));
967}
968
969static bool checkFunctionConditionAttr(Sema &S, Decl *D, const ParsedAttr &AL,
970 Expr *&Cond, StringRef &Msg) {
971 Cond = AL.getArgAsExpr(0);
972 if (!Cond->isTypeDependent()) {
973 ExprResult Converted = S.PerformContextuallyConvertToBool(Cond);
974 if (Converted.isInvalid())
975 return false;
976 Cond = Converted.get();
977 }
978
979 if (!S.checkStringLiteralArgumentAttr(AL, 1, Msg))
980 return false;
981
982 if (Msg.empty())
983 Msg = "<no message provided>";
984
985 SmallVector<PartialDiagnosticAt, 8> Diags;
986 if (isa<FunctionDecl>(D) && !Cond->isValueDependent() &&
987 !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(D),
988 Diags)) {
989 S.Diag(AL.getLoc(), diag::err_attr_cond_never_constant_expr) << AL;
990 for (const PartialDiagnosticAt &PDiag : Diags)
991 S.Diag(PDiag.first, PDiag.second);
992 return false;
993 }
994 return true;
995}
996
997static void handleEnableIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
998 S.Diag(AL.getLoc(), diag::ext_clang_enable_if);
999
1000 Expr *Cond;
1001 StringRef Msg;
1002 if (checkFunctionConditionAttr(S, D, AL, Cond, Msg))
1003 D->addAttr(::new (S.Context) EnableIfAttr(S.Context, AL, Cond, Msg));
1004}
1005
1006namespace {
1007/// Determines if a given Expr references any of the given function's
1008/// ParmVarDecls, or the function's implicit `this` parameter (if applicable).
1009class ArgumentDependenceChecker
1010 : public RecursiveASTVisitor<ArgumentDependenceChecker> {
1011#ifndef NDEBUG
1012 const CXXRecordDecl *ClassType;
1013#endif
1014 llvm::SmallPtrSet<const ParmVarDecl *, 16> Parms;
1015 bool Result;
1016
1017public:
1018 ArgumentDependenceChecker(const FunctionDecl *FD) {
1019#ifndef NDEBUG
1020 if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
1021 ClassType = MD->getParent();
1022 else
1023 ClassType = nullptr;
1024#endif
1025 Parms.insert(FD->param_begin(), FD->param_end());
1026 }
1027
1028 bool referencesArgs(Expr *E) {
1029 Result = false;
1030 TraverseStmt(E);
1031 return Result;
1032 }
1033
1034 bool VisitCXXThisExpr(CXXThisExpr *E) {
1035 assert(E->getType()->getPointeeCXXRecordDecl() == ClassType &&((E->getType()->getPointeeCXXRecordDecl() == ClassType &&
"`this` doesn't refer to the enclosing class?") ? static_cast
<void> (0) : __assert_fail ("E->getType()->getPointeeCXXRecordDecl() == ClassType && \"`this` doesn't refer to the enclosing class?\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 1036, __PRETTY_FUNCTION__))
1036 "`this` doesn't refer to the enclosing class?")((E->getType()->getPointeeCXXRecordDecl() == ClassType &&
"`this` doesn't refer to the enclosing class?") ? static_cast
<void> (0) : __assert_fail ("E->getType()->getPointeeCXXRecordDecl() == ClassType && \"`this` doesn't refer to the enclosing class?\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 1036, __PRETTY_FUNCTION__))
;
1037 Result = true;
1038 return false;
1039 }
1040
1041 bool VisitDeclRefExpr(DeclRefExpr *DRE) {
1042 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
1043 if (Parms.count(PVD)) {
1044 Result = true;
1045 return false;
1046 }
1047 return true;
1048 }
1049};
1050}
1051
1052static void handleDiagnoseIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1053 S.Diag(AL.getLoc(), diag::ext_clang_diagnose_if);
1054
1055 Expr *Cond;
1056 StringRef Msg;
1057 if (!checkFunctionConditionAttr(S, D, AL, Cond, Msg))
1058 return;
1059
1060 StringRef DiagTypeStr;
1061 if (!S.checkStringLiteralArgumentAttr(AL, 2, DiagTypeStr))
1062 return;
1063
1064 DiagnoseIfAttr::DiagnosticType DiagType;
1065 if (!DiagnoseIfAttr::ConvertStrToDiagnosticType(DiagTypeStr, DiagType)) {
1066 S.Diag(AL.getArgAsExpr(2)->getBeginLoc(),
1067 diag::err_diagnose_if_invalid_diagnostic_type);
1068 return;
1069 }
1070
1071 bool ArgDependent = false;
1072 if (const auto *FD = dyn_cast<FunctionDecl>(D))
1073 ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond);
1074 D->addAttr(::new (S.Context) DiagnoseIfAttr(
1075 S.Context, AL, Cond, Msg, DiagType, ArgDependent, cast<NamedDecl>(D)));
1076}
1077
1078static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1079 static constexpr const StringRef kWildcard = "*";
1080
1081 llvm::SmallVector<StringRef, 16> Names;
1082 bool HasWildcard = false;
1083
1084 const auto AddBuiltinName = [&Names, &HasWildcard](StringRef Name) {
1085 if (Name == kWildcard)
1086 HasWildcard = true;
1087 Names.push_back(Name);
1088 };
1089
1090 // Add previously defined attributes.
1091 if (const auto *NBA = D->getAttr<NoBuiltinAttr>())
1092 for (StringRef BuiltinName : NBA->builtinNames())
1093 AddBuiltinName(BuiltinName);
1094
1095 // Add current attributes.
1096 if (AL.getNumArgs() == 0)
1097 AddBuiltinName(kWildcard);
1098 else
1099 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
1100 StringRef BuiltinName;
1101 SourceLocation LiteralLoc;
1102 if (!S.checkStringLiteralArgumentAttr(AL, I, BuiltinName, &LiteralLoc))
1103 return;
1104
1105 if (Builtin::Context::isBuiltinFunc(BuiltinName))
1106 AddBuiltinName(BuiltinName);
1107 else
1108 S.Diag(LiteralLoc, diag::warn_attribute_no_builtin_invalid_builtin_name)
1109 << BuiltinName << AL;
1110 }
1111
1112 // Repeating the same attribute is fine.
1113 llvm::sort(Names);
1114 Names.erase(std::unique(Names.begin(), Names.end()), Names.end());
1115
1116 // Empty no_builtin must be on its own.
1117 if (HasWildcard && Names.size() > 1)
1118 S.Diag(D->getLocation(),
1119 diag::err_attribute_no_builtin_wildcard_or_builtin_name)
1120 << AL;
1121
1122 if (D->hasAttr<NoBuiltinAttr>())
1123 D->dropAttr<NoBuiltinAttr>();
1124 D->addAttr(::new (S.Context)
1125 NoBuiltinAttr(S.Context, AL, Names.data(), Names.size()));
1126}
1127
1128static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1129 if (D->hasAttr<PassObjectSizeAttr>()) {
1130 S.Diag(D->getBeginLoc(), diag::err_attribute_only_once_per_parameter) << AL;
1131 return;
1132 }
1133
1134 Expr *E = AL.getArgAsExpr(0);
1135 uint32_t Type;
1136 if (!checkUInt32Argument(S, AL, E, Type, /*Idx=*/1))
1137 return;
1138
1139 // pass_object_size's argument is passed in as the second argument of
1140 // __builtin_object_size. So, it has the same constraints as that second
1141 // argument; namely, it must be in the range [0, 3].
1142 if (Type > 3) {
1143 S.Diag(E->getBeginLoc(), diag::err_attribute_argument_out_of_range)
1144 << AL << 0 << 3 << E->getSourceRange();
1145 return;
1146 }
1147
1148 // pass_object_size is only supported on constant pointer parameters; as a
1149 // kindness to users, we allow the parameter to be non-const for declarations.
1150 // At this point, we have no clue if `D` belongs to a function declaration or
1151 // definition, so we defer the constness check until later.
1152 if (!cast<ParmVarDecl>(D)->getType()->isPointerType()) {
1153 S.Diag(D->getBeginLoc(), diag::err_attribute_pointers_only) << AL << 1;
1154 return;
1155 }
1156
1157 D->addAttr(::new (S.Context) PassObjectSizeAttr(S.Context, AL, (int)Type));
1158}
1159
1160static void handleConsumableAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1161 ConsumableAttr::ConsumedState DefaultState;
1162
1163 if (AL.isArgIdent(0)) {
1164 IdentifierLoc *IL = AL.getArgAsIdent(0);
1165 if (!ConsumableAttr::ConvertStrToConsumedState(IL->Ident->getName(),
1166 DefaultState)) {
1167 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL
1168 << IL->Ident;
1169 return;
1170 }
1171 } else {
1172 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1173 << AL << AANT_ArgumentIdentifier;
1174 return;
1175 }
1176
1177 D->addAttr(::new (S.Context) ConsumableAttr(S.Context, AL, DefaultState));
1178}
1179
1180static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD,
1181 const ParsedAttr &AL) {
1182 QualType ThisType = MD->getThisType()->getPointeeType();
1183
1184 if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {
1185 if (!RD->hasAttr<ConsumableAttr>()) {
1186 S.Diag(AL.getLoc(), diag::warn_attr_on_unconsumable_class) << RD;
1187
1188 return false;
1189 }
1190 }
1191
1192 return true;
1193}
1194
1195static void handleCallableWhenAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1196 if (!checkAttributeAtLeastNumArgs(S, AL, 1))
1197 return;
1198
1199 if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
1200 return;
1201
1202 SmallVector<CallableWhenAttr::ConsumedState, 3> States;
1203 for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); ++ArgIndex) {
1204 CallableWhenAttr::ConsumedState CallableState;
1205
1206 StringRef StateString;
1207 SourceLocation Loc;
1208 if (AL.isArgIdent(ArgIndex)) {
1209 IdentifierLoc *Ident = AL.getArgAsIdent(ArgIndex);
1210 StateString = Ident->Ident->getName();
1211 Loc = Ident->Loc;
1212 } else {
1213 if (!S.checkStringLiteralArgumentAttr(AL, ArgIndex, StateString, &Loc))
1214 return;
1215 }
1216
1217 if (!CallableWhenAttr::ConvertStrToConsumedState(StateString,
1218 CallableState)) {
1219 S.Diag(Loc, diag::warn_attribute_type_not_supported) << AL << StateString;
1220 return;
1221 }
1222
1223 States.push_back(CallableState);
1224 }
1225
1226 D->addAttr(::new (S.Context)
1227 CallableWhenAttr(S.Context, AL, States.data(), States.size()));
1228}
1229
1230static void handleParamTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1231 ParamTypestateAttr::ConsumedState ParamState;
1232
1233 if (AL.isArgIdent(0)) {
1234 IdentifierLoc *Ident = AL.getArgAsIdent(0);
1235 StringRef StateString = Ident->Ident->getName();
1236
1237 if (!ParamTypestateAttr::ConvertStrToConsumedState(StateString,
1238 ParamState)) {
1239 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported)
1240 << AL << StateString;
1241 return;
1242 }
1243 } else {
1244 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1245 << AL << AANT_ArgumentIdentifier;
1246 return;
1247 }
1248
1249 // FIXME: This check is currently being done in the analysis. It can be
1250 // enabled here only after the parser propagates attributes at
1251 // template specialization definition, not declaration.
1252 //QualType ReturnType = cast<ParmVarDecl>(D)->getType();
1253 //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1254 //
1255 //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1256 // S.Diag(AL.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1257 // ReturnType.getAsString();
1258 // return;
1259 //}
1260
1261 D->addAttr(::new (S.Context) ParamTypestateAttr(S.Context, AL, ParamState));
1262}
1263
1264static void handleReturnTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1265 ReturnTypestateAttr::ConsumedState ReturnState;
1266
1267 if (AL.isArgIdent(0)) {
1268 IdentifierLoc *IL = AL.getArgAsIdent(0);
1269 if (!ReturnTypestateAttr::ConvertStrToConsumedState(IL->Ident->getName(),
1270 ReturnState)) {
1271 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL
1272 << IL->Ident;
1273 return;
1274 }
1275 } else {
1276 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1277 << AL << AANT_ArgumentIdentifier;
1278 return;
1279 }
1280
1281 // FIXME: This check is currently being done in the analysis. It can be
1282 // enabled here only after the parser propagates attributes at
1283 // template specialization definition, not declaration.
1284 //QualType ReturnType;
1285 //
1286 //if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) {
1287 // ReturnType = Param->getType();
1288 //
1289 //} else if (const CXXConstructorDecl *Constructor =
1290 // dyn_cast<CXXConstructorDecl>(D)) {
1291 // ReturnType = Constructor->getThisType()->getPointeeType();
1292 //
1293 //} else {
1294 //
1295 // ReturnType = cast<FunctionDecl>(D)->getCallResultType();
1296 //}
1297 //
1298 //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1299 //
1300 //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1301 // S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1302 // ReturnType.getAsString();
1303 // return;
1304 //}
1305
1306 D->addAttr(::new (S.Context) ReturnTypestateAttr(S.Context, AL, ReturnState));
1307}
1308
1309static void handleSetTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1310 if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
1311 return;
1312
1313 SetTypestateAttr::ConsumedState NewState;
1314 if (AL.isArgIdent(0)) {
1315 IdentifierLoc *Ident = AL.getArgAsIdent(0);
1316 StringRef Param = Ident->Ident->getName();
1317 if (!SetTypestateAttr::ConvertStrToConsumedState(Param, NewState)) {
1318 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) << AL
1319 << Param;
1320 return;
1321 }
1322 } else {
1323 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1324 << AL << AANT_ArgumentIdentifier;
1325 return;
1326 }
1327
1328 D->addAttr(::new (S.Context) SetTypestateAttr(S.Context, AL, NewState));
1329}
1330
1331static void handleTestTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1332 if (!checkForConsumableClass(S, cast<CXXMethodDecl>(D), AL))
1333 return;
1334
1335 TestTypestateAttr::ConsumedState TestState;
1336 if (AL.isArgIdent(0)) {
1337 IdentifierLoc *Ident = AL.getArgAsIdent(0);
1338 StringRef Param = Ident->Ident->getName();
1339 if (!TestTypestateAttr::ConvertStrToConsumedState(Param, TestState)) {
1340 S.Diag(Ident->Loc, diag::warn_attribute_type_not_supported) << AL
1341 << Param;
1342 return;
1343 }
1344 } else {
1345 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
1346 << AL << AANT_ArgumentIdentifier;
1347 return;
1348 }
1349
1350 D->addAttr(::new (S.Context) TestTypestateAttr(S.Context, AL, TestState));
1351}
1352
1353static void handleExtVectorTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1354 // Remember this typedef decl, we will need it later for diagnostics.
1355 S.ExtVectorDecls.push_back(cast<TypedefNameDecl>(D));
1356}
1357
1358static void handlePackedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1359 if (auto *TD = dyn_cast<TagDecl>(D))
1360 TD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1361 else if (auto *FD = dyn_cast<FieldDecl>(D)) {
1362 bool BitfieldByteAligned = (!FD->getType()->isDependentType() &&
1363 !FD->getType()->isIncompleteType() &&
1364 FD->isBitField() &&
1365 S.Context.getTypeAlign(FD->getType()) <= 8);
1366
1367 if (S.getASTContext().getTargetInfo().getTriple().isPS4()) {
1368 if (BitfieldByteAligned)
1369 // The PS4 target needs to maintain ABI backwards compatibility.
1370 S.Diag(AL.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
1371 << AL << FD->getType();
1372 else
1373 FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1374 } else {
1375 // Report warning about changed offset in the newer compiler versions.
1376 if (BitfieldByteAligned)
1377 S.Diag(AL.getLoc(), diag::warn_attribute_packed_for_bitfield);
1378
1379 FD->addAttr(::new (S.Context) PackedAttr(S.Context, AL));
1380 }
1381
1382 } else
1383 S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
1384}
1385
1386static void handlePreferredName(Sema &S, Decl *D, const ParsedAttr &AL) {
1387 auto *RD = cast<CXXRecordDecl>(D);
1388 ClassTemplateDecl *CTD = RD->getDescribedClassTemplate();
1389 assert(CTD && "attribute does not appertain to this declaration")((CTD && "attribute does not appertain to this declaration"
) ? static_cast<void> (0) : __assert_fail ("CTD && \"attribute does not appertain to this declaration\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 1389, __PRETTY_FUNCTION__))
;
1390
1391 ParsedType PT = AL.getTypeArg();
1392 TypeSourceInfo *TSI = nullptr;
1393 QualType T = S.GetTypeFromParser(PT, &TSI);
1394 if (!TSI)
1395 TSI = S.Context.getTrivialTypeSourceInfo(T, AL.getLoc());
1396
1397 if (!T.hasQualifiers() && T->isTypedefNameType()) {
1398 // Find the template name, if this type names a template specialization.
1399 const TemplateDecl *Template = nullptr;
1400 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
1401 T->getAsCXXRecordDecl())) {
1402 Template = CTSD->getSpecializedTemplate();
1403 } else if (const auto *TST = T->getAs<TemplateSpecializationType>()) {
1404 while (TST && TST->isTypeAlias())
1405 TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
1406 if (TST)
1407 Template = TST->getTemplateName().getAsTemplateDecl();
1408 }
1409
1410 if (Template && declaresSameEntity(Template, CTD)) {
1411 D->addAttr(::new (S.Context) PreferredNameAttr(S.Context, AL, TSI));
1412 return;
1413 }
1414 }
1415
1416 S.Diag(AL.getLoc(), diag::err_attribute_preferred_name_arg_invalid)
1417 << T << CTD;
1418 if (const auto *TT = T->getAs<TypedefType>())
1419 S.Diag(TT->getDecl()->getLocation(), diag::note_entity_declared_at)
1420 << TT->getDecl();
1421}
1422
1423static bool checkIBOutletCommon(Sema &S, Decl *D, const ParsedAttr &AL) {
1424 // The IBOutlet/IBOutletCollection attributes only apply to instance
1425 // variables or properties of Objective-C classes. The outlet must also
1426 // have an object reference type.
1427 if (const auto *VD = dyn_cast<ObjCIvarDecl>(D)) {
1428 if (!VD->getType()->getAs<ObjCObjectPointerType>()) {
1429 S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type)
1430 << AL << VD->getType() << 0;
1431 return false;
1432 }
1433 }
1434 else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) {
1435 if (!PD->getType()->getAs<ObjCObjectPointerType>()) {
1436 S.Diag(AL.getLoc(), diag::warn_iboutlet_object_type)
1437 << AL << PD->getType() << 1;
1438 return false;
1439 }
1440 }
1441 else {
1442 S.Diag(AL.getLoc(), diag::warn_attribute_iboutlet) << AL;
1443 return false;
1444 }
1445
1446 return true;
1447}
1448
1449static void handleIBOutlet(Sema &S, Decl *D, const ParsedAttr &AL) {
1450 if (!checkIBOutletCommon(S, D, AL))
1451 return;
1452
1453 D->addAttr(::new (S.Context) IBOutletAttr(S.Context, AL));
1454}
1455
1456static void handleIBOutletCollection(Sema &S, Decl *D, const ParsedAttr &AL) {
1457
1458 // The iboutletcollection attribute can have zero or one arguments.
1459 if (AL.getNumArgs() > 1) {
1460 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1461 return;
1462 }
1463
1464 if (!checkIBOutletCommon(S, D, AL))
1465 return;
1466
1467 ParsedType PT;
1468
1469 if (AL.hasParsedType())
1470 PT = AL.getTypeArg();
1471 else {
1472 PT = S.getTypeName(S.Context.Idents.get("NSObject"), AL.getLoc(),
1473 S.getScopeForContext(D->getDeclContext()->getParent()));
1474 if (!PT) {
1475 S.Diag(AL.getLoc(), diag::err_iboutletcollection_type) << "NSObject";
1476 return;
1477 }
1478 }
1479
1480 TypeSourceInfo *QTLoc = nullptr;
1481 QualType QT = S.GetTypeFromParser(PT, &QTLoc);
1482 if (!QTLoc)
1483 QTLoc = S.Context.getTrivialTypeSourceInfo(QT, AL.getLoc());
1484
1485 // Diagnose use of non-object type in iboutletcollection attribute.
1486 // FIXME. Gnu attribute extension ignores use of builtin types in
1487 // attributes. So, __attribute__((iboutletcollection(char))) will be
1488 // treated as __attribute__((iboutletcollection())).
1489 if (!QT->isObjCIdType() && !QT->isObjCObjectType()) {
1490 S.Diag(AL.getLoc(),
1491 QT->isBuiltinType() ? diag::err_iboutletcollection_builtintype
1492 : diag::err_iboutletcollection_type) << QT;
1493 return;
1494 }
1495
1496 D->addAttr(::new (S.Context) IBOutletCollectionAttr(S.Context, AL, QTLoc));
1497}
1498
1499bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) {
1500 if (RefOkay) {
1501 if (T->isReferenceType())
1502 return true;
1503 } else {
1504 T = T.getNonReferenceType();
1505 }
1506
1507 // The nonnull attribute, and other similar attributes, can be applied to a
1508 // transparent union that contains a pointer type.
1509 if (const RecordType *UT = T->getAsUnionType()) {
1510 if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
1511 RecordDecl *UD = UT->getDecl();
1512 for (const auto *I : UD->fields()) {
1513 QualType QT = I->getType();
1514 if (QT->isAnyPointerType() || QT->isBlockPointerType())
1515 return true;
1516 }
1517 }
1518 }
1519
1520 return T->isAnyPointerType() || T->isBlockPointerType();
1521}
1522
1523static bool attrNonNullArgCheck(Sema &S, QualType T, const ParsedAttr &AL,
1524 SourceRange AttrParmRange,
1525 SourceRange TypeRange,
1526 bool isReturnValue = false) {
1527 if (!S.isValidPointerAttrType(T)) {
1528 if (isReturnValue)
1529 S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
1530 << AL << AttrParmRange << TypeRange;
1531 else
1532 S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)
1533 << AL << AttrParmRange << TypeRange << 0;
1534 return false;
1535 }
1536 return true;
1537}
1538
1539static void handleNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1540 SmallVector<ParamIdx, 8> NonNullArgs;
1541 for (unsigned I = 0; I < AL.getNumArgs(); ++I) {
1542 Expr *Ex = AL.getArgAsExpr(I);
1543 ParamIdx Idx;
1544 if (!checkFunctionOrMethodParameterIndex(S, D, AL, I + 1, Ex, Idx))
1545 return;
1546
1547 // Is the function argument a pointer type?
1548 if (Idx.getASTIndex() < getFunctionOrMethodNumParams(D) &&
1549 !attrNonNullArgCheck(
1550 S, getFunctionOrMethodParamType(D, Idx.getASTIndex()), AL,
1551 Ex->getSourceRange(),
1552 getFunctionOrMethodParamRange(D, Idx.getASTIndex())))
1553 continue;
1554
1555 NonNullArgs.push_back(Idx);
1556 }
1557
1558 // If no arguments were specified to __attribute__((nonnull)) then all pointer
1559 // arguments have a nonnull attribute; warn if there aren't any. Skip this
1560 // check if the attribute came from a macro expansion or a template
1561 // instantiation.
1562 if (NonNullArgs.empty() && AL.getLoc().isFileID() &&
1563 !S.inTemplateInstantiation()) {
1564 bool AnyPointers = isFunctionOrMethodVariadic(D);
1565 for (unsigned I = 0, E = getFunctionOrMethodNumParams(D);
1566 I != E && !AnyPointers; ++I) {
1567 QualType T = getFunctionOrMethodParamType(D, I);
1568 if (T->isDependentType() || S.isValidPointerAttrType(T))
1569 AnyPointers = true;
1570 }
1571
1572 if (!AnyPointers)
1573 S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_no_pointers);
1574 }
1575
1576 ParamIdx *Start = NonNullArgs.data();
1577 unsigned Size = NonNullArgs.size();
1578 llvm::array_pod_sort(Start, Start + Size);
1579 D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, Start, Size));
1580}
1581
1582static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D,
1583 const ParsedAttr &AL) {
1584 if (AL.getNumArgs() > 0) {
1585 if (D->getFunctionType()) {
1586 handleNonNullAttr(S, D, AL);
1587 } else {
1588 S.Diag(AL.getLoc(), diag::warn_attribute_nonnull_parm_no_args)
1589 << D->getSourceRange();
1590 }
1591 return;
1592 }
1593
1594 // Is the argument a pointer type?
1595 if (!attrNonNullArgCheck(S, D->getType(), AL, SourceRange(),
1596 D->getSourceRange()))
1597 return;
1598
1599 D->addAttr(::new (S.Context) NonNullAttr(S.Context, AL, nullptr, 0));
1600}
1601
1602static void handleReturnsNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1603 QualType ResultType = getFunctionOrMethodResultType(D);
1604 SourceRange SR = getFunctionOrMethodResultSourceRange(D);
1605 if (!attrNonNullArgCheck(S, ResultType, AL, SourceRange(), SR,
1606 /* isReturnValue */ true))
1607 return;
1608
1609 D->addAttr(::new (S.Context) ReturnsNonNullAttr(S.Context, AL));
1610}
1611
1612static void handleNoEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1613 if (D->isInvalidDecl())
1614 return;
1615
1616 // noescape only applies to pointer types.
1617 QualType T = cast<ParmVarDecl>(D)->getType();
1618 if (!S.isValidPointerAttrType(T, /* RefOkay */ true)) {
1619 S.Diag(AL.getLoc(), diag::warn_attribute_pointers_only)
1620 << AL << AL.getRange() << 0;
1621 return;
1622 }
1623
1624 D->addAttr(::new (S.Context) NoEscapeAttr(S.Context, AL));
1625}
1626
1627static void handleAssumeAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1628 Expr *E = AL.getArgAsExpr(0),
1629 *OE = AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr;
1630 S.AddAssumeAlignedAttr(D, AL, E, OE);
1631}
1632
1633static void handleAllocAlignAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1634 S.AddAllocAlignAttr(D, AL, AL.getArgAsExpr(0));
1635}
1636
1637void Sema::AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
1638 Expr *OE) {
1639 QualType ResultType = getFunctionOrMethodResultType(D);
1640 SourceRange SR = getFunctionOrMethodResultSourceRange(D);
1641
1642 AssumeAlignedAttr TmpAttr(Context, CI, E, OE);
1643 SourceLocation AttrLoc = TmpAttr.getLocation();
1644
1645 if (!isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
1646 Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1647 << &TmpAttr << TmpAttr.getRange() << SR;
1648 return;
1649 }
1650
1651 if (!E->isValueDependent()) {
1652 Optional<llvm::APSInt> I = llvm::APSInt(64);
1653 if (!(I = E->getIntegerConstantExpr(Context))) {
1654 if (OE)
1655 Diag(AttrLoc, diag::err_attribute_argument_n_type)
1656 << &TmpAttr << 1 << AANT_ArgumentIntegerConstant
1657 << E->getSourceRange();
1658 else
1659 Diag(AttrLoc, diag::err_attribute_argument_type)
1660 << &TmpAttr << AANT_ArgumentIntegerConstant
1661 << E->getSourceRange();
1662 return;
1663 }
1664
1665 if (!I->isPowerOf2()) {
1666 Diag(AttrLoc, diag::err_alignment_not_power_of_two)
1667 << E->getSourceRange();
1668 return;
1669 }
1670
1671 if (*I > Sema::MaximumAlignment)
1672 Diag(CI.getLoc(), diag::warn_assume_aligned_too_great)
1673 << CI.getRange() << Sema::MaximumAlignment;
1674 }
1675
1676 if (OE && !OE->isValueDependent() && !OE->isIntegerConstantExpr(Context)) {
1677 Diag(AttrLoc, diag::err_attribute_argument_n_type)
1678 << &TmpAttr << 2 << AANT_ArgumentIntegerConstant
1679 << OE->getSourceRange();
1680 return;
1681 }
1682
1683 D->addAttr(::new (Context) AssumeAlignedAttr(Context, CI, E, OE));
1684}
1685
1686void Sema::AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI,
1687 Expr *ParamExpr) {
1688 QualType ResultType = getFunctionOrMethodResultType(D);
1689
1690 AllocAlignAttr TmpAttr(Context, CI, ParamIdx());
1691 SourceLocation AttrLoc = CI.getLoc();
1692
1693 if (!ResultType->isDependentType() &&
1694 !isValidPointerAttrType(ResultType, /* RefOkay */ true)) {
1695 Diag(AttrLoc, diag::warn_attribute_return_pointers_refs_only)
1696 << &TmpAttr << CI.getRange() << getFunctionOrMethodResultSourceRange(D);
1697 return;
1698 }
1699
1700 ParamIdx Idx;
1701 const auto *FuncDecl = cast<FunctionDecl>(D);
1702 if (!checkFunctionOrMethodParameterIndex(*this, FuncDecl, TmpAttr,
1703 /*AttrArgNum=*/1, ParamExpr, Idx))
1704 return;
1705
1706 QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());
1707 if (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
1708 !Ty->isAlignValT()) {
1709 Diag(ParamExpr->getBeginLoc(), diag::err_attribute_integers_only)
1710 << &TmpAttr
1711 << FuncDecl->getParamDecl(Idx.getASTIndex())->getSourceRange();
1712 return;
1713 }
1714
1715 D->addAttr(::new (Context) AllocAlignAttr(Context, CI, Idx));
1716}
1717
1718/// Check if \p AssumptionStr is a known assumption and warn if not.
1719static void checkAssumptionAttr(Sema &S, SourceLocation Loc,
1720 StringRef AssumptionStr) {
1721 if (llvm::KnownAssumptionStrings.count(AssumptionStr))
1722 return;
1723
1724 unsigned BestEditDistance = 3;
1725 StringRef Suggestion;
1726 for (const auto &KnownAssumptionIt : llvm::KnownAssumptionStrings) {
1727 unsigned EditDistance =
1728 AssumptionStr.edit_distance(KnownAssumptionIt.getKey());
1729 if (EditDistance < BestEditDistance) {
1730 Suggestion = KnownAssumptionIt.getKey();
1731 BestEditDistance = EditDistance;
1732 }
1733 }
1734
1735 if (!Suggestion.empty())
1736 S.Diag(Loc, diag::warn_assume_attribute_string_unknown_suggested)
1737 << AssumptionStr << Suggestion;
1738 else
1739 S.Diag(Loc, diag::warn_assume_attribute_string_unknown) << AssumptionStr;
1740}
1741
1742static void handleAssumumptionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1743 // Handle the case where the attribute has a text message.
1744 StringRef Str;
1745 SourceLocation AttrStrLoc;
1746 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &AttrStrLoc))
1747 return;
1748
1749 checkAssumptionAttr(S, AttrStrLoc, Str);
1750
1751 D->addAttr(::new (S.Context) AssumptionAttr(S.Context, AL, Str));
1752}
1753
1754/// Normalize the attribute, __foo__ becomes foo.
1755/// Returns true if normalization was applied.
1756static bool normalizeName(StringRef &AttrName) {
1757 if (AttrName.size() > 4 && AttrName.startswith("__") &&
1758 AttrName.endswith("__")) {
1759 AttrName = AttrName.drop_front(2).drop_back(2);
1760 return true;
1761 }
1762 return false;
1763}
1764
1765static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1766 // This attribute must be applied to a function declaration. The first
1767 // argument to the attribute must be an identifier, the name of the resource,
1768 // for example: malloc. The following arguments must be argument indexes, the
1769 // arguments must be of integer type for Returns, otherwise of pointer type.
1770 // The difference between Holds and Takes is that a pointer may still be used
1771 // after being held. free() should be __attribute((ownership_takes)), whereas
1772 // a list append function may well be __attribute((ownership_holds)).
1773
1774 if (!AL.isArgIdent(0)) {
1775 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
1776 << AL << 1 << AANT_ArgumentIdentifier;
1777 return;
1778 }
1779
1780 // Figure out our Kind.
1781 OwnershipAttr::OwnershipKind K =
1782 OwnershipAttr(S.Context, AL, nullptr, nullptr, 0).getOwnKind();
1783
1784 // Check arguments.
1785 switch (K) {
1786 case OwnershipAttr::Takes:
1787 case OwnershipAttr::Holds:
1788 if (AL.getNumArgs() < 2) {
1789 S.Diag(AL.getLoc(), diag::err_attribute_too_few_arguments) << AL << 2;
1790 return;
1791 }
1792 break;
1793 case OwnershipAttr::Returns:
1794 if (AL.getNumArgs() > 2) {
1795 S.Diag(AL.getLoc(), diag::err_attribute_too_many_arguments) << AL << 1;
1796 return;
1797 }
1798 break;
1799 }
1800
1801 IdentifierInfo *Module = AL.getArgAsIdent(0)->Ident;
1802
1803 StringRef ModuleName = Module->getName();
1804 if (normalizeName(ModuleName)) {
1805 Module = &S.PP.getIdentifierTable().get(ModuleName);
1806 }
1807
1808 SmallVector<ParamIdx, 8> OwnershipArgs;
1809 for (unsigned i = 1; i < AL.getNumArgs(); ++i) {
1810 Expr *Ex = AL.getArgAsExpr(i);
1811 ParamIdx Idx;
1812 if (!checkFunctionOrMethodParameterIndex(S, D, AL, i, Ex, Idx))
1813 return;
1814
1815 // Is the function argument a pointer type?
1816 QualType T = getFunctionOrMethodParamType(D, Idx.getASTIndex());
1817 int Err = -1; // No error
1818 switch (K) {
1819 case OwnershipAttr::Takes:
1820 case OwnershipAttr::Holds:
1821 if (!T->isAnyPointerType() && !T->isBlockPointerType())
1822 Err = 0;
1823 break;
1824 case OwnershipAttr::Returns:
1825 if (!T->isIntegerType())
1826 Err = 1;
1827 break;
1828 }
1829 if (-1 != Err) {
1830 S.Diag(AL.getLoc(), diag::err_ownership_type) << AL << Err
1831 << Ex->getSourceRange();
1832 return;
1833 }
1834
1835 // Check we don't have a conflict with another ownership attribute.
1836 for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
1837 // Cannot have two ownership attributes of different kinds for the same
1838 // index.
1839 if (I->getOwnKind() != K && I->args_end() !=
1840 std::find(I->args_begin(), I->args_end(), Idx)) {
1841 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) << AL << I;
1842 return;
1843 } else if (K == OwnershipAttr::Returns &&
1844 I->getOwnKind() == OwnershipAttr::Returns) {
1845 // A returns attribute conflicts with any other returns attribute using
1846 // a different index.
1847 if (std::find(I->args_begin(), I->args_end(), Idx) == I->args_end()) {
1848 S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch)
1849 << I->args_begin()->getSourceIndex();
1850 if (I->args_size())
1851 S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch)
1852 << Idx.getSourceIndex() << Ex->getSourceRange();
1853 return;
1854 }
1855 }
1856 }
1857 OwnershipArgs.push_back(Idx);
1858 }
1859
1860 ParamIdx *Start = OwnershipArgs.data();
1861 unsigned Size = OwnershipArgs.size();
1862 llvm::array_pod_sort(Start, Start + Size);
1863 D->addAttr(::new (S.Context)
1864 OwnershipAttr(S.Context, AL, Module, Start, Size));
1865}
1866
1867static void handleWeakRefAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1868 // Check the attribute arguments.
1869 if (AL.getNumArgs() > 1) {
1870 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
1871 return;
1872 }
1873
1874 // gcc rejects
1875 // class c {
1876 // static int a __attribute__((weakref ("v2")));
1877 // static int b() __attribute__((weakref ("f3")));
1878 // };
1879 // and ignores the attributes of
1880 // void f(void) {
1881 // static int a __attribute__((weakref ("v2")));
1882 // }
1883 // we reject them
1884 const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
1885 if (!Ctx->isFileContext()) {
1886 S.Diag(AL.getLoc(), diag::err_attribute_weakref_not_global_context)
1887 << cast<NamedDecl>(D);
1888 return;
1889 }
1890
1891 // The GCC manual says
1892 //
1893 // At present, a declaration to which `weakref' is attached can only
1894 // be `static'.
1895 //
1896 // It also says
1897 //
1898 // Without a TARGET,
1899 // given as an argument to `weakref' or to `alias', `weakref' is
1900 // equivalent to `weak'.
1901 //
1902 // gcc 4.4.1 will accept
1903 // int a7 __attribute__((weakref));
1904 // as
1905 // int a7 __attribute__((weak));
1906 // This looks like a bug in gcc. We reject that for now. We should revisit
1907 // it if this behaviour is actually used.
1908
1909 // GCC rejects
1910 // static ((alias ("y"), weakref)).
1911 // Should we? How to check that weakref is before or after alias?
1912
1913 // FIXME: it would be good for us to keep the WeakRefAttr as-written instead
1914 // of transforming it into an AliasAttr. The WeakRefAttr never uses the
1915 // StringRef parameter it was given anyway.
1916 StringRef Str;
1917 if (AL.getNumArgs() && S.checkStringLiteralArgumentAttr(AL, 0, Str))
1918 // GCC will accept anything as the argument of weakref. Should we
1919 // check for an existing decl?
1920 D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
1921
1922 D->addAttr(::new (S.Context) WeakRefAttr(S.Context, AL));
1923}
1924
1925static void handleIFuncAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1926 StringRef Str;
1927 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
1928 return;
1929
1930 // Aliases should be on declarations, not definitions.
1931 const auto *FD = cast<FunctionDecl>(D);
1932 if (FD->isThisDeclarationADefinition()) {
1933 S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 1;
1934 return;
1935 }
1936
1937 D->addAttr(::new (S.Context) IFuncAttr(S.Context, AL, Str));
1938}
1939
1940static void handleAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1941 StringRef Str;
1942 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
1943 return;
1944
1945 if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1946 S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_darwin);
1947 return;
1948 }
1949 if (S.Context.getTargetInfo().getTriple().isNVPTX()) {
1950 S.Diag(AL.getLoc(), diag::err_alias_not_supported_on_nvptx);
1951 }
1952
1953 // Aliases should be on declarations, not definitions.
1954 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
1955 if (FD->isThisDeclarationADefinition()) {
1956 S.Diag(AL.getLoc(), diag::err_alias_is_definition) << FD << 0;
1957 return;
1958 }
1959 } else {
1960 const auto *VD = cast<VarDecl>(D);
1961 if (VD->isThisDeclarationADefinition() && VD->isExternallyVisible()) {
1962 S.Diag(AL.getLoc(), diag::err_alias_is_definition) << VD << 0;
1963 return;
1964 }
1965 }
1966
1967 // Mark target used to prevent unneeded-internal-declaration warnings.
1968 if (!S.LangOpts.CPlusPlus) {
1969 // FIXME: demangle Str for C++, as the attribute refers to the mangled
1970 // linkage name, not the pre-mangled identifier.
1971 const DeclarationNameInfo target(&S.Context.Idents.get(Str), AL.getLoc());
1972 LookupResult LR(S, target, Sema::LookupOrdinaryName);
1973 if (S.LookupQualifiedName(LR, S.getCurLexicalContext()))
1974 for (NamedDecl *ND : LR)
1975 ND->markUsed(S.Context);
1976 }
1977
1978 D->addAttr(::new (S.Context) AliasAttr(S.Context, AL, Str));
1979}
1980
1981static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1982 StringRef Model;
1983 SourceLocation LiteralLoc;
1984 // Check that it is a string.
1985 if (!S.checkStringLiteralArgumentAttr(AL, 0, Model, &LiteralLoc))
1986 return;
1987
1988 // Check that the value.
1989 if (Model != "global-dynamic" && Model != "local-dynamic"
1990 && Model != "initial-exec" && Model != "local-exec") {
1991 S.Diag(LiteralLoc, diag::err_attr_tlsmodel_arg);
1992 return;
1993 }
1994
1995 D->addAttr(::new (S.Context) TLSModelAttr(S.Context, AL, Model));
1996}
1997
1998static void handleRestrictAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1999 QualType ResultType = getFunctionOrMethodResultType(D);
2000 if (ResultType->isAnyPointerType() || ResultType->isBlockPointerType()) {
2001 D->addAttr(::new (S.Context) RestrictAttr(S.Context, AL));
2002 return;
2003 }
2004
2005 S.Diag(AL.getLoc(), diag::warn_attribute_return_pointers_only)
2006 << AL << getFunctionOrMethodResultSourceRange(D);
2007}
2008
2009static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2010 FunctionDecl *FD = cast<FunctionDecl>(D);
2011
2012 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
2013 if (MD->getParent()->isLambda()) {
2014 S.Diag(AL.getLoc(), diag::err_attribute_dll_lambda) << AL;
2015 return;
2016 }
2017 }
2018
2019 if (!checkAttributeAtLeastNumArgs(S, AL, 1))
2020 return;
2021
2022 SmallVector<IdentifierInfo *, 8> CPUs;
2023 for (unsigned ArgNo = 0; ArgNo < getNumAttributeArgs(AL); ++ArgNo) {
2024 if (!AL.isArgIdent(ArgNo)) {
2025 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
2026 << AL << AANT_ArgumentIdentifier;
2027 return;
2028 }
2029
2030 IdentifierLoc *CPUArg = AL.getArgAsIdent(ArgNo);
2031 StringRef CPUName = CPUArg->Ident->getName().trim();
2032
2033 if (!S.Context.getTargetInfo().validateCPUSpecificCPUDispatch(CPUName)) {
2034 S.Diag(CPUArg->Loc, diag::err_invalid_cpu_specific_dispatch_value)
2035 << CPUName << (AL.getKind() == ParsedAttr::AT_CPUDispatch);
2036 return;
2037 }
2038
2039 const TargetInfo &Target = S.Context.getTargetInfo();
2040 if (llvm::any_of(CPUs, [CPUName, &Target](const IdentifierInfo *Cur) {
2041 return Target.CPUSpecificManglingCharacter(CPUName) ==
2042 Target.CPUSpecificManglingCharacter(Cur->getName());
2043 })) {
2044 S.Diag(AL.getLoc(), diag::warn_multiversion_duplicate_entries);
2045 return;
2046 }
2047 CPUs.push_back(CPUArg->Ident);
2048 }
2049
2050 FD->setIsMultiVersion(true);
2051 if (AL.getKind() == ParsedAttr::AT_CPUSpecific)
2052 D->addAttr(::new (S.Context)
2053 CPUSpecificAttr(S.Context, AL, CPUs.data(), CPUs.size()));
2054 else
2055 D->addAttr(::new (S.Context)
2056 CPUDispatchAttr(S.Context, AL, CPUs.data(), CPUs.size()));
2057}
2058
2059static void handleCommonAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2060 if (S.LangOpts.CPlusPlus) {
2061 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_in_lang)
2062 << AL << AttributeLangSupport::Cpp;
2063 return;
2064 }
2065
2066 if (CommonAttr *CA = S.mergeCommonAttr(D, AL))
2067 D->addAttr(CA);
2068}
2069
2070static void handleCmseNSEntryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2071 if (S.LangOpts.CPlusPlus && !D->getDeclContext()->isExternCContext()) {
2072 S.Diag(AL.getLoc(), diag::err_attribute_not_clinkage) << AL;
2073 return;
2074 }
2075
2076 const auto *FD = cast<FunctionDecl>(D);
2077 if (!FD->isExternallyVisible()) {
2078 S.Diag(AL.getLoc(), diag::warn_attribute_cmse_entry_static);
2079 return;
2080 }
2081
2082 D->addAttr(::new (S.Context) CmseNSEntryAttr(S.Context, AL));
2083}
2084
2085static void handleNakedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2086 if (checkAttrMutualExclusion<DisableTailCallsAttr>(S, D, AL))
2087 return;
2088
2089 if (AL.isDeclspecAttribute()) {
2090 const auto &Triple = S.getASTContext().getTargetInfo().getTriple();
2091 const auto &Arch = Triple.getArch();
2092 if (Arch != llvm::Triple::x86 &&
2093 (Arch != llvm::Triple::arm && Arch != llvm::Triple::thumb)) {
2094 S.Diag(AL.getLoc(), diag::err_attribute_not_supported_on_arch)
2095 << AL << Triple.getArchName();
2096 return;
2097 }
2098 }
2099
2100 D->addAttr(::new (S.Context) NakedAttr(S.Context, AL));
2101}
2102
2103static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
2104 if (hasDeclarator(D)) return;
2105
2106 if (!isa<ObjCMethodDecl>(D)) {
2107 S.Diag(Attrs.getLoc(), diag::warn_attribute_wrong_decl_type)
2108 << Attrs << ExpectedFunctionOrMethod;
2109 return;
2110 }
2111
2112 D->addAttr(::new (S.Context) NoReturnAttr(S.Context, Attrs));
2113}
2114
2115static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
2116 if (!S.getLangOpts().CFProtectionBranch)
2117 S.Diag(Attrs.getLoc(), diag::warn_nocf_check_attribute_ignored);
2118 else
2119 handleSimpleAttribute<AnyX86NoCfCheckAttr>(S, D, Attrs);
2120}
2121
2122bool Sema::CheckAttrNoArgs(const ParsedAttr &Attrs) {
2123 if (!checkAttributeNumArgs(*this, Attrs, 0)) {
2124 Attrs.setInvalid();
2125 return true;
2126 }
2127
2128 return false;
2129}
2130
2131bool Sema::CheckAttrTarget(const ParsedAttr &AL) {
2132 // Check whether the attribute is valid on the current target.
2133 if (!AL.existsInTarget(Context.getTargetInfo())) {
2134 Diag(AL.getLoc(), diag::warn_unknown_attribute_ignored)
2135 << AL << AL.getRange();
2136 AL.setInvalid();
2137 return true;
2138 }
2139
2140 return false;
2141}
2142
2143static void handleAnalyzerNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2144
2145 // The checking path for 'noreturn' and 'analyzer_noreturn' are different
2146 // because 'analyzer_noreturn' does not impact the type.
2147 if (!isFunctionOrMethodOrBlock(D)) {
2148 ValueDecl *VD = dyn_cast<ValueDecl>(D);
2149 if (!VD || (!VD->getType()->isBlockPointerType() &&
2150 !VD->getType()->isFunctionPointerType())) {
2151 S.Diag(AL.getLoc(), AL.isCXX11Attribute()
2152 ? diag::err_attribute_wrong_decl_type
2153 : diag::warn_attribute_wrong_decl_type)
2154 << AL << ExpectedFunctionMethodOrBlock;
2155 return;
2156 }
2157 }
2158
2159 D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(S.Context, AL));
2160}
2161
2162// PS3 PPU-specific.
2163static void handleVecReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2164 /*
2165 Returning a Vector Class in Registers
2166
2167 According to the PPU ABI specifications, a class with a single member of
2168 vector type is returned in memory when used as the return value of a
2169 function.
2170 This results in inefficient code when implementing vector classes. To return
2171 the value in a single vector register, add the vecreturn attribute to the
2172 class definition. This attribute is also applicable to struct types.
2173
2174 Example:
2175
2176 struct Vector
2177 {
2178 __vector float xyzw;
2179 } __attribute__((vecreturn));
2180
2181 Vector Add(Vector lhs, Vector rhs)
2182 {
2183 Vector result;
2184 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
2185 return result; // This will be returned in a register
2186 }
2187 */
2188 if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) {
2189 S.Diag(AL.getLoc(), diag::err_repeat_attribute) << A;
2190 return;
2191 }
2192
2193 const auto *R = cast<RecordDecl>(D);
2194 int count = 0;
2195
2196 if (!isa<CXXRecordDecl>(R)) {
2197 S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
2198 return;
2199 }
2200
2201 if (!cast<CXXRecordDecl>(R)->isPOD()) {
2202 S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_pod_record);
2203 return;
2204 }
2205
2206 for (const auto *I : R->fields()) {
2207 if ((count == 1) || !I->getType()->isVectorType()) {
2208 S.Diag(AL.getLoc(), diag::err_attribute_vecreturn_only_vector_member);
2209 return;
2210 }
2211 count++;
2212 }
2213
2214 D->addAttr(::new (S.Context) VecReturnAttr(S.Context, AL));
2215}
2216
2217static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D,
2218 const ParsedAttr &AL) {
2219 if (isa<ParmVarDecl>(D)) {
2220 // [[carries_dependency]] can only be applied to a parameter if it is a
2221 // parameter of a function declaration or lambda.
2222 if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) {
2223 S.Diag(AL.getLoc(),
2224 diag::err_carries_dependency_param_not_function_decl);
2225 return;
2226 }
2227 }
2228
2229 D->addAttr(::new (S.Context) CarriesDependencyAttr(S.Context, AL));
2230}
2231
2232static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2233 bool IsCXX17Attr = AL.isCXX11Attribute() && !AL.getScopeName();
2234
2235 // If this is spelled as the standard C++17 attribute, but not in C++17, warn
2236 // about using it as an extension.
2237 if (!S.getLangOpts().CPlusPlus17 && IsCXX17Attr)
2238 S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
2239
2240 D->addAttr(::new (S.Context) UnusedAttr(S.Context, AL));
2241}
2242
2243static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2244 uint32_t priority = ConstructorAttr::DefaultPriority;
2245 if (AL.getNumArgs() &&
2246 !checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority))
2247 return;
2248
2249 D->addAttr(::new (S.Context) ConstructorAttr(S.Context, AL, priority));
2250}
2251
2252static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2253 uint32_t priority = DestructorAttr::DefaultPriority;
2254 if (AL.getNumArgs() &&
2255 !checkUInt32Argument(S, AL, AL.getArgAsExpr(0), priority))
2256 return;
2257
2258 D->addAttr(::new (S.Context) DestructorAttr(S.Context, AL, priority));
2259}
2260
2261template <typename AttrTy>
2262static void handleAttrWithMessage(Sema &S, Decl *D, const ParsedAttr &AL) {
2263 // Handle the case where the attribute has a text message.
2264 StringRef Str;
2265 if (AL.getNumArgs() == 1 && !S.checkStringLiteralArgumentAttr(AL, 0, Str))
2266 return;
2267
2268 D->addAttr(::new (S.Context) AttrTy(S.Context, AL, Str));
2269}
2270
2271static void handleObjCSuppresProtocolAttr(Sema &S, Decl *D,
2272 const ParsedAttr &AL) {
2273 if (!cast<ObjCProtocolDecl>(D)->isThisDeclarationADefinition()) {
2274 S.Diag(AL.getLoc(), diag::err_objc_attr_protocol_requires_definition)
2275 << AL << AL.getRange();
2276 return;
2277 }
2278
2279 D->addAttr(::new (S.Context) ObjCExplicitProtocolImplAttr(S.Context, AL));
2280}
2281
2282static bool checkAvailabilityAttr(Sema &S, SourceRange Range,
2283 IdentifierInfo *Platform,
2284 VersionTuple Introduced,
2285 VersionTuple Deprecated,
2286 VersionTuple Obsoleted) {
2287 StringRef PlatformName
2288 = AvailabilityAttr::getPrettyPlatformName(Platform->getName());
2289 if (PlatformName.empty())
2290 PlatformName = Platform->getName();
2291
2292 // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
2293 // of these steps are needed).
2294 if (!Introduced.empty() && !Deprecated.empty() &&
2295 !(Introduced <= Deprecated)) {
2296 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2297 << 1 << PlatformName << Deprecated.getAsString()
2298 << 0 << Introduced.getAsString();
2299 return true;
2300 }
2301
2302 if (!Introduced.empty() && !Obsoleted.empty() &&
2303 !(Introduced <= Obsoleted)) {
2304 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2305 << 2 << PlatformName << Obsoleted.getAsString()
2306 << 0 << Introduced.getAsString();
2307 return true;
2308 }
2309
2310 if (!Deprecated.empty() && !Obsoleted.empty() &&
2311 !(Deprecated <= Obsoleted)) {
2312 S.Diag(Range.getBegin(), diag::warn_availability_version_ordering)
2313 << 2 << PlatformName << Obsoleted.getAsString()
2314 << 1 << Deprecated.getAsString();
2315 return true;
2316 }
2317
2318 return false;
2319}
2320
2321/// Check whether the two versions match.
2322///
2323/// If either version tuple is empty, then they are assumed to match. If
2324/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
2325static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
2326 bool BeforeIsOkay) {
2327 if (X.empty() || Y.empty())
2328 return true;
2329
2330 if (X == Y)
2331 return true;
2332
2333 if (BeforeIsOkay && X < Y)
2334 return true;
2335
2336 return false;
2337}
2338
2339AvailabilityAttr *Sema::mergeAvailabilityAttr(
2340 NamedDecl *D, const AttributeCommonInfo &CI, IdentifierInfo *Platform,
2341 bool Implicit, VersionTuple Introduced, VersionTuple Deprecated,
2342 VersionTuple Obsoleted, bool IsUnavailable, StringRef Message,
2343 bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK,
2344 int Priority) {
2345 VersionTuple MergedIntroduced = Introduced;
2346 VersionTuple MergedDeprecated = Deprecated;
2347 VersionTuple MergedObsoleted = Obsoleted;
2348 bool FoundAny = false;
2349 bool OverrideOrImpl = false;
2350 switch (AMK) {
2351 case AMK_None:
2352 case AMK_Redeclaration:
2353 OverrideOrImpl = false;
2354 break;
2355
2356 case AMK_Override:
2357 case AMK_ProtocolImplementation:
2358 OverrideOrImpl = true;
2359 break;
2360 }
2361
2362 if (D->hasAttrs()) {
2363 AttrVec &Attrs = D->getAttrs();
2364 for (unsigned i = 0, e = Attrs.size(); i != e;) {
2365 const auto *OldAA = dyn_cast<AvailabilityAttr>(Attrs[i]);
2366 if (!OldAA) {
2367 ++i;
2368 continue;
2369 }
2370
2371 IdentifierInfo *OldPlatform = OldAA->getPlatform();
2372 if (OldPlatform != Platform) {
2373 ++i;
2374 continue;
2375 }
2376
2377 // If there is an existing availability attribute for this platform that
2378 // has a lower priority use the existing one and discard the new
2379 // attribute.
2380 if (OldAA->getPriority() < Priority)
2381 return nullptr;
2382
2383 // If there is an existing attribute for this platform that has a higher
2384 // priority than the new attribute then erase the old one and continue
2385 // processing the attributes.
2386 if (OldAA->getPriority() > Priority) {
2387 Attrs.erase(Attrs.begin() + i);
2388 --e;
2389 continue;
2390 }
2391
2392 FoundAny = true;
2393 VersionTuple OldIntroduced = OldAA->getIntroduced();
2394 VersionTuple OldDeprecated = OldAA->getDeprecated();
2395 VersionTuple OldObsoleted = OldAA->getObsoleted();
2396 bool OldIsUnavailable = OldAA->getUnavailable();
2397
2398 if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl) ||
2399 !versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl) ||
2400 !versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl) ||
2401 !(OldIsUnavailable == IsUnavailable ||
2402 (OverrideOrImpl && !OldIsUnavailable && IsUnavailable))) {
2403 if (OverrideOrImpl) {
2404 int Which = -1;
2405 VersionTuple FirstVersion;
2406 VersionTuple SecondVersion;
2407 if (!versionsMatch(OldIntroduced, Introduced, OverrideOrImpl)) {
2408 Which = 0;
2409 FirstVersion = OldIntroduced;
2410 SecondVersion = Introduced;
2411 } else if (!versionsMatch(Deprecated, OldDeprecated, OverrideOrImpl)) {
2412 Which = 1;
2413 FirstVersion = Deprecated;
2414 SecondVersion = OldDeprecated;
2415 } else if (!versionsMatch(Obsoleted, OldObsoleted, OverrideOrImpl)) {
2416 Which = 2;
2417 FirstVersion = Obsoleted;
2418 SecondVersion = OldObsoleted;
2419 }
2420
2421 if (Which == -1) {
2422 Diag(OldAA->getLocation(),
2423 diag::warn_mismatched_availability_override_unavail)
2424 << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2425 << (AMK == AMK_Override);
2426 } else {
2427 Diag(OldAA->getLocation(),
2428 diag::warn_mismatched_availability_override)
2429 << Which
2430 << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
2431 << FirstVersion.getAsString() << SecondVersion.getAsString()
2432 << (AMK == AMK_Override);
2433 }
2434 if (AMK == AMK_Override)
2435 Diag(CI.getLoc(), diag::note_overridden_method);
2436 else
2437 Diag(CI.getLoc(), diag::note_protocol_method);
2438 } else {
2439 Diag(OldAA->getLocation(), diag::warn_mismatched_availability);
2440 Diag(CI.getLoc(), diag::note_previous_attribute);
2441 }
2442
2443 Attrs.erase(Attrs.begin() + i);
2444 --e;
2445 continue;
2446 }
2447
2448 VersionTuple MergedIntroduced2 = MergedIntroduced;
2449 VersionTuple MergedDeprecated2 = MergedDeprecated;
2450 VersionTuple MergedObsoleted2 = MergedObsoleted;
2451
2452 if (MergedIntroduced2.empty())
2453 MergedIntroduced2 = OldIntroduced;
2454 if (MergedDeprecated2.empty())
2455 MergedDeprecated2 = OldDeprecated;
2456 if (MergedObsoleted2.empty())
2457 MergedObsoleted2 = OldObsoleted;
2458
2459 if (checkAvailabilityAttr(*this, OldAA->getRange(), Platform,
2460 MergedIntroduced2, MergedDeprecated2,
2461 MergedObsoleted2)) {
2462 Attrs.erase(Attrs.begin() + i);
2463 --e;
2464 continue;
2465 }
2466
2467 MergedIntroduced = MergedIntroduced2;
2468 MergedDeprecated = MergedDeprecated2;
2469 MergedObsoleted = MergedObsoleted2;
2470 ++i;
2471 }
2472 }
2473
2474 if (FoundAny &&
2475 MergedIntroduced == Introduced &&
2476 MergedDeprecated == Deprecated &&
2477 MergedObsoleted == Obsoleted)
2478 return nullptr;
2479
2480 // Only create a new attribute if !OverrideOrImpl, but we want to do
2481 // the checking.
2482 if (!checkAvailabilityAttr(*this, CI.getRange(), Platform, MergedIntroduced,
2483 MergedDeprecated, MergedObsoleted) &&
2484 !OverrideOrImpl) {
2485 auto *Avail = ::new (Context) AvailabilityAttr(
2486 Context, CI, Platform, Introduced, Deprecated, Obsoleted, IsUnavailable,
2487 Message, IsStrict, Replacement, Priority);
2488 Avail->setImplicit(Implicit);
2489 return Avail;
2490 }
2491 return nullptr;
2492}
2493
2494static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2495 if (!checkAttributeNumArgs(S, AL, 1))
2496 return;
2497 IdentifierLoc *Platform = AL.getArgAsIdent(0);
2498
2499 IdentifierInfo *II = Platform->Ident;
2500 if (AvailabilityAttr::getPrettyPlatformName(II->getName()).empty())
2501 S.Diag(Platform->Loc, diag::warn_availability_unknown_platform)
2502 << Platform->Ident;
2503
2504 auto *ND = dyn_cast<NamedDecl>(D);
2505 if (!ND) // We warned about this already, so just return.
2506 return;
2507
2508 AvailabilityChange Introduced = AL.getAvailabilityIntroduced();
2509 AvailabilityChange Deprecated = AL.getAvailabilityDeprecated();
2510 AvailabilityChange Obsoleted = AL.getAvailabilityObsoleted();
2511 bool IsUnavailable = AL.getUnavailableLoc().isValid();
2512 bool IsStrict = AL.getStrictLoc().isValid();
2513 StringRef Str;
2514 if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getMessageExpr()))
2515 Str = SE->getString();
2516 StringRef Replacement;
2517 if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getReplacementExpr()))
2518 Replacement = SE->getString();
2519
2520 if (II->isStr("swift")) {
2521 if (Introduced.isValid() || Obsoleted.isValid() ||
2522 (!IsUnavailable && !Deprecated.isValid())) {
2523 S.Diag(AL.getLoc(),
2524 diag::warn_availability_swift_unavailable_deprecated_only);
2525 return;
2526 }
2527 }
2528
2529 int PriorityModifier = AL.isPragmaClangAttribute()
2530 ? Sema::AP_PragmaClangAttribute
2531 : Sema::AP_Explicit;
2532 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2533 ND, AL, II, false /*Implicit*/, Introduced.Version, Deprecated.Version,
2534 Obsoleted.Version, IsUnavailable, Str, IsStrict, Replacement,
2535 Sema::AMK_None, PriorityModifier);
2536 if (NewAttr)
2537 D->addAttr(NewAttr);
2538
2539 // Transcribe "ios" to "watchos" (and add a new attribute) if the versioning
2540 // matches before the start of the watchOS platform.
2541 if (S.Context.getTargetInfo().getTriple().isWatchOS()) {
2542 IdentifierInfo *NewII = nullptr;
2543 if (II->getName() == "ios")
2544 NewII = &S.Context.Idents.get("watchos");
2545 else if (II->getName() == "ios_app_extension")
2546 NewII = &S.Context.Idents.get("watchos_app_extension");
2547
2548 if (NewII) {
2549 auto adjustWatchOSVersion = [](VersionTuple Version) -> VersionTuple {
2550 if (Version.empty())
2551 return Version;
2552 auto Major = Version.getMajor();
2553 auto NewMajor = Major >= 9 ? Major - 7 : 0;
2554 if (NewMajor >= 2) {
2555 if (Version.getMinor().hasValue()) {
2556 if (Version.getSubminor().hasValue())
2557 return VersionTuple(NewMajor, Version.getMinor().getValue(),
2558 Version.getSubminor().getValue());
2559 else
2560 return VersionTuple(NewMajor, Version.getMinor().getValue());
2561 }
2562 return VersionTuple(NewMajor);
2563 }
2564
2565 return VersionTuple(2, 0);
2566 };
2567
2568 auto NewIntroduced = adjustWatchOSVersion(Introduced.Version);
2569 auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version);
2570 auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version);
2571
2572 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2573 ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
2574 NewObsoleted, IsUnavailable, Str, IsStrict, Replacement,
2575 Sema::AMK_None,
2576 PriorityModifier + Sema::AP_InferredFromOtherPlatform);
2577 if (NewAttr)
2578 D->addAttr(NewAttr);
2579 }
2580 } else if (S.Context.getTargetInfo().getTriple().isTvOS()) {
2581 // Transcribe "ios" to "tvos" (and add a new attribute) if the versioning
2582 // matches before the start of the tvOS platform.
2583 IdentifierInfo *NewII = nullptr;
2584 if (II->getName() == "ios")
2585 NewII = &S.Context.Idents.get("tvos");
2586 else if (II->getName() == "ios_app_extension")
2587 NewII = &S.Context.Idents.get("tvos_app_extension");
2588
2589 if (NewII) {
2590 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2591 ND, AL, NewII, true /*Implicit*/, Introduced.Version,
2592 Deprecated.Version, Obsoleted.Version, IsUnavailable, Str, IsStrict,
2593 Replacement, Sema::AMK_None,
2594 PriorityModifier + Sema::AP_InferredFromOtherPlatform);
2595 if (NewAttr)
2596 D->addAttr(NewAttr);
2597 }
2598 }
2599}
2600
2601static void handleExternalSourceSymbolAttr(Sema &S, Decl *D,
2602 const ParsedAttr &AL) {
2603 if (!checkAttributeAtLeastNumArgs(S, AL, 1))
2604 return;
2605 assert(checkAttributeAtMostNumArgs(S, AL, 3) &&((checkAttributeAtMostNumArgs(S, AL, 3) && "Invalid number of arguments in an external_source_symbol attribute"
) ? static_cast<void> (0) : __assert_fail ("checkAttributeAtMostNumArgs(S, AL, 3) && \"Invalid number of arguments in an external_source_symbol attribute\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 2606, __PRETTY_FUNCTION__))
2606 "Invalid number of arguments in an external_source_symbol attribute")((checkAttributeAtMostNumArgs(S, AL, 3) && "Invalid number of arguments in an external_source_symbol attribute"
) ? static_cast<void> (0) : __assert_fail ("checkAttributeAtMostNumArgs(S, AL, 3) && \"Invalid number of arguments in an external_source_symbol attribute\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 2606, __PRETTY_FUNCTION__))
;
2607
2608 StringRef Language;
2609 if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getArgAsExpr(0)))
2610 Language = SE->getString();
2611 StringRef DefinedIn;
2612 if (const auto *SE = dyn_cast_or_null<StringLiteral>(AL.getArgAsExpr(1)))
2613 DefinedIn = SE->getString();
2614 bool IsGeneratedDeclaration = AL.getArgAsIdent(2) != nullptr;
2615
2616 D->addAttr(::new (S.Context) ExternalSourceSymbolAttr(
2617 S.Context, AL, Language, DefinedIn, IsGeneratedDeclaration));
2618}
2619
2620template <class T>
2621static T *mergeVisibilityAttr(Sema &S, Decl *D, const AttributeCommonInfo &CI,
2622 typename T::VisibilityType value) {
2623 T *existingAttr = D->getAttr<T>();
2624 if (existingAttr) {
2625 typename T::VisibilityType existingValue = existingAttr->getVisibility();
2626 if (existingValue == value)
2627 return nullptr;
2628 S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
2629 S.Diag(CI.getLoc(), diag::note_previous_attribute);
2630 D->dropAttr<T>();
2631 }
2632 return ::new (S.Context) T(S.Context, CI, value);
2633}
2634
2635VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D,
2636 const AttributeCommonInfo &CI,
2637 VisibilityAttr::VisibilityType Vis) {
2638 return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, CI, Vis);
2639}
2640
2641TypeVisibilityAttr *
2642Sema::mergeTypeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI,
2643 TypeVisibilityAttr::VisibilityType Vis) {
2644 return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, CI, Vis);
2645}
2646
2647static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL,
2648 bool isTypeVisibility) {
2649 // Visibility attributes don't mean anything on a typedef.
2650 if (isa<TypedefNameDecl>(D)) {
2651 S.Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored) << AL;
2652 return;
2653 }
2654
2655 // 'type_visibility' can only go on a type or namespace.
2656 if (isTypeVisibility &&
2657 !(isa<TagDecl>(D) ||
2658 isa<ObjCInterfaceDecl>(D) ||
2659 isa<NamespaceDecl>(D))) {
2660 S.Diag(AL.getRange().getBegin(), diag::err_attribute_wrong_decl_type)
2661 << AL << ExpectedTypeOrNamespace;
2662 return;
2663 }
2664
2665 // Check that the argument is a string literal.
2666 StringRef TypeStr;
2667 SourceLocation LiteralLoc;
2668 if (!S.checkStringLiteralArgumentAttr(AL, 0, TypeStr, &LiteralLoc))
2669 return;
2670
2671 VisibilityAttr::VisibilityType type;
2672 if (!VisibilityAttr::ConvertStrToVisibilityType(TypeStr, type)) {
2673 S.Diag(LiteralLoc, diag::warn_attribute_type_not_supported) << AL
2674 << TypeStr;
2675 return;
2676 }
2677
2678 // Complain about attempts to use protected visibility on targets
2679 // (like Darwin) that don't support it.
2680 if (type == VisibilityAttr::Protected &&
2681 !S.Context.getTargetInfo().hasProtectedVisibility()) {
2682 S.Diag(AL.getLoc(), diag::warn_attribute_protected_visibility);
2683 type = VisibilityAttr::Default;
2684 }
2685
2686 Attr *newAttr;
2687 if (isTypeVisibility) {
2688 newAttr = S.mergeTypeVisibilityAttr(
2689 D, AL, (TypeVisibilityAttr::VisibilityType)type);
2690 } else {
2691 newAttr = S.mergeVisibilityAttr(D, AL, type);
2692 }
2693 if (newAttr)
2694 D->addAttr(newAttr);
2695}
2696
2697static void handleObjCNonRuntimeProtocolAttr(Sema &S, Decl *D,
2698 const ParsedAttr &AL) {
2699 handleSimpleAttribute<ObjCNonRuntimeProtocolAttr>(S, D, AL);
2700}
2701
2702static void handleObjCDirectAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2703 // objc_direct cannot be set on methods declared in the context of a protocol
2704 if (isa<ObjCProtocolDecl>(D->getDeclContext())) {
2705 S.Diag(AL.getLoc(), diag::err_objc_direct_on_protocol) << false;
2706 return;
2707 }
2708
2709 if (S.getLangOpts().ObjCRuntime.allowsDirectDispatch()) {
2710 handleSimpleAttribute<ObjCDirectAttr>(S, D, AL);
2711 } else {
2712 S.Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;
2713 }
2714}
2715
2716static void handleObjCDirectMembersAttr(Sema &S, Decl *D,
2717 const ParsedAttr &AL) {
2718 if (S.getLangOpts().ObjCRuntime.allowsDirectDispatch()) {
2719 handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, AL);
2720 } else {
2721 S.Diag(AL.getLoc(), diag::warn_objc_direct_ignored) << AL;
2722 }
2723}
2724
2725static void handleObjCMethodFamilyAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2726 const auto *M = cast<ObjCMethodDecl>(D);
2727 if (!AL.isArgIdent(0)) {
2728 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
2729 << AL << 1 << AANT_ArgumentIdentifier;
2730 return;
2731 }
2732
2733 IdentifierLoc *IL = AL.getArgAsIdent(0);
2734 ObjCMethodFamilyAttr::FamilyKind F;
2735 if (!ObjCMethodFamilyAttr::ConvertStrToFamilyKind(IL->Ident->getName(), F)) {
2736 S.Diag(IL->Loc, diag::warn_attribute_type_not_supported) << AL << IL->Ident;
2737 return;
2738 }
2739
2740 if (F == ObjCMethodFamilyAttr::OMF_init &&
2741 !M->getReturnType()->isObjCObjectPointerType()) {
2742 S.Diag(M->getLocation(), diag::err_init_method_bad_return_type)
2743 << M->getReturnType();
2744 // Ignore the attribute.
2745 return;
2746 }
2747
2748 D->addAttr(new (S.Context) ObjCMethodFamilyAttr(S.Context, AL, F));
2749}
2750
2751static void handleObjCNSObject(Sema &S, Decl *D, const ParsedAttr &AL) {
2752 if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
2753 QualType T = TD->getUnderlyingType();
2754 if (!T->isCARCBridgableType()) {
2755 S.Diag(TD->getLocation(), diag::err_nsobject_attribute);
2756 return;
2757 }
2758 }
2759 else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) {
2760 QualType T = PD->getType();
2761 if (!T->isCARCBridgableType()) {
2762 S.Diag(PD->getLocation(), diag::err_nsobject_attribute);
2763 return;
2764 }
2765 }
2766 else {
2767 // It is okay to include this attribute on properties, e.g.:
2768 //
2769 // @property (retain, nonatomic) struct Bork *Q __attribute__((NSObject));
2770 //
2771 // In this case it follows tradition and suppresses an error in the above
2772 // case.
2773 S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
2774 }
2775 D->addAttr(::new (S.Context) ObjCNSObjectAttr(S.Context, AL));
2776}
2777
2778static void handleObjCIndependentClass(Sema &S, Decl *D, const ParsedAttr &AL) {
2779 if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
2780 QualType T = TD->getUnderlyingType();
2781 if (!T->isObjCObjectPointerType()) {
2782 S.Diag(TD->getLocation(), diag::warn_ptr_independentclass_attribute);
2783 return;
2784 }
2785 } else {
2786 S.Diag(D->getLocation(), diag::warn_independentclass_attribute);
2787 return;
2788 }
2789 D->addAttr(::new (S.Context) ObjCIndependentClassAttr(S.Context, AL));
2790}
2791
2792static void handleBlocksAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2793 if (!AL.isArgIdent(0)) {
2794 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
2795 << AL << 1 << AANT_ArgumentIdentifier;
2796 return;
2797 }
2798
2799 IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
2800 BlocksAttr::BlockType type;
2801 if (!BlocksAttr::ConvertStrToBlockType(II->getName(), type)) {
2802 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
2803 return;
2804 }
2805
2806 D->addAttr(::new (S.Context) BlocksAttr(S.Context, AL, type));
2807}
2808
2809static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2810 unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel;
2811 if (AL.getNumArgs() > 0) {
2812 Expr *E = AL.getArgAsExpr(0);
2813 Optional<llvm::APSInt> Idx = llvm::APSInt(32);
2814 if (E->isTypeDependent() || E->isValueDependent() ||
2815 !(Idx = E->getIntegerConstantExpr(S.Context))) {
2816 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
2817 << AL << 1 << AANT_ArgumentIntegerConstant << E->getSourceRange();
2818 return;
2819 }
2820
2821 if (Idx->isSigned() && Idx->isNegative()) {
2822 S.Diag(AL.getLoc(), diag::err_attribute_sentinel_less_than_zero)
2823 << E->getSourceRange();
2824 return;
2825 }
2826
2827 sentinel = Idx->getZExtValue();
2828 }
2829
2830 unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos;
2831 if (AL.getNumArgs() > 1) {
2832 Expr *E = AL.getArgAsExpr(1);
2833 Optional<llvm::APSInt> Idx = llvm::APSInt(32);
2834 if (E->isTypeDependent() || E->isValueDependent() ||
2835 !(Idx = E->getIntegerConstantExpr(S.Context))) {
2836 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
2837 << AL << 2 << AANT_ArgumentIntegerConstant << E->getSourceRange();
2838 return;
2839 }
2840 nullPos = Idx->getZExtValue();
2841
2842 if ((Idx->isSigned() && Idx->isNegative()) || nullPos > 1) {
2843 // FIXME: This error message could be improved, it would be nice
2844 // to say what the bounds actually are.
2845 S.Diag(AL.getLoc(), diag::err_attribute_sentinel_not_zero_or_one)
2846 << E->getSourceRange();
2847 return;
2848 }
2849 }
2850
2851 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
2852 const FunctionType *FT = FD->getType()->castAs<FunctionType>();
2853 if (isa<FunctionNoProtoType>(FT)) {
2854 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_named_arguments);
2855 return;
2856 }
2857
2858 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
2859 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2860 return;
2861 }
2862 } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
2863 if (!MD->isVariadic()) {
2864 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 0;
2865 return;
2866 }
2867 } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
2868 if (!BD->isVariadic()) {
2869 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << 1;
2870 return;
2871 }
2872 } else if (const auto *V = dyn_cast<VarDecl>(D)) {
2873 QualType Ty = V->getType();
2874 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
2875 const FunctionType *FT = Ty->isFunctionPointerType()
2876 ? D->getFunctionType()
2877 : Ty->castAs<BlockPointerType>()->getPointeeType()->getAs<FunctionType>();
2878 if (!cast<FunctionProtoType>(FT)->isVariadic()) {
2879 int m = Ty->isFunctionPointerType() ? 0 : 1;
2880 S.Diag(AL.getLoc(), diag::warn_attribute_sentinel_not_variadic) << m;
2881 return;
2882 }
2883 } else {
2884 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
2885 << AL << ExpectedFunctionMethodOrBlock;
2886 return;
2887 }
2888 } else {
2889 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
2890 << AL << ExpectedFunctionMethodOrBlock;
2891 return;
2892 }
2893 D->addAttr(::new (S.Context) SentinelAttr(S.Context, AL, sentinel, nullPos));
2894}
2895
2896static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) {
2897 if (D->getFunctionType() &&
2898 D->getFunctionType()->getReturnType()->isVoidType() &&
2899 !isa<CXXConstructorDecl>(D)) {
2900 S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 0;
2901 return;
2902 }
2903 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
2904 if (MD->getReturnType()->isVoidType()) {
2905 S.Diag(AL.getLoc(), diag::warn_attribute_void_function_method) << AL << 1;
2906 return;
2907 }
2908
2909 StringRef Str;
2910 if ((AL.isCXX11Attribute() || AL.isC2xAttribute()) && !AL.getScopeName()) {
2911 // The standard attribute cannot be applied to variable declarations such
2912 // as a function pointer.
2913 if (isa<VarDecl>(D))
2914 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type_str)
2915 << AL << "functions, classes, or enumerations";
2916
2917 // If this is spelled as the standard C++17 attribute, but not in C++17,
2918 // warn about using it as an extension. If there are attribute arguments,
2919 // then claim it's a C++2a extension instead.
2920 // FIXME: If WG14 does not seem likely to adopt the same feature, add an
2921 // extension warning for C2x mode.
2922 const LangOptions &LO = S.getLangOpts();
2923 if (AL.getNumArgs() == 1) {
2924 if (LO.CPlusPlus && !LO.CPlusPlus20)
2925 S.Diag(AL.getLoc(), diag::ext_cxx20_attr) << AL;
2926
2927 // Since this this is spelled [[nodiscard]], get the optional string
2928 // literal. If in C++ mode, but not in C++2a mode, diagnose as an
2929 // extension.
2930 // FIXME: C2x should support this feature as well, even as an extension.
2931 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, nullptr))
2932 return;
2933 } else if (LO.CPlusPlus && !LO.CPlusPlus17)
2934 S.Diag(AL.getLoc(), diag::ext_cxx17_attr) << AL;
2935 }
2936
2937 D->addAttr(::new (S.Context) WarnUnusedResultAttr(S.Context, AL, Str));
2938}
2939
2940static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2941 // weak_import only applies to variable & function declarations.
2942 bool isDef = false;
2943 if (!D->canBeWeakImported(isDef)) {
2944 if (isDef)
2945 S.Diag(AL.getLoc(), diag::warn_attribute_invalid_on_definition)
2946 << "weak_import";
2947 else if (isa<ObjCPropertyDecl>(D) || isa<ObjCMethodDecl>(D) ||
2948 (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
2949 (isa<ObjCInterfaceDecl>(D) || isa<EnumDecl>(D)))) {
2950 // Nothing to warn about here.
2951 } else
2952 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
2953 << AL << ExpectedVariableOrFunction;
2954
2955 return;
2956 }
2957
2958 D->addAttr(::new (S.Context) WeakImportAttr(S.Context, AL));
2959}
2960
2961// Handles reqd_work_group_size and work_group_size_hint.
2962template <typename WorkGroupAttr>
2963static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
2964 uint32_t WGSize[3];
2965 for (unsigned i = 0; i < 3; ++i) {
2966 const Expr *E = AL.getArgAsExpr(i);
2967 if (!checkUInt32Argument(S, AL, E, WGSize[i], i,
2968 /*StrictlyUnsigned=*/true))
2969 return;
2970 if (WGSize[i] == 0) {
2971 S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
2972 << AL << E->getSourceRange();
2973 return;
2974 }
2975 }
2976
2977 WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
2978 if (Existing && !(Existing->getXDim() == WGSize[0] &&
2979 Existing->getYDim() == WGSize[1] &&
2980 Existing->getZDim() == WGSize[2]))
2981 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
2982
2983 D->addAttr(::new (S.Context)
2984 WorkGroupAttr(S.Context, AL, WGSize[0], WGSize[1], WGSize[2]));
2985}
2986
2987// Handles intel_reqd_sub_group_size.
2988static void handleSubGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
2989 uint32_t SGSize;
2990 const Expr *E = AL.getArgAsExpr(0);
2991 if (!checkUInt32Argument(S, AL, E, SGSize))
2992 return;
2993 if (SGSize == 0) {
2994 S.Diag(AL.getLoc(), diag::err_attribute_argument_is_zero)
2995 << AL << E->getSourceRange();
2996 return;
2997 }
2998
2999 OpenCLIntelReqdSubGroupSizeAttr *Existing =
3000 D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>();
3001 if (Existing && Existing->getSubGroupSize() != SGSize)
3002 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3003
3004 D->addAttr(::new (S.Context)
3005 OpenCLIntelReqdSubGroupSizeAttr(S.Context, AL, SGSize));
3006}
3007
3008static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
3009 if (!AL.hasParsedType()) {
3010 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
3011 return;
3012 }
3013
3014 TypeSourceInfo *ParmTSI = nullptr;
3015 QualType ParmType = S.GetTypeFromParser(AL.getTypeArg(), &ParmTSI);
3016 assert(ParmTSI && "no type source info for attribute argument")((ParmTSI && "no type source info for attribute argument"
) ? static_cast<void> (0) : __assert_fail ("ParmTSI && \"no type source info for attribute argument\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 3016, __PRETTY_FUNCTION__))
;
3017
3018 if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
3019 (ParmType->isBooleanType() ||
3020 !ParmType->isIntegralType(S.getASTContext()))) {
3021 S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument) << 2 << AL;
3022 return;
3023 }
3024
3025 if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) {
3026 if (!S.Context.hasSameType(A->getTypeHint(), ParmType)) {
3027 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3028 return;
3029 }
3030 }
3031
3032 D->addAttr(::new (S.Context) VecTypeHintAttr(S.Context, AL, ParmTSI));
3033}
3034
3035SectionAttr *Sema::mergeSectionAttr(Decl *D, const AttributeCommonInfo &CI,
3036 StringRef Name) {
3037 // Explicit or partial specializations do not inherit
3038 // the section attribute from the primary template.
3039 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3040 if (CI.getAttributeSpellingListIndex() == SectionAttr::Declspec_allocate &&
3041 FD->isFunctionTemplateSpecialization())
3042 return nullptr;
3043 }
3044 if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
3045 if (ExistingAttr->getName() == Name)
3046 return nullptr;
3047 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
3048 << 1 /*section*/;
3049 Diag(CI.getLoc(), diag::note_previous_attribute);
3050 return nullptr;
3051 }
3052 return ::new (Context) SectionAttr(Context, CI, Name);
3053}
3054
3055bool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) {
3056 if (llvm::Error E =
3057 Context.getTargetInfo().isValidSectionSpecifier(SecName)) {
3058 Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
3059 << toString(std::move(E)) << 1 /*'section'*/;
3060 return false;
3061 }
3062 return true;
3063}
3064
3065static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3066 // Make sure that there is a string literal as the sections's single
3067 // argument.
3068 StringRef Str;
3069 SourceLocation LiteralLoc;
3070 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
3071 return;
3072
3073 if (!S.checkSectionName(LiteralLoc, Str))
3074 return;
3075
3076 // If the target wants to validate the section specifier, make it happen.
3077 if (llvm::Error E = S.Context.getTargetInfo().isValidSectionSpecifier(Str)) {
3078 S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
3079 << toString(std::move(E));
3080 return;
3081 }
3082
3083 SectionAttr *NewAttr = S.mergeSectionAttr(D, AL, Str);
3084 if (NewAttr) {
3085 D->addAttr(NewAttr);
3086 if (isa<FunctionDecl, FunctionTemplateDecl, ObjCMethodDecl,
3087 ObjCPropertyDecl>(D))
3088 S.UnifySection(NewAttr->getName(),
3089 ASTContext::PSF_Execute | ASTContext::PSF_Read,
3090 cast<NamedDecl>(D));
3091 }
3092}
3093
3094// This is used for `__declspec(code_seg("segname"))` on a decl.
3095// `#pragma code_seg("segname")` uses checkSectionName() instead.
3096static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc,
3097 StringRef CodeSegName) {
3098 if (llvm::Error E =
3099 S.Context.getTargetInfo().isValidSectionSpecifier(CodeSegName)) {
3100 S.Diag(LiteralLoc, diag::err_attribute_section_invalid_for_target)
3101 << toString(std::move(E)) << 0 /*'code-seg'*/;
3102 return false;
3103 }
3104
3105 return true;
3106}
3107
3108CodeSegAttr *Sema::mergeCodeSegAttr(Decl *D, const AttributeCommonInfo &CI,
3109 StringRef Name) {
3110 // Explicit or partial specializations do not inherit
3111 // the code_seg attribute from the primary template.
3112 if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
3113 if (FD->isFunctionTemplateSpecialization())
3114 return nullptr;
3115 }
3116 if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3117 if (ExistingAttr->getName() == Name)
3118 return nullptr;
3119 Diag(ExistingAttr->getLocation(), diag::warn_mismatched_section)
3120 << 0 /*codeseg*/;
3121 Diag(CI.getLoc(), diag::note_previous_attribute);
3122 return nullptr;
3123 }
3124 return ::new (Context) CodeSegAttr(Context, CI, Name);
3125}
3126
3127static void handleCodeSegAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3128 StringRef Str;
3129 SourceLocation LiteralLoc;
3130 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc))
3131 return;
3132 if (!checkCodeSegName(S, LiteralLoc, Str))
3133 return;
3134 if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3135 if (!ExistingAttr->isImplicit()) {
3136 S.Diag(AL.getLoc(),
3137 ExistingAttr->getName() == Str
3138 ? diag::warn_duplicate_codeseg_attribute
3139 : diag::err_conflicting_codeseg_attribute);
3140 return;
3141 }
3142 D->dropAttr<CodeSegAttr>();
3143 }
3144 if (CodeSegAttr *CSA = S.mergeCodeSegAttr(D, AL, Str))
3145 D->addAttr(CSA);
3146}
3147
3148// Check for things we'd like to warn about. Multiversioning issues are
3149// handled later in the process, once we know how many exist.
3150bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
3151 enum FirstParam { Unsupported, Duplicate, Unknown };
3152 enum SecondParam { None, Architecture, Tune };
3153 if (AttrStr.find("fpmath=") != StringRef::npos)
3154 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3155 << Unsupported << None << "fpmath=";
3156
3157 // Diagnose use of tune if target doesn't support it.
3158 if (!Context.getTargetInfo().supportsTargetAttributeTune() &&
3159 AttrStr.find("tune=") != StringRef::npos)
3160 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3161 << Unsupported << None << "tune=";
3162
3163 ParsedTargetAttr ParsedAttrs = TargetAttr::parse(AttrStr);
3164
3165 if (!ParsedAttrs.Architecture.empty() &&
3166 !Context.getTargetInfo().isValidCPUName(ParsedAttrs.Architecture))
3167 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3168 << Unknown << Architecture << ParsedAttrs.Architecture;
3169
3170 if (!ParsedAttrs.Tune.empty() &&
3171 !Context.getTargetInfo().isValidCPUName(ParsedAttrs.Tune))
3172 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3173 << Unknown << Tune << ParsedAttrs.Tune;
3174
3175 if (ParsedAttrs.DuplicateArchitecture)
3176 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3177 << Duplicate << None << "arch=";
3178 if (ParsedAttrs.DuplicateTune)
3179 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3180 << Duplicate << None << "tune=";
3181
3182 for (const auto &Feature : ParsedAttrs.Features) {
3183 auto CurFeature = StringRef(Feature).drop_front(); // remove + or -.
3184 if (!Context.getTargetInfo().isValidFeatureName(CurFeature))
3185 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3186 << Unsupported << None << CurFeature;
3187 }
3188
3189 TargetInfo::BranchProtectionInfo BPI;
3190 StringRef Error;
3191 if (!ParsedAttrs.BranchProtection.empty() &&
3192 !Context.getTargetInfo().validateBranchProtection(
3193 ParsedAttrs.BranchProtection, BPI, Error)) {
3194 if (Error.empty())
3195 return Diag(LiteralLoc, diag::warn_unsupported_target_attribute)
3196 << Unsupported << None << "branch-protection";
3197 else
3198 return Diag(LiteralLoc, diag::err_invalid_branch_protection_spec)
3199 << Error;
3200 }
3201
3202 return false;
3203}
3204
3205static void handleTargetAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3206 StringRef Str;
3207 SourceLocation LiteralLoc;
3208 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc) ||
3209 S.checkTargetAttr(LiteralLoc, Str))
3210 return;
3211
3212 TargetAttr *NewAttr = ::new (S.Context) TargetAttr(S.Context, AL, Str);
3213 D->addAttr(NewAttr);
3214}
3215
3216static void handleMinVectorWidthAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3217 Expr *E = AL.getArgAsExpr(0);
3218 uint32_t VecWidth;
3219 if (!checkUInt32Argument(S, AL, E, VecWidth)) {
3220 AL.setInvalid();
3221 return;
3222 }
3223
3224 MinVectorWidthAttr *Existing = D->getAttr<MinVectorWidthAttr>();
3225 if (Existing && Existing->getVectorWidth() != VecWidth) {
3226 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
3227 return;
3228 }
3229
3230 D->addAttr(::new (S.Context) MinVectorWidthAttr(S.Context, AL, VecWidth));
3231}
3232
3233static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3234 Expr *E = AL.getArgAsExpr(0);
3235 SourceLocation Loc = E->getExprLoc();
3236 FunctionDecl *FD = nullptr;
3237 DeclarationNameInfo NI;
3238
3239 // gcc only allows for simple identifiers. Since we support more than gcc, we
3240 // will warn the user.
3241 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
3242 if (DRE->hasQualifier())
3243 S.Diag(Loc, diag::warn_cleanup_ext);
3244 FD = dyn_cast<FunctionDecl>(DRE->getDecl());
3245 NI = DRE->getNameInfo();
3246 if (!FD) {
3247 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 1
3248 << NI.getName();
3249 return;
3250 }
3251 } else if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(E)) {
3252 if (ULE->hasExplicitTemplateArgs())
3253 S.Diag(Loc, diag::warn_cleanup_ext);
3254 FD = S.ResolveSingleFunctionTemplateSpecialization(ULE, true);
3255 NI = ULE->getNameInfo();
3256 if (!FD) {
3257 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 2
3258 << NI.getName();
3259 if (ULE->getType() == S.Context.OverloadTy)
3260 S.NoteAllOverloadCandidates(ULE);
3261 return;
3262 }
3263 } else {
3264 S.Diag(Loc, diag::err_attribute_cleanup_arg_not_function) << 0;
3265 return;
3266 }
3267
3268 if (FD->getNumParams() != 1) {
3269 S.Diag(Loc, diag::err_attribute_cleanup_func_must_take_one_arg)
3270 << NI.getName();
3271 return;
3272 }
3273
3274 // We're currently more strict than GCC about what function types we accept.
3275 // If this ever proves to be a problem it should be easy to fix.
3276 QualType Ty = S.Context.getPointerType(cast<VarDecl>(D)->getType());
3277 QualType ParamTy = FD->getParamDecl(0)->getType();
3278 if (S.CheckAssignmentConstraints(FD->getParamDecl(0)->getLocation(),
3279 ParamTy, Ty) != Sema::Compatible) {
3280 S.Diag(Loc, diag::err_attribute_cleanup_func_arg_incompatible_type)
3281 << NI.getName() << ParamTy << Ty;
3282 return;
3283 }
3284
3285 D->addAttr(::new (S.Context) CleanupAttr(S.Context, AL, FD));
3286}
3287
3288static void handleEnumExtensibilityAttr(Sema &S, Decl *D,
3289 const ParsedAttr &AL) {
3290 if (!AL.isArgIdent(0)) {
3291 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3292 << AL << 0 << AANT_ArgumentIdentifier;
3293 return;
3294 }
3295
3296 EnumExtensibilityAttr::Kind ExtensibilityKind;
3297 IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
3298 if (!EnumExtensibilityAttr::ConvertStrToKind(II->getName(),
3299 ExtensibilityKind)) {
3300 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported) << AL << II;
3301 return;
3302 }
3303
3304 D->addAttr(::new (S.Context)
3305 EnumExtensibilityAttr(S.Context, AL, ExtensibilityKind));
3306}
3307
3308/// Handle __attribute__((format_arg((idx)))) attribute based on
3309/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
3310static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3311 Expr *IdxExpr = AL.getArgAsExpr(0);
3312 ParamIdx Idx;
3313 if (!checkFunctionOrMethodParameterIndex(S, D, AL, 1, IdxExpr, Idx))
3314 return;
3315
3316 // Make sure the format string is really a string.
3317 QualType Ty = getFunctionOrMethodParamType(D, Idx.getASTIndex());
3318
3319 bool NotNSStringTy = !isNSStringType(Ty, S.Context);
3320 if (NotNSStringTy &&
3321 !isCFStringType(Ty, S.Context) &&
3322 (!Ty->isPointerType() ||
3323 !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
3324 S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3325 << "a string type" << IdxExpr->getSourceRange()
3326 << getFunctionOrMethodParamRange(D, 0);
3327 return;
3328 }
3329 Ty = getFunctionOrMethodResultType(D);
3330 if (!isNSStringType(Ty, S.Context) &&
3331 !isCFStringType(Ty, S.Context) &&
3332 (!Ty->isPointerType() ||
3333 !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
3334 S.Diag(AL.getLoc(), diag::err_format_attribute_result_not)
3335 << (NotNSStringTy ? "string type" : "NSString")
3336 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, 0);
3337 return;
3338 }
3339
3340 D->addAttr(::new (S.Context) FormatArgAttr(S.Context, AL, Idx));
3341}
3342
3343enum FormatAttrKind {
3344 CFStringFormat,
3345 NSStringFormat,
3346 StrftimeFormat,
3347 SupportedFormat,
3348 IgnoredFormat,
3349 InvalidFormat
3350};
3351
3352/// getFormatAttrKind - Map from format attribute names to supported format
3353/// types.
3354static FormatAttrKind getFormatAttrKind(StringRef Format) {
3355 return llvm::StringSwitch<FormatAttrKind>(Format)
3356 // Check for formats that get handled specially.
3357 .Case("NSString", NSStringFormat)
3358 .Case("CFString", CFStringFormat)
3359 .Case("strftime", StrftimeFormat)
3360
3361 // Otherwise, check for supported formats.
3362 .Cases("scanf", "printf", "printf0", "strfmon", SupportedFormat)
3363 .Cases("cmn_err", "vcmn_err", "zcmn_err", SupportedFormat)
3364 .Case("kprintf", SupportedFormat) // OpenBSD.
3365 .Case("freebsd_kprintf", SupportedFormat) // FreeBSD.
3366 .Case("os_trace", SupportedFormat)
3367 .Case("os_log", SupportedFormat)
3368
3369 .Cases("gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag", IgnoredFormat)
3370 .Default(InvalidFormat);
3371}
3372
3373/// Handle __attribute__((init_priority(priority))) attributes based on
3374/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
3375static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3376 if (!S.getLangOpts().CPlusPlus) {
3377 S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
3378 return;
3379 }
3380
3381 if (S.getCurFunctionOrMethodDecl()) {
3382 S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);
3383 AL.setInvalid();
3384 return;
3385 }
3386 QualType T = cast<VarDecl>(D)->getType();
3387 if (S.Context.getAsArrayType(T))
3388 T = S.Context.getBaseElementType(T);
3389 if (!T->getAs<RecordType>()) {
3390 S.Diag(AL.getLoc(), diag::err_init_priority_object_attr);
3391 AL.setInvalid();
3392 return;
3393 }
3394
3395 Expr *E = AL.getArgAsExpr(0);
3396 uint32_t prioritynum;
3397 if (!checkUInt32Argument(S, AL, E, prioritynum)) {
3398 AL.setInvalid();
3399 return;
3400 }
3401
3402 // Only perform the priority check if the attribute is outside of a system
3403 // header. Values <= 100 are reserved for the implementation, and libc++
3404 // benefits from being able to specify values in that range.
3405 if ((prioritynum < 101 || prioritynum > 65535) &&
3406 !S.getSourceManager().isInSystemHeader(AL.getLoc())) {
3407 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_range)
3408 << E->getSourceRange() << AL << 101 << 65535;
3409 AL.setInvalid();
3410 return;
3411 }
3412 D->addAttr(::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
3413}
3414
3415FormatAttr *Sema::mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI,
3416 IdentifierInfo *Format, int FormatIdx,
3417 int FirstArg) {
3418 // Check whether we already have an equivalent format attribute.
3419 for (auto *F : D->specific_attrs<FormatAttr>()) {
3420 if (F->getType() == Format &&
3421 F->getFormatIdx() == FormatIdx &&
3422 F->getFirstArg() == FirstArg) {
3423 // If we don't have a valid location for this attribute, adopt the
3424 // location.
3425 if (F->getLocation().isInvalid())
3426 F->setRange(CI.getRange());
3427 return nullptr;
3428 }
3429 }
3430
3431 return ::new (Context) FormatAttr(Context, CI, Format, FormatIdx, FirstArg);
3432}
3433
3434/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
3435/// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
3436static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3437 if (!AL.isArgIdent(0)) {
3438 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
3439 << AL << 1 << AANT_ArgumentIdentifier;
3440 return;
3441 }
3442
3443 // In C++ the implicit 'this' function parameter also counts, and they are
3444 // counted from one.
3445 bool HasImplicitThisParam = isInstanceMethod(D);
3446 unsigned NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam;
3447
3448 IdentifierInfo *II = AL.getArgAsIdent(0)->Ident;
3449 StringRef Format = II->getName();
3450
3451 if (normalizeName(Format)) {
3452 // If we've modified the string name, we need a new identifier for it.
3453 II = &S.Context.Idents.get(Format);
3454 }
3455
3456 // Check for supported formats.
3457 FormatAttrKind Kind = getFormatAttrKind(Format);
3458
3459 if (Kind == IgnoredFormat)
3460 return;
3461
3462 if (Kind == InvalidFormat) {
3463 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
3464 << AL << II->getName();
3465 return;
3466 }
3467
3468 // checks for the 2nd argument
3469 Expr *IdxExpr = AL.getArgAsExpr(1);
3470 uint32_t Idx;
3471 if (!checkUInt32Argument(S, AL, IdxExpr, Idx, 2))
3472 return;
3473
3474 if (Idx < 1 || Idx > NumArgs) {
3475 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
3476 << AL << 2 << IdxExpr->getSourceRange();
3477 return;
3478 }
3479
3480 // FIXME: Do we need to bounds check?
3481 unsigned ArgIdx = Idx - 1;
3482
3483 if (HasImplicitThisParam) {
3484 if (ArgIdx == 0) {
3485 S.Diag(AL.getLoc(),
3486 diag::err_format_attribute_implicit_this_format_string)
3487 << IdxExpr->getSourceRange();
3488 return;
3489 }
3490 ArgIdx--;
3491 }
3492
3493 // make sure the format string is really a string
3494 QualType Ty = getFunctionOrMethodParamType(D, ArgIdx);
3495
3496 if (Kind == CFStringFormat) {
3497 if (!isCFStringType(Ty, S.Context)) {
3498 S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3499 << "a CFString" << IdxExpr->getSourceRange()
3500 << getFunctionOrMethodParamRange(D, ArgIdx);
3501 return;
3502 }
3503 } else if (Kind == NSStringFormat) {
3504 // FIXME: do we need to check if the type is NSString*? What are the
3505 // semantics?
3506 if (!isNSStringType(Ty, S.Context)) {
3507 S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3508 << "an NSString" << IdxExpr->getSourceRange()
3509 << getFunctionOrMethodParamRange(D, ArgIdx);
3510 return;
3511 }
3512 } else if (!Ty->isPointerType() ||
3513 !Ty->castAs<PointerType>()->getPointeeType()->isCharType()) {
3514 S.Diag(AL.getLoc(), diag::err_format_attribute_not)
3515 << "a string type" << IdxExpr->getSourceRange()
3516 << getFunctionOrMethodParamRange(D, ArgIdx);
3517 return;
3518 }
3519
3520 // check the 3rd argument
3521 Expr *FirstArgExpr = AL.getArgAsExpr(2);
3522 uint32_t FirstArg;
3523 if (!checkUInt32Argument(S, AL, FirstArgExpr, FirstArg, 3))
3524 return;
3525
3526 // check if the function is variadic if the 3rd argument non-zero
3527 if (FirstArg != 0) {
3528 if (isFunctionOrMethodVariadic(D)) {
3529 ++NumArgs; // +1 for ...
3530 } else {
3531 S.Diag(D->getLocation(), diag::err_format_attribute_requires_variadic);
3532 return;
3533 }
3534 }
3535
3536 // strftime requires FirstArg to be 0 because it doesn't read from any
3537 // variable the input is just the current time + the format string.
3538 if (Kind == StrftimeFormat) {
3539 if (FirstArg != 0) {
3540 S.Diag(AL.getLoc(), diag::err_format_strftime_third_parameter)
3541 << FirstArgExpr->getSourceRange();
3542 return;
3543 }
3544 // if 0 it disables parameter checking (to use with e.g. va_list)
3545 } else if (FirstArg != 0 && FirstArg != NumArgs) {
3546 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
3547 << AL << 3 << FirstArgExpr->getSourceRange();
3548 return;
3549 }
3550
3551 FormatAttr *NewAttr = S.mergeFormatAttr(D, AL, II, Idx, FirstArg);
3552 if (NewAttr)
3553 D->addAttr(NewAttr);
3554}
3555
3556/// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
3557static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3558 // The index that identifies the callback callee is mandatory.
3559 if (AL.getNumArgs() == 0) {
3560 S.Diag(AL.getLoc(), diag::err_callback_attribute_no_callee)
3561 << AL.getRange();
3562 return;
3563 }
3564
3565 bool HasImplicitThisParam = isInstanceMethod(D);
3566 int32_t NumArgs = getFunctionOrMethodNumParams(D);
3567
3568 FunctionDecl *FD = D->getAsFunction();
3569 assert(FD && "Expected a function declaration!")((FD && "Expected a function declaration!") ? static_cast
<void> (0) : __assert_fail ("FD && \"Expected a function declaration!\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 3569, __PRETTY_FUNCTION__))
;
3570
3571 llvm::StringMap<int> NameIdxMapping;
3572 NameIdxMapping["__"] = -1;
3573
3574 NameIdxMapping["this"] = 0;
3575
3576 int Idx = 1;
3577 for (const ParmVarDecl *PVD : FD->parameters())
3578 NameIdxMapping[PVD->getName()] = Idx++;
3579
3580 auto UnknownName = NameIdxMapping.end();
3581
3582 SmallVector<int, 8> EncodingIndices;
3583 for (unsigned I = 0, E = AL.getNumArgs(); I < E; ++I) {
3584 SourceRange SR;
3585 int32_t ArgIdx;
3586
3587 if (AL.isArgIdent(I)) {
3588 IdentifierLoc *IdLoc = AL.getArgAsIdent(I);
3589 auto It = NameIdxMapping.find(IdLoc->Ident->getName());
3590 if (It == UnknownName) {
3591 S.Diag(AL.getLoc(), diag::err_callback_attribute_argument_unknown)
3592 << IdLoc->Ident << IdLoc->Loc;
3593 return;
3594 }
3595
3596 SR = SourceRange(IdLoc->Loc);
3597 ArgIdx = It->second;
3598 } else if (AL.isArgExpr(I)) {
3599 Expr *IdxExpr = AL.getArgAsExpr(I);
3600
3601 // If the expression is not parseable as an int32_t we have a problem.
3602 if (!checkUInt32Argument(S, AL, IdxExpr, (uint32_t &)ArgIdx, I + 1,
3603 false)) {
3604 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
3605 << AL << (I + 1) << IdxExpr->getSourceRange();
3606 return;
3607 }
3608
3609 // Check oob, excluding the special values, 0 and -1.
3610 if (ArgIdx < -1 || ArgIdx > NumArgs) {
3611 S.Diag(AL.getLoc(), diag::err_attribute_argument_out_of_bounds)
3612 << AL << (I + 1) << IdxExpr->getSourceRange();
3613 return;
3614 }
3615
3616 SR = IdxExpr->getSourceRange();
3617 } else {
3618 llvm_unreachable("Unexpected ParsedAttr argument type!")::llvm::llvm_unreachable_internal("Unexpected ParsedAttr argument type!"
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 3618)
;
3619 }
3620
3621 if (ArgIdx == 0 && !HasImplicitThisParam) {
3622 S.Diag(AL.getLoc(), diag::err_callback_implicit_this_not_available)
3623 << (I + 1) << SR;
3624 return;
3625 }
3626
3627 // Adjust for the case we do not have an implicit "this" parameter. In this
3628 // case we decrease all positive values by 1 to get LLVM argument indices.
3629 if (!HasImplicitThisParam && ArgIdx > 0)
3630 ArgIdx -= 1;
3631
3632 EncodingIndices.push_back(ArgIdx);
3633 }
3634
3635 int CalleeIdx = EncodingIndices.front();
3636 // Check if the callee index is proper, thus not "this" and not "unknown".
3637 // This means the "CalleeIdx" has to be non-negative if "HasImplicitThisParam"
3638 // is false and positive if "HasImplicitThisParam" is true.
3639 if (CalleeIdx < (int)HasImplicitThisParam) {
3640 S.Diag(AL.getLoc(), diag::err_callback_attribute_invalid_callee)
3641 << AL.getRange();
3642 return;
3643 }
3644
3645 // Get the callee type, note the index adjustment as the AST doesn't contain
3646 // the this type (which the callee cannot reference anyway!).
3647 const Type *CalleeType =
3648 getFunctionOrMethodParamType(D, CalleeIdx - HasImplicitThisParam)
3649 .getTypePtr();
3650 if (!CalleeType || !CalleeType->isFunctionPointerType()) {
3651 S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
3652 << AL.getRange();
3653 return;
3654 }
3655
3656 const Type *CalleeFnType =
3657 CalleeType->getPointeeType()->getUnqualifiedDesugaredType();
3658
3659 // TODO: Check the type of the callee arguments.
3660
3661 const auto *CalleeFnProtoType = dyn_cast<FunctionProtoType>(CalleeFnType);
3662 if (!CalleeFnProtoType) {
3663 S.Diag(AL.getLoc(), diag::err_callback_callee_no_function_type)
3664 << AL.getRange();
3665 return;
3666 }
3667
3668 if (CalleeFnProtoType->getNumParams() > EncodingIndices.size() - 1) {
3669 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
3670 << AL << (unsigned)(EncodingIndices.size() - 1);
3671 return;
3672 }
3673
3674 if (CalleeFnProtoType->getNumParams() < EncodingIndices.size() - 1) {
3675 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
3676 << AL << (unsigned)(EncodingIndices.size() - 1);
3677 return;
3678 }
3679
3680 if (CalleeFnProtoType->isVariadic()) {
3681 S.Diag(AL.getLoc(), diag::err_callback_callee_is_variadic) << AL.getRange();
3682 return;
3683 }
3684
3685 // Do not allow multiple callback attributes.
3686 if (D->hasAttr<CallbackAttr>()) {
3687 S.Diag(AL.getLoc(), diag::err_callback_attribute_multiple) << AL.getRange();
3688 return;
3689 }
3690
3691 D->addAttr(::new (S.Context) CallbackAttr(
3692 S.Context, AL, EncodingIndices.data(), EncodingIndices.size()));
3693}
3694
3695static bool isFunctionLike(const Type &T) {
3696 // Check for explicit function types.
3697 // 'called_once' is only supported in Objective-C and it has
3698 // function pointers and block pointers.
3699 return T.isFunctionPointerType() || T.isBlockPointerType();
3700}
3701
3702/// Handle 'called_once' attribute.
3703static void handleCalledOnceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3704 // 'called_once' only applies to parameters representing functions.
3705 QualType T = cast<ParmVarDecl>(D)->getType();
3706
3707 if (!isFunctionLike(*T)) {
3708 S.Diag(AL.getLoc(), diag::err_called_once_attribute_wrong_type);
3709 return;
3710 }
3711
3712 D->addAttr(::new (S.Context) CalledOnceAttr(S.Context, AL));
3713}
3714
3715static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3716 // Try to find the underlying union declaration.
3717 RecordDecl *RD = nullptr;
3718 const auto *TD = dyn_cast<TypedefNameDecl>(D);
3719 if (TD && TD->getUnderlyingType()->isUnionType())
3720 RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
3721 else
3722 RD = dyn_cast<RecordDecl>(D);
3723
3724 if (!RD || !RD->isUnion()) {
3725 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) << AL
3726 << ExpectedUnion;
3727 return;
3728 }
3729
3730 if (!RD->isCompleteDefinition()) {
3731 if (!RD->isBeingDefined())
3732 S.Diag(AL.getLoc(),
3733 diag::warn_transparent_union_attribute_not_definition);
3734 return;
3735 }
3736
3737 RecordDecl::field_iterator Field = RD->field_begin(),
3738 FieldEnd = RD->field_end();
3739 if (Field == FieldEnd) {
3740 S.Diag(AL.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
3741 return;
3742 }
3743
3744 FieldDecl *FirstField = *Field;
3745 QualType FirstType = FirstField->getType();
3746 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
3747 S.Diag(FirstField->getLocation(),
3748 diag::warn_transparent_union_attribute_floating)
3749 << FirstType->isVectorType() << FirstType;
3750 return;
3751 }
3752
3753 if (FirstType->isIncompleteType())
3754 return;
3755 uint64_t FirstSize = S.Context.getTypeSize(FirstType);
3756 uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
3757 for (; Field != FieldEnd; ++Field) {
3758 QualType FieldType = Field->getType();
3759 if (FieldType->isIncompleteType())
3760 return;
3761 // FIXME: this isn't fully correct; we also need to test whether the
3762 // members of the union would all have the same calling convention as the
3763 // first member of the union. Checking just the size and alignment isn't
3764 // sufficient (consider structs passed on the stack instead of in registers
3765 // as an example).
3766 if (S.Context.getTypeSize(FieldType) != FirstSize ||
3767 S.Context.getTypeAlign(FieldType) > FirstAlign) {
3768 // Warn if we drop the attribute.
3769 bool isSize = S.Context.getTypeSize(FieldType) != FirstSize;
3770 unsigned FieldBits = isSize ? S.Context.getTypeSize(FieldType)
3771 : S.Context.getTypeAlign(FieldType);
3772 S.Diag(Field->getLocation(),
3773 diag::warn_transparent_union_attribute_field_size_align)
3774 << isSize << *Field << FieldBits;
3775 unsigned FirstBits = isSize ? FirstSize : FirstAlign;
3776 S.Diag(FirstField->getLocation(),
3777 diag::note_transparent_union_first_field_size_align)
3778 << isSize << FirstBits;
3779 return;
3780 }
3781 }
3782
3783 RD->addAttr(::new (S.Context) TransparentUnionAttr(S.Context, AL));
3784}
3785
3786void Sema::AddAnnotationAttr(Decl *D, const AttributeCommonInfo &CI,
3787 StringRef Str, MutableArrayRef<Expr *> Args) {
3788 auto *Attr = AnnotateAttr::Create(Context, Str, Args.data(), Args.size(), CI);
3789 llvm::SmallVector<PartialDiagnosticAt, 8> Notes;
3790 for (unsigned Idx = 0; Idx < Attr->args_size(); Idx++) {
3791 Expr *&E = Attr->args_begin()[Idx];
3792 assert(E && "error are handled before")((E && "error are handled before") ? static_cast<void
> (0) : __assert_fail ("E && \"error are handled before\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 3792, __PRETTY_FUNCTION__))
;
3793 if (E->isValueDependent() || E->isTypeDependent())
3794 continue;
3795
3796 if (E->getType()->isArrayType())
3797 E = ImpCastExprToType(E, Context.getPointerType(E->getType()),
3798 clang::CK_ArrayToPointerDecay)
3799 .get();
3800 if (E->getType()->isFunctionType())
3801 E = ImplicitCastExpr::Create(Context,
3802 Context.getPointerType(E->getType()),
3803 clang::CK_FunctionToPointerDecay, E, nullptr,
3804 VK_RValue, FPOptionsOverride());
3805 if (E->isLValue())
3806 E = ImplicitCastExpr::Create(Context, E->getType().getNonReferenceType(),
3807 clang::CK_LValueToRValue, E, nullptr,
3808 VK_RValue, FPOptionsOverride());
3809
3810 Expr::EvalResult Eval;
3811 Notes.clear();
3812 Eval.Diag = &Notes;
3813
3814 bool Result =
3815 E->EvaluateAsConstantExpr(Eval, Context);
3816
3817 /// Result means the expression can be folded to a constant.
3818 /// Note.empty() means the expression is a valid constant expression in the
3819 /// current language mode.
3820 if (!Result || !Notes.empty()) {
3821 Diag(E->getBeginLoc(), diag::err_attribute_argument_n_type)
3822 << CI << (Idx + 1) << AANT_ArgumentConstantExpr;
3823 for (auto &Note : Notes)
3824 Diag(Note.first, Note.second);
3825 return;
3826 }
3827 assert(Eval.Val.hasValue())((Eval.Val.hasValue()) ? static_cast<void> (0) : __assert_fail
("Eval.Val.hasValue()", "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 3827, __PRETTY_FUNCTION__))
;
3828 E = ConstantExpr::Create(Context, E, Eval.Val);
3829 }
3830 D->addAttr(Attr);
3831}
3832
3833static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3834 // Make sure that there is a string literal as the annotation's first
3835 // argument.
3836 StringRef Str;
3837 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
3838 return;
3839
3840 llvm::SmallVector<Expr *, 4> Args;
3841 Args.reserve(AL.getNumArgs() - 1);
3842 for (unsigned Idx = 1; Idx < AL.getNumArgs(); Idx++) {
3843 assert(!AL.isArgIdent(Idx))((!AL.isArgIdent(Idx)) ? static_cast<void> (0) : __assert_fail
("!AL.isArgIdent(Idx)", "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 3843, __PRETTY_FUNCTION__))
;
3844 Args.push_back(AL.getArgAsExpr(Idx));
3845 }
3846
3847 S.AddAnnotationAttr(D, AL, Str, Args);
3848}
3849
3850static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3851 S.AddAlignValueAttr(D, AL, AL.getArgAsExpr(0));
3852}
3853
3854void Sema::AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E) {
3855 AlignValueAttr TmpAttr(Context, CI, E);
3856 SourceLocation AttrLoc = CI.getLoc();
3857
3858 QualType T;
3859 if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
3860 T = TD->getUnderlyingType();
3861 else if (const auto *VD = dyn_cast<ValueDecl>(D))
3862 T = VD->getType();
3863 else
3864 llvm_unreachable("Unknown decl type for align_value")::llvm::llvm_unreachable_internal("Unknown decl type for align_value"
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 3864)
;
3865
3866 if (!T->isDependentType() && !T->isAnyPointerType() &&
3867 !T->isReferenceType() && !T->isMemberPointerType()) {
3868 Diag(AttrLoc, diag::warn_attribute_pointer_or_reference_only)
3869 << &TmpAttr << T << D->getSourceRange();
3870 return;
3871 }
3872
3873 if (!E->isValueDependent()) {
3874 llvm::APSInt Alignment;
3875 ExprResult ICE = VerifyIntegerConstantExpression(
3876 E, &Alignment, diag::err_align_value_attribute_argument_not_int);
3877 if (ICE.isInvalid())
3878 return;
3879
3880 if (!Alignment.isPowerOf2()) {
3881 Diag(AttrLoc, diag::err_alignment_not_power_of_two)
3882 << E->getSourceRange();
3883 return;
3884 }
3885
3886 D->addAttr(::new (Context) AlignValueAttr(Context, CI, ICE.get()));
3887 return;
3888 }
3889
3890 // Save dependent expressions in the AST to be instantiated.
3891 D->addAttr(::new (Context) AlignValueAttr(Context, CI, E));
3892}
3893
3894static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3895 // check the attribute arguments.
3896 if (AL.getNumArgs() > 1) {
3897 S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;
3898 return;
3899 }
3900
3901 if (AL.getNumArgs() == 0) {
3902 D->addAttr(::new (S.Context) AlignedAttr(S.Context, AL, true, nullptr));
3903 return;
3904 }
3905
3906 Expr *E = AL.getArgAsExpr(0);
3907 if (AL.isPackExpansion() && !E->containsUnexpandedParameterPack()) {
3908 S.Diag(AL.getEllipsisLoc(),
3909 diag::err_pack_expansion_without_parameter_packs);
3910 return;
3911 }
3912
3913 if (!AL.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E))
3914 return;
3915
3916 S.AddAlignedAttr(D, AL, E, AL.isPackExpansion());
3917}
3918
3919void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
3920 bool IsPackExpansion) {
3921 AlignedAttr TmpAttr(Context, CI, true, E);
3922 SourceLocation AttrLoc = CI.getLoc();
3923
3924 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
3925 if (TmpAttr.isAlignas()) {
3926 // C++11 [dcl.align]p1:
3927 // An alignment-specifier may be applied to a variable or to a class
3928 // data member, but it shall not be applied to a bit-field, a function
3929 // parameter, the formal parameter of a catch clause, or a variable
3930 // declared with the register storage class specifier. An
3931 // alignment-specifier may also be applied to the declaration of a class
3932 // or enumeration type.
3933 // C11 6.7.5/2:
3934 // An alignment attribute shall not be specified in a declaration of
3935 // a typedef, or a bit-field, or a function, or a parameter, or an
3936 // object declared with the register storage-class specifier.
3937 int DiagKind = -1;
3938 if (isa<ParmVarDecl>(D)) {
3939 DiagKind = 0;
3940 } else if (const auto *VD = dyn_cast<VarDecl>(D)) {
3941 if (VD->getStorageClass() == SC_Register)
3942 DiagKind = 1;
3943 if (VD->isExceptionVariable())
3944 DiagKind = 2;
3945 } else if (const auto *FD = dyn_cast<FieldDecl>(D)) {
3946 if (FD->isBitField())
3947 DiagKind = 3;
3948 } else if (!isa<TagDecl>(D)) {
3949 Diag(AttrLoc, diag::err_attribute_wrong_decl_type) << &TmpAttr
3950 << (TmpAttr.isC11() ? ExpectedVariableOrField
3951 : ExpectedVariableFieldOrTag);
3952 return;
3953 }
3954 if (DiagKind != -1) {
3955 Diag(AttrLoc, diag::err_alignas_attribute_wrong_decl_type)
3956 << &TmpAttr << DiagKind;
3957 return;
3958 }
3959 }
3960
3961 if (E->isValueDependent()) {
3962 // We can't support a dependent alignment on a non-dependent type,
3963 // because we have no way to model that a type is "alignment-dependent"
3964 // but not dependent in any other way.
3965 if (const auto *TND = dyn_cast<TypedefNameDecl>(D)) {
3966 if (!TND->getUnderlyingType()->isDependentType()) {
3967 Diag(AttrLoc, diag::err_alignment_dependent_typedef_name)
3968 << E->getSourceRange();
3969 return;
3970 }
3971 }
3972
3973 // Save dependent expressions in the AST to be instantiated.
3974 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, E);
3975 AA->setPackExpansion(IsPackExpansion);
3976 D->addAttr(AA);
3977 return;
3978 }
3979
3980 // FIXME: Cache the number on the AL object?
3981 llvm::APSInt Alignment;
3982 ExprResult ICE = VerifyIntegerConstantExpression(
3983 E, &Alignment, diag::err_aligned_attribute_argument_not_int);
3984 if (ICE.isInvalid())
3985 return;
3986
3987 uint64_t AlignVal = Alignment.getZExtValue();
3988
3989 // C++11 [dcl.align]p2:
3990 // -- if the constant expression evaluates to zero, the alignment
3991 // specifier shall have no effect
3992 // C11 6.7.5p6:
3993 // An alignment specification of zero has no effect.
3994 if (!(TmpAttr.isAlignas() && !Alignment)) {
3995 if (!llvm::isPowerOf2_64(AlignVal)) {
3996 Diag(AttrLoc, diag::err_alignment_not_power_of_two)
3997 << E->getSourceRange();
3998 return;
3999 }
4000 }
4001
4002 unsigned MaximumAlignment = Sema::MaximumAlignment;
4003 if (Context.getTargetInfo().getTriple().isOSBinFormatCOFF())
4004 MaximumAlignment = std::min(MaximumAlignment, 8192u);
4005 if (AlignVal > MaximumAlignment) {
4006 Diag(AttrLoc, diag::err_attribute_aligned_too_great)
4007 << MaximumAlignment << E->getSourceRange();
4008 return;
4009 }
4010
4011 if (Context.getTargetInfo().isTLSSupported()) {
4012 unsigned MaxTLSAlign =
4013 Context.toCharUnitsFromBits(Context.getTargetInfo().getMaxTLSAlign())
4014 .getQuantity();
4015 const auto *VD = dyn_cast<VarDecl>(D);
4016 if (MaxTLSAlign && AlignVal > MaxTLSAlign && VD &&
4017 VD->getTLSKind() != VarDecl::TLS_None) {
4018 Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum)
4019 << (unsigned)AlignVal << VD << MaxTLSAlign;
4020 return;
4021 }
4022 }
4023
4024 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, ICE.get());
4025 AA->setPackExpansion(IsPackExpansion);
4026 D->addAttr(AA);
4027}
4028
4029void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI,
4030 TypeSourceInfo *TS, bool IsPackExpansion) {
4031 // FIXME: Cache the number on the AL object if non-dependent?
4032 // FIXME: Perform checking of type validity
4033 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
4034 AA->setPackExpansion(IsPackExpansion);
4035 D->addAttr(AA);
4036}
4037
4038void Sema::CheckAlignasUnderalignment(Decl *D) {
4039 assert(D->hasAttrs() && "no attributes on decl")((D->hasAttrs() && "no attributes on decl") ? static_cast
<void> (0) : __assert_fail ("D->hasAttrs() && \"no attributes on decl\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 4039, __PRETTY_FUNCTION__))
;
4040
4041 QualType UnderlyingTy, DiagTy;
4042 if (const auto *VD = dyn_cast<ValueDecl>(D)) {
4043 UnderlyingTy = DiagTy = VD->getType();
4044 } else {
4045 UnderlyingTy = DiagTy = Context.getTagDeclType(cast<TagDecl>(D));
4046 if (const auto *ED = dyn_cast<EnumDecl>(D))
4047 UnderlyingTy = ED->getIntegerType();
4048 }
4049 if (DiagTy->isDependentType() || DiagTy->isIncompleteType())
4050 return;
4051
4052 // C++11 [dcl.align]p5, C11 6.7.5/4:
4053 // The combined effect of all alignment attributes in a declaration shall
4054 // not specify an alignment that is less strict than the alignment that
4055 // would otherwise be required for the entity being declared.
4056 AlignedAttr *AlignasAttr = nullptr;
4057 AlignedAttr *LastAlignedAttr = nullptr;
4058 unsigned Align = 0;
4059 for (auto *I : D->specific_attrs<AlignedAttr>()) {
4060 if (I->isAlignmentDependent())
4061 return;
4062 if (I->isAlignas())
4063 AlignasAttr = I;
4064 Align = std::max(Align, I->getAlignment(Context));
4065 LastAlignedAttr = I;
4066 }
4067
4068 if (Align && DiagTy->isSizelessType()) {
4069 Diag(LastAlignedAttr->getLocation(), diag::err_attribute_sizeless_type)
4070 << LastAlignedAttr << DiagTy;
4071 } else if (AlignasAttr && Align) {
4072 CharUnits RequestedAlign = Context.toCharUnitsFromBits(Align);
4073 CharUnits NaturalAlign = Context.getTypeAlignInChars(UnderlyingTy);
4074 if (NaturalAlign > RequestedAlign)
4075 Diag(AlignasAttr->getLocation(), diag::err_alignas_underaligned)
4076 << DiagTy << (unsigned)NaturalAlign.getQuantity();
4077 }
4078}
4079
4080bool Sema::checkMSInheritanceAttrOnDefinition(
4081 CXXRecordDecl *RD, SourceRange Range, bool BestCase,
4082 MSInheritanceModel ExplicitModel) {
4083 assert(RD->hasDefinition() && "RD has no definition!")((RD->hasDefinition() && "RD has no definition!") ?
static_cast<void> (0) : __assert_fail ("RD->hasDefinition() && \"RD has no definition!\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 4083, __PRETTY_FUNCTION__))
;
4084
4085 // We may not have seen base specifiers or any virtual methods yet. We will
4086 // have to wait until the record is defined to catch any mismatches.
4087 if (!RD->getDefinition()->isCompleteDefinition())
4088 return false;
4089
4090 // The unspecified model never matches what a definition could need.
4091 if (ExplicitModel == MSInheritanceModel::Unspecified)
4092 return false;
4093
4094 if (BestCase) {
4095 if (RD->calculateInheritanceModel() == ExplicitModel)
4096 return false;
4097 } else {
4098 if (RD->calculateInheritanceModel() <= ExplicitModel)
4099 return false;
4100 }
4101
4102 Diag(Range.getBegin(), diag::err_mismatched_ms_inheritance)
4103 << 0 /*definition*/;
4104 Diag(RD->getDefinition()->getLocation(), diag::note_defined_here) << RD;
4105 return true;
4106}
4107
4108/// parseModeAttrArg - Parses attribute mode string and returns parsed type
4109/// attribute.
4110static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth,
4111 bool &IntegerMode, bool &ComplexMode,
4112 bool &ExplicitIEEE) {
4113 IntegerMode = true;
4114 ComplexMode = false;
4115 switch (Str.size()) {
4116 case 2:
4117 switch (Str[0]) {
4118 case 'Q':
4119 DestWidth = 8;
4120 break;
4121 case 'H':
4122 DestWidth = 16;
4123 break;
4124 case 'S':
4125 DestWidth = 32;
4126 break;
4127 case 'D':
4128 DestWidth = 64;
4129 break;
4130 case 'X':
4131 DestWidth = 96;
4132 break;
4133 case 'K': // KFmode - IEEE quad precision (__float128)
4134 ExplicitIEEE = true;
4135 DestWidth = Str[1] == 'I' ? 0 : 128;
4136 break;
4137 case 'T':
4138 ExplicitIEEE = false;
4139 DestWidth = 128;
4140 break;
4141 }
4142 if (Str[1] == 'F') {
4143 IntegerMode = false;
4144 } else if (Str[1] == 'C') {
4145 IntegerMode = false;
4146 ComplexMode = true;
4147 } else if (Str[1] != 'I') {
4148 DestWidth = 0;
4149 }
4150 break;
4151 case 4:
4152 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
4153 // pointer on PIC16 and other embedded platforms.
4154 if (Str == "word")
4155 DestWidth = S.Context.getTargetInfo().getRegisterWidth();
4156 else if (Str == "byte")
4157 DestWidth = S.Context.getTargetInfo().getCharWidth();
4158 break;
4159 case 7:
4160 if (Str == "pointer")
4161 DestWidth = S.Context.getTargetInfo().getPointerWidth(0);
4162 break;
4163 case 11:
4164 if (Str == "unwind_word")
4165 DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
4166 break;
4167 }
4168}
4169
4170/// handleModeAttr - This attribute modifies the width of a decl with primitive
4171/// type.
4172///
4173/// Despite what would be logical, the mode attribute is a decl attribute, not a
4174/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
4175/// HImode, not an intermediate pointer.
4176static void handleModeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4177 // This attribute isn't documented, but glibc uses it. It changes
4178 // the width of an int or unsigned int to the specified size.
4179 if (!AL.isArgIdent(0)) {
4180 S.Diag(AL.getLoc(), diag::err_attribute_argument_type)
4181 << AL << AANT_ArgumentIdentifier;
4182 return;
4183 }
4184
4185 IdentifierInfo *Name = AL.getArgAsIdent(0)->Ident;
4186
4187 S.AddModeAttr(D, AL, Name);
4188}
4189
4190void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI,
4191 IdentifierInfo *Name, bool InInstantiation) {
4192 StringRef Str = Name->getName();
4193 normalizeName(Str);
4194 SourceLocation AttrLoc = CI.getLoc();
4195
4196 unsigned DestWidth = 0;
4197 bool IntegerMode = true;
4198 bool ComplexMode = false;
4199 bool ExplicitIEEE = false;
4200 llvm::APInt VectorSize(64, 0);
4201 if (Str.size() >= 4 && Str[0] == 'V') {
4202 // Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2).
4203 size_t StrSize = Str.size();
4204 size_t VectorStringLength = 0;
4205 while ((VectorStringLength + 1) < StrSize &&
4206 isdigit(Str[VectorStringLength + 1]))
4207 ++VectorStringLength;
4208 if (VectorStringLength &&
4209 !Str.substr(1, VectorStringLength).getAsInteger(10, VectorSize) &&
4210 VectorSize.isPowerOf2()) {
4211 parseModeAttrArg(*this, Str.substr(VectorStringLength + 1), DestWidth,
4212 IntegerMode, ComplexMode, ExplicitIEEE);
4213 // Avoid duplicate warning from template instantiation.
4214 if (!InInstantiation)
4215 Diag(AttrLoc, diag::warn_vector_mode_deprecated);
4216 } else {
4217 VectorSize = 0;
4218 }
4219 }
4220
4221 if (!VectorSize)
4222 parseModeAttrArg(*this, Str, DestWidth, IntegerMode, ComplexMode,
4223 ExplicitIEEE);
4224
4225 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
4226 // and friends, at least with glibc.
4227 // FIXME: Make sure floating-point mappings are accurate
4228 // FIXME: Support XF and TF types
4229 if (!DestWidth) {
4230 Diag(AttrLoc, diag::err_machine_mode) << 0 /*Unknown*/ << Name;
4231 return;
4232 }
4233
4234 QualType OldTy;
4235 if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
4236 OldTy = TD->getUnderlyingType();
4237 else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
4238 // Something like 'typedef enum { X } __attribute__((mode(XX))) T;'.
4239 // Try to get type from enum declaration, default to int.
4240 OldTy = ED->getIntegerType();
4241 if (OldTy.isNull())
4242 OldTy = Context.IntTy;
4243 } else
4244 OldTy = cast<ValueDecl>(D)->getType();
4245
4246 if (OldTy->isDependentType()) {
4247 D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
4248 return;
4249 }
4250
4251 // Base type can also be a vector type (see PR17453).
4252 // Distinguish between base type and base element type.
4253 QualType OldElemTy = OldTy;
4254 if (const auto *VT = OldTy->getAs<VectorType>())
4255 OldElemTy = VT->getElementType();
4256
4257 // GCC allows 'mode' attribute on enumeration types (even incomplete), except
4258 // for vector modes. So, 'enum X __attribute__((mode(QI)));' forms a complete
4259 // type, 'enum { A } __attribute__((mode(V4SI)))' is rejected.
4260 if ((isa<EnumDecl>(D) || OldElemTy->getAs<EnumType>()) &&
4261 VectorSize.getBoolValue()) {
4262 Diag(AttrLoc, diag::err_enum_mode_vector_type) << Name << CI.getRange();
4263 return;
4264 }
4265 bool IntegralOrAnyEnumType = (OldElemTy->isIntegralOrEnumerationType() &&
4266 !OldElemTy->isExtIntType()) ||
4267 OldElemTy->getAs<EnumType>();
4268
4269 if (!OldElemTy->getAs<BuiltinType>() && !OldElemTy->isComplexType() &&
4270 !IntegralOrAnyEnumType)
4271 Diag(AttrLoc, diag::err_mode_not_primitive);
4272 else if (IntegerMode) {
4273 if (!IntegralOrAnyEnumType)
4274 Diag(AttrLoc, diag::err_mode_wrong_type);
4275 } else if (ComplexMode) {
4276 if (!OldElemTy->isComplexType())
4277 Diag(AttrLoc, diag::err_mode_wrong_type);
4278 } else {
4279 if (!OldElemTy->isFloatingType())
4280 Diag(AttrLoc, diag::err_mode_wrong_type);
4281 }
4282
4283 QualType NewElemTy;
4284
4285 if (IntegerMode)
4286 NewElemTy = Context.getIntTypeForBitwidth(DestWidth,
4287 OldElemTy->isSignedIntegerType());
4288 else
4289 NewElemTy = Context.getRealTypeForBitwidth(DestWidth, ExplicitIEEE);
4290
4291 if (NewElemTy.isNull()) {
4292 Diag(AttrLoc, diag::err_machine_mode) << 1 /*Unsupported*/ << Name;
4293 return;
4294 }
4295
4296 if (ComplexMode) {
4297 NewElemTy = Context.getComplexType(NewElemTy);
4298 }
4299
4300 QualType NewTy = NewElemTy;
4301 if (VectorSize.getBoolValue()) {
4302 NewTy = Context.getVectorType(NewTy, VectorSize.getZExtValue(),
4303 VectorType::GenericVector);
4304 } else if (const auto *OldVT = OldTy->getAs<VectorType>()) {
4305 // Complex machine mode does not support base vector types.
4306 if (ComplexMode) {
4307 Diag(AttrLoc, diag::err_complex_mode_vector_type);
4308 return;
4309 }
4310 unsigned NumElements = Context.getTypeSize(OldElemTy) *
4311 OldVT->getNumElements() /
4312 Context.getTypeSize(NewElemTy);
4313 NewTy =
4314 Context.getVectorType(NewElemTy, NumElements, OldVT->getVectorKind());
4315 }
4316
4317 if (NewTy.isNull()) {
4318 Diag(AttrLoc, diag::err_mode_wrong_type);
4319 return;
4320 }
4321
4322 // Install the new type.
4323 if (auto *TD = dyn_cast<TypedefNameDecl>(D))
4324 TD->setModedTypeSourceInfo(TD->getTypeSourceInfo(), NewTy);
4325 else if (auto *ED = dyn_cast<EnumDecl>(D))
4326 ED->setIntegerType(NewTy);
4327 else
4328 cast<ValueDecl>(D)->setType(NewTy);
4329
4330 D->addAttr(::new (Context) ModeAttr(Context, CI, Name));
4331}
4332
4333static void handleNoDebugAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4334 D->addAttr(::new (S.Context) NoDebugAttr(S.Context, AL));
4335}
4336
4337AlwaysInlineAttr *Sema::mergeAlwaysInlineAttr(Decl *D,
4338 const AttributeCommonInfo &CI,
4339 const IdentifierInfo *Ident) {
4340 if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
4341 Diag(CI.getLoc(), diag::warn_attribute_ignored) << Ident;
4342 Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
4343 return nullptr;
4344 }
4345
4346 if (D->hasAttr<AlwaysInlineAttr>())
4347 return nullptr;
4348
4349 return ::new (Context) AlwaysInlineAttr(Context, CI);
4350}
4351
4352CommonAttr *Sema::mergeCommonAttr(Decl *D, const ParsedAttr &AL) {
4353 if (checkAttrMutualExclusion<InternalLinkageAttr>(*this, D, AL))
4354 return nullptr;
4355
4356 return ::new (Context) CommonAttr(Context, AL);
4357}
4358
4359CommonAttr *Sema::mergeCommonAttr(Decl *D, const CommonAttr &AL) {
4360 if (checkAttrMutualExclusion<InternalLinkageAttr>(*this, D, AL))
4361 return nullptr;
4362
4363 return ::new (Context) CommonAttr(Context, AL);
4364}
4365
4366InternalLinkageAttr *Sema::mergeInternalLinkageAttr(Decl *D,
4367 const ParsedAttr &AL) {
4368 if (const auto *VD = dyn_cast<VarDecl>(D)) {
4369 // Attribute applies to Var but not any subclass of it (like ParmVar,
4370 // ImplicitParm or VarTemplateSpecialization).
4371 if (VD->getKind() != Decl::Var) {
4372 Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
4373 << AL << (getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass
4374 : ExpectedVariableOrFunction);
4375 return nullptr;
4376 }
4377 // Attribute does not apply to non-static local variables.
4378 if (VD->hasLocalStorage()) {
4379 Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage);
4380 return nullptr;
4381 }
4382 }
4383
4384 if (checkAttrMutualExclusion<CommonAttr>(*this, D, AL))
4385 return nullptr;
4386
4387 return ::new (Context) InternalLinkageAttr(Context, AL);
4388}
4389InternalLinkageAttr *
4390Sema::mergeInternalLinkageAttr(Decl *D, const InternalLinkageAttr &AL) {
4391 if (const auto *VD = dyn_cast<VarDecl>(D)) {
4392 // Attribute applies to Var but not any subclass of it (like ParmVar,
4393 // ImplicitParm or VarTemplateSpecialization).
4394 if (VD->getKind() != Decl::Var) {
4395 Diag(AL.getLocation(), diag::warn_attribute_wrong_decl_type)
4396 << &AL << (getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass
4397 : ExpectedVariableOrFunction);
4398 return nullptr;
4399 }
4400 // Attribute does not apply to non-static local variables.
4401 if (VD->hasLocalStorage()) {
4402 Diag(VD->getLocation(), diag::warn_internal_linkage_local_storage);
4403 return nullptr;
4404 }
4405 }
4406
4407 if (checkAttrMutualExclusion<CommonAttr>(*this, D, AL))
4408 return nullptr;
4409
4410 return ::new (Context) InternalLinkageAttr(Context, AL);
4411}
4412
4413MinSizeAttr *Sema::mergeMinSizeAttr(Decl *D, const AttributeCommonInfo &CI) {
4414 if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
4415 Diag(CI.getLoc(), diag::warn_attribute_ignored) << "'minsize'";
4416 Diag(Optnone->getLocation(), diag::note_conflicting_attribute);
4417 return nullptr;
4418 }
4419
4420 if (D->hasAttr<MinSizeAttr>())
4421 return nullptr;
4422
4423 return ::new (Context) MinSizeAttr(Context, CI);
4424}
4425
4426NoSpeculativeLoadHardeningAttr *Sema::mergeNoSpeculativeLoadHardeningAttr(
4427 Decl *D, const NoSpeculativeLoadHardeningAttr &AL) {
4428 if (checkAttrMutualExclusion<SpeculativeLoadHardeningAttr>(*this, D, AL))
4429 return nullptr;
4430
4431 return ::new (Context) NoSpeculativeLoadHardeningAttr(Context, AL);
4432}
4433
4434SwiftNameAttr *Sema::mergeSwiftNameAttr(Decl *D, const SwiftNameAttr &SNA,
4435 StringRef Name) {
4436 if (const auto *PrevSNA = D->getAttr<SwiftNameAttr>()) {
4437 if (PrevSNA->getName() != Name && !PrevSNA->isImplicit()) {
4438 Diag(PrevSNA->getLocation(), diag::err_attributes_are_not_compatible)
4439 << PrevSNA << &SNA;
4440 Diag(SNA.getLoc(), diag::note_conflicting_attribute);
4441 }
4442
4443 D->dropAttr<SwiftNameAttr>();
4444 }
4445 return ::new (Context) SwiftNameAttr(Context, SNA, Name);
4446}
4447
4448OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D,
4449 const AttributeCommonInfo &CI) {
4450 if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) {
4451 Diag(Inline->getLocation(), diag::warn_attribute_ignored) << Inline;
4452 Diag(CI.getLoc(), diag::note_conflicting_attribute);
4453 D->dropAttr<AlwaysInlineAttr>();
4454 }
4455 if (MinSizeAttr *MinSize = D->getAttr<MinSizeAttr>()) {
4456 Diag(MinSize->getLocation(), diag::warn_attribute_ignored) << MinSize;
4457 Diag(CI.getLoc(), diag::note_conflicting_attribute);
4458 D->dropAttr<MinSizeAttr>();
4459 }
4460
4461 if (D->hasAttr<OptimizeNoneAttr>())
4462 return nullptr;
4463
4464 return ::new (Context) OptimizeNoneAttr(Context, CI);
4465}
4466
4467SpeculativeLoadHardeningAttr *Sema::mergeSpeculativeLoadHardeningAttr(
4468 Decl *D, const SpeculativeLoadHardeningAttr &AL) {
4469 if (checkAttrMutualExclusion<NoSpeculativeLoadHardeningAttr>(*this, D, AL))
4470 return nullptr;
4471
4472 return ::new (Context) SpeculativeLoadHardeningAttr(Context, AL);
4473}
4474
4475static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4476 if (checkAttrMutualExclusion<NotTailCalledAttr>(S, D, AL))
4477 return;
4478
4479 if (AlwaysInlineAttr *Inline =
4480 S.mergeAlwaysInlineAttr(D, AL, AL.getAttrName()))
4481 D->addAttr(Inline);
4482}
4483
4484static void handleMinSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4485 if (MinSizeAttr *MinSize = S.mergeMinSizeAttr(D, AL))
4486 D->addAttr(MinSize);
4487}
4488
4489static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4490 if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr(D, AL))
4491 D->addAttr(Optnone);
4492}
4493
4494static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4495 if (checkAttrMutualExclusion<CUDASharedAttr>(S, D, AL) ||
4496 checkAttrMutualExclusion<HIPManagedAttr>(S, D, AL))
4497 return;
4498 const auto *VD = cast<VarDecl>(D);
4499 if (VD->hasLocalStorage()) {
4500 S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
4501 return;
4502 }
4503 D->addAttr(::new (S.Context) CUDAConstantAttr(S.Context, AL));
4504}
4505
4506static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4507 if (checkAttrMutualExclusion<CUDAConstantAttr>(S, D, AL) ||
4508 checkAttrMutualExclusion<HIPManagedAttr>(S, D, AL))
4509 return;
4510 const auto *VD = cast<VarDecl>(D);
4511 // extern __shared__ is only allowed on arrays with no length (e.g.
4512 // "int x[]").
4513 if (!S.getLangOpts().GPURelocatableDeviceCode && VD->hasExternalStorage() &&
4514 !isa<IncompleteArrayType>(VD->getType())) {
4515 S.Diag(AL.getLoc(), diag::err_cuda_extern_shared) << VD;
4516 return;
4517 }
4518 if (S.getLangOpts().CUDA && VD->hasLocalStorage() &&
4519 S.CUDADiagIfHostCode(AL.getLoc(), diag::err_cuda_host_shared)
4520 << S.CurrentCUDATarget())
4521 return;
4522 D->addAttr(::new (S.Context) CUDASharedAttr(S.Context, AL));
4523}
4524
4525static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4526 if (checkAttrMutualExclusion<CUDADeviceAttr>(S, D, AL) ||
4527 checkAttrMutualExclusion<CUDAHostAttr>(S, D, AL)) {
4528 return;
4529 }
4530 const auto *FD = cast<FunctionDecl>(D);
4531 if (!FD->getReturnType()->isVoidType() &&
4532 !FD->getReturnType()->getAs<AutoType>() &&
4533 !FD->getReturnType()->isInstantiationDependentType()) {
4534 SourceRange RTRange = FD->getReturnTypeSourceRange();
4535 S.Diag(FD->getTypeSpecStartLoc(), diag::err_kern_type_not_void_return)
4536 << FD->getType()
4537 << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void")
4538 : FixItHint());
4539 return;
4540 }
4541 if (const auto *Method = dyn_cast<CXXMethodDecl>(FD)) {
4542 if (Method->isInstance()) {
4543 S.Diag(Method->getBeginLoc(), diag::err_kern_is_nonstatic_method)
4544 << Method;
4545 return;
4546 }
4547 S.Diag(Method->getBeginLoc(), diag::warn_kern_is_method) << Method;
4548 }
4549 // Only warn for "inline" when compiling for host, to cut down on noise.
4550 if (FD->isInlineSpecified() && !S.getLangOpts().CUDAIsDevice)
4551 S.Diag(FD->getBeginLoc(), diag::warn_kern_is_inline) << FD;
4552
4553 D->addAttr(::new (S.Context) CUDAGlobalAttr(S.Context, AL));
4554 // In host compilation the kernel is emitted as a stub function, which is
4555 // a helper function for launching the kernel. The instructions in the helper
4556 // function has nothing to do with the source code of the kernel. Do not emit
4557 // debug info for the stub function to avoid confusing the debugger.
4558 if (S.LangOpts.HIP && !S.LangOpts.CUDAIsDevice)
4559 D->addAttr(NoDebugAttr::CreateImplicit(S.Context));
4560}
4561
4562static void handleDeviceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4563 if (checkAttrMutualExclusion<CUDAGlobalAttr>(S, D, AL)) {
4564 return;
4565 }
4566
4567 if (const auto *VD = dyn_cast<VarDecl>(D)) {
4568 if (VD->hasLocalStorage()) {
4569 S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
4570 return;
4571 }
4572 }
4573
4574 if (auto *A = D->getAttr<CUDADeviceAttr>()) {
4575 if (!A->isImplicit())
4576 return;
4577 D->dropAttr<CUDADeviceAttr>();
4578 }
4579 D->addAttr(::new (S.Context) CUDADeviceAttr(S.Context, AL));
4580}
4581
4582static void handleManagedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4583 if (checkAttrMutualExclusion<CUDAConstantAttr>(S, D, AL) ||
4584 checkAttrMutualExclusion<CUDASharedAttr>(S, D, AL)) {
4585 return;
4586 }
4587
4588 if (const auto *VD = dyn_cast<VarDecl>(D)) {
4589 if (VD->hasLocalStorage()) {
4590 S.Diag(AL.getLoc(), diag::err_cuda_nonstatic_constdev);
4591 return;
4592 }
4593 }
4594 if (!D->hasAttr<HIPManagedAttr>())
4595 D->addAttr(::new (S.Context) HIPManagedAttr(S.Context, AL));
4596 if (!D->hasAttr<CUDADeviceAttr>())
4597 D->addAttr(CUDADeviceAttr::CreateImplicit(S.Context));
4598}
4599
4600static void handleGNUInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4601 const auto *Fn = cast<FunctionDecl>(D);
4602 if (!Fn->isInlineSpecified()) {
4603 S.Diag(AL.getLoc(), diag::warn_gnu_inline_attribute_requires_inline);
4604 return;
4605 }
4606
4607 if (S.LangOpts.CPlusPlus && Fn->getStorageClass() != SC_Extern)
4608 S.Diag(AL.getLoc(), diag::warn_gnu_inline_cplusplus_without_extern);
4609
4610 D->addAttr(::new (S.Context) GNUInlineAttr(S.Context, AL));
4611}
4612
4613static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4614 if (hasDeclarator(D)) return;
4615
4616 // Diagnostic is emitted elsewhere: here we store the (valid) AL
4617 // in the Decl node for syntactic reasoning, e.g., pretty-printing.
4618 CallingConv CC;
4619 if (S.CheckCallingConvAttr(AL, CC, /*FD*/nullptr))
4620 return;
4621
4622 if (!isa<ObjCMethodDecl>(D)) {
4623 S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type)
4624 << AL << ExpectedFunctionOrMethod;
4625 return;
4626 }
4627
4628 switch (AL.getKind()) {
4629 case ParsedAttr::AT_FastCall:
4630 D->addAttr(::new (S.Context) FastCallAttr(S.Context, AL));
4631 return;
4632 case ParsedAttr::AT_StdCall:
4633 D->addAttr(::new (S.Context) StdCallAttr(S.Context, AL));
4634 return;
4635 case ParsedAttr::AT_ThisCall:
4636 D->addAttr(::new (S.Context) ThisCallAttr(S.Context, AL));
4637 return;
4638 case ParsedAttr::AT_CDecl:
4639 D->addAttr(::new (S.Context) CDeclAttr(S.Context, AL));
4640 return;
4641 case ParsedAttr::AT_Pascal:
4642 D->addAttr(::new (S.Context) PascalAttr(S.Context, AL));
4643 return;
4644 case ParsedAttr::AT_SwiftCall:
4645 D->addAttr(::new (S.Context) SwiftCallAttr(S.Context, AL));
4646 return;
4647 case ParsedAttr::AT_VectorCall:
4648 D->addAttr(::new (S.Context) VectorCallAttr(S.Context, AL));
4649 return;
4650 case ParsedAttr::AT_MSABI:
4651 D->addAttr(::new (S.Context) MSABIAttr(S.Context, AL));
4652 return;
4653 case ParsedAttr::AT_SysVABI:
4654 D->addAttr(::new (S.Context) SysVABIAttr(S.Context, AL));
4655 return;
4656 case ParsedAttr::AT_RegCall:
4657 D->addAttr(::new (S.Context) RegCallAttr(S.Context, AL));
4658 return;
4659 case ParsedAttr::AT_Pcs: {
4660 PcsAttr::PCSType PCS;
4661 switch (CC) {
4662 case CC_AAPCS:
4663 PCS = PcsAttr::AAPCS;
4664 break;
4665 case CC_AAPCS_VFP:
4666 PCS = PcsAttr::AAPCS_VFP;
4667 break;
4668 default:
4669 llvm_unreachable("unexpected calling convention in pcs attribute")::llvm::llvm_unreachable_internal("unexpected calling convention in pcs attribute"
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 4669)
;
4670 }
4671
4672 D->addAttr(::new (S.Context) PcsAttr(S.Context, AL, PCS));
4673 return;
4674 }
4675 case ParsedAttr::AT_AArch64VectorPcs:
4676 D->addAttr(::new (S.Context) AArch64VectorPcsAttr(S.Context, AL));
4677 return;
4678 case ParsedAttr::AT_IntelOclBicc:
4679 D->addAttr(::new (S.Context) IntelOclBiccAttr(S.Context, AL));
4680 return;
4681 case ParsedAttr::AT_PreserveMost:
4682 D->addAttr(::new (S.Context) PreserveMostAttr(S.Context, AL));
4683 return;
4684 case ParsedAttr::AT_PreserveAll:
4685 D->addAttr(::new (S.Context) PreserveAllAttr(S.Context, AL));
4686 return;
4687 default:
4688 llvm_unreachable("unexpected attribute kind")::llvm::llvm_unreachable_internal("unexpected attribute kind"
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 4688)
;
4689 }
4690}
4691
4692static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4693 if (!checkAttributeAtLeastNumArgs(S, AL, 1))
4694 return;
4695
4696 std::vector<StringRef> DiagnosticIdentifiers;
4697 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
4698 StringRef RuleName;
4699
4700 if (!S.checkStringLiteralArgumentAttr(AL, I, RuleName, nullptr))
4701 return;
4702
4703 // FIXME: Warn if the rule name is unknown. This is tricky because only
4704 // clang-tidy knows about available rules.
4705 DiagnosticIdentifiers.push_back(RuleName);
4706 }
4707 D->addAttr(::new (S.Context)
4708 SuppressAttr(S.Context, AL, DiagnosticIdentifiers.data(),
4709 DiagnosticIdentifiers.size()));
4710}
4711
4712static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4713 TypeSourceInfo *DerefTypeLoc = nullptr;
4714 QualType ParmType;
4715 if (AL.hasParsedType()) {
4716 ParmType = S.GetTypeFromParser(AL.getTypeArg(), &DerefTypeLoc);
4717
4718 unsigned SelectIdx = ~0U;
4719 if (ParmType->isReferenceType())
4720 SelectIdx = 0;
4721 else if (ParmType->isArrayType())
4722 SelectIdx = 1;
4723
4724 if (SelectIdx != ~0U) {
4725 S.Diag(AL.getLoc(), diag::err_attribute_invalid_argument)
4726 << SelectIdx << AL;
4727 return;
4728 }
4729 }
4730
4731 // To check if earlier decl attributes do not conflict the newly parsed ones
4732 // we always add (and check) the attribute to the cannonical decl.
4733 D = D->getCanonicalDecl();
4734 if (AL.getKind() == ParsedAttr::AT_Owner) {
4735 if (checkAttrMutualExclusion<PointerAttr>(S, D, AL))
4736 return;
4737 if (const auto *OAttr = D->getAttr<OwnerAttr>()) {
4738 const Type *ExistingDerefType = OAttr->getDerefTypeLoc()
4739 ? OAttr->getDerefType().getTypePtr()
4740 : nullptr;
4741 if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
4742 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
4743 << AL << OAttr;
4744 S.Diag(OAttr->getLocation(), diag::note_conflicting_attribute);
4745 }
4746 return;
4747 }
4748 for (Decl *Redecl : D->redecls()) {
4749 Redecl->addAttr(::new (S.Context) OwnerAttr(S.Context, AL, DerefTypeLoc));
4750 }
4751 } else {
4752 if (checkAttrMutualExclusion<OwnerAttr>(S, D, AL))
4753 return;
4754 if (const auto *PAttr = D->getAttr<PointerAttr>()) {
4755 const Type *ExistingDerefType = PAttr->getDerefTypeLoc()
4756 ? PAttr->getDerefType().getTypePtr()
4757 : nullptr;
4758 if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
4759 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
4760 << AL << PAttr;
4761 S.Diag(PAttr->getLocation(), diag::note_conflicting_attribute);
4762 }
4763 return;
4764 }
4765 for (Decl *Redecl : D->redecls()) {
4766 Redecl->addAttr(::new (S.Context)
4767 PointerAttr(S.Context, AL, DerefTypeLoc));
4768 }
4769 }
4770}
4771
4772bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
4773 const FunctionDecl *FD) {
4774 if (Attrs.isInvalid())
4775 return true;
4776
4777 if (Attrs.hasProcessingCache()) {
4778 CC = (CallingConv) Attrs.getProcessingCache();
4779 return false;
4780 }
4781
4782 unsigned ReqArgs = Attrs.getKind() == ParsedAttr::AT_Pcs ? 1 : 0;
4783 if (!checkAttributeNumArgs(*this, Attrs, ReqArgs)) {
4784 Attrs.setInvalid();
4785 return true;
4786 }
4787
4788 // TODO: diagnose uses of these conventions on the wrong target.
4789 switch (Attrs.getKind()) {
4790 case ParsedAttr::AT_CDecl:
4791 CC = CC_C;
4792 break;
4793 case ParsedAttr::AT_FastCall:
4794 CC = CC_X86FastCall;
4795 break;
4796 case ParsedAttr::AT_StdCall:
4797 CC = CC_X86StdCall;
4798 break;
4799 case ParsedAttr::AT_ThisCall:
4800 CC = CC_X86ThisCall;
4801 break;
4802 case ParsedAttr::AT_Pascal:
4803 CC = CC_X86Pascal;
4804 break;
4805 case ParsedAttr::AT_SwiftCall:
4806 CC = CC_Swift;
4807 break;
4808 case ParsedAttr::AT_VectorCall:
4809 CC = CC_X86VectorCall;
4810 break;
4811 case ParsedAttr::AT_AArch64VectorPcs:
4812 CC = CC_AArch64VectorCall;
4813 break;
4814 case ParsedAttr::AT_RegCall:
4815 CC = CC_X86RegCall;
4816 break;
4817 case ParsedAttr::AT_MSABI:
4818 CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :
4819 CC_Win64;
4820 break;
4821 case ParsedAttr::AT_SysVABI:
4822 CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV :
4823 CC_C;
4824 break;
4825 case ParsedAttr::AT_Pcs: {
4826 StringRef StrRef;
4827 if (!checkStringLiteralArgumentAttr(Attrs, 0, StrRef)) {
4828 Attrs.setInvalid();
4829 return true;
4830 }
4831 if (StrRef == "aapcs") {
4832 CC = CC_AAPCS;
4833 break;
4834 } else if (StrRef == "aapcs-vfp") {
4835 CC = CC_AAPCS_VFP;
4836 break;
4837 }
4838
4839 Attrs.setInvalid();
4840 Diag(Attrs.getLoc(), diag::err_invalid_pcs);
4841 return true;
4842 }
4843 case ParsedAttr::AT_IntelOclBicc:
4844 CC = CC_IntelOclBicc;
4845 break;
4846 case ParsedAttr::AT_PreserveMost:
4847 CC = CC_PreserveMost;
4848 break;
4849 case ParsedAttr::AT_PreserveAll:
4850 CC = CC_PreserveAll;
4851 break;
4852 default: llvm_unreachable("unexpected attribute kind")::llvm::llvm_unreachable_internal("unexpected attribute kind"
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 4852)
;
4853 }
4854
4855 TargetInfo::CallingConvCheckResult A = TargetInfo::CCCR_OK;
4856 const TargetInfo &TI = Context.getTargetInfo();
4857 // CUDA functions may have host and/or device attributes which indicate
4858 // their targeted execution environment, therefore the calling convention
4859 // of functions in CUDA should be checked against the target deduced based
4860 // on their host/device attributes.
4861 if (LangOpts.CUDA) {
4862 auto *Aux = Context.getAuxTargetInfo();
4863 auto CudaTarget = IdentifyCUDATarget(FD);
4864 bool CheckHost = false, CheckDevice = false;
4865 switch (CudaTarget) {
4866 case CFT_HostDevice:
4867 CheckHost = true;
4868 CheckDevice = true;
4869 break;
4870 case CFT_Host:
4871 CheckHost = true;
4872 break;
4873 case CFT_Device:
4874 case CFT_Global:
4875 CheckDevice = true;
4876 break;
4877 case CFT_InvalidTarget:
4878 llvm_unreachable("unexpected cuda target")::llvm::llvm_unreachable_internal("unexpected cuda target", "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 4878)
;
4879 }
4880 auto *HostTI = LangOpts.CUDAIsDevice ? Aux : &TI;
4881 auto *DeviceTI = LangOpts.CUDAIsDevice ? &TI : Aux;
4882 if (CheckHost && HostTI)
4883 A = HostTI->checkCallingConvention(CC);
4884 if (A == TargetInfo::CCCR_OK && CheckDevice && DeviceTI)
4885 A = DeviceTI->checkCallingConvention(CC);
4886 } else {
4887 A = TI.checkCallingConvention(CC);
4888 }
4889
4890 switch (A) {
4891 case TargetInfo::CCCR_OK:
4892 break;
4893
4894 case TargetInfo::CCCR_Ignore:
4895 // Treat an ignored convention as if it was an explicit C calling convention
4896 // attribute. For example, __stdcall on Win x64 functions as __cdecl, so
4897 // that command line flags that change the default convention to
4898 // __vectorcall don't affect declarations marked __stdcall.
4899 CC = CC_C;
4900 break;
4901
4902 case TargetInfo::CCCR_Error:
4903 Diag(Attrs.getLoc(), diag::error_cconv_unsupported)
4904 << Attrs << (int)CallingConventionIgnoredReason::ForThisTarget;
4905 break;
4906
4907 case TargetInfo::CCCR_Warning: {
4908 Diag(Attrs.getLoc(), diag::warn_cconv_unsupported)
4909 << Attrs << (int)CallingConventionIgnoredReason::ForThisTarget;
4910
4911 // This convention is not valid for the target. Use the default function or
4912 // method calling convention.
4913 bool IsCXXMethod = false, IsVariadic = false;
4914 if (FD) {
4915 IsCXXMethod = FD->isCXXInstanceMember();
4916 IsVariadic = FD->isVariadic();
4917 }
4918 CC = Context.getDefaultCallingConvention(IsVariadic, IsCXXMethod);
4919 break;
4920 }
4921 }
4922
4923 Attrs.setProcessingCache((unsigned) CC);
4924 return false;
4925}
4926
4927/// Pointer-like types in the default address space.
4928static bool isValidSwiftContextType(QualType Ty) {
4929 if (!Ty->hasPointerRepresentation())
4930 return Ty->isDependentType();
4931 return Ty->getPointeeType().getAddressSpace() == LangAS::Default;
4932}
4933
4934/// Pointers and references in the default address space.
4935static bool isValidSwiftIndirectResultType(QualType Ty) {
4936 if (const auto *PtrType = Ty->getAs<PointerType>()) {
4937 Ty = PtrType->getPointeeType();
4938 } else if (const auto *RefType = Ty->getAs<ReferenceType>()) {
4939 Ty = RefType->getPointeeType();
4940 } else {
4941 return Ty->isDependentType();
4942 }
4943 return Ty.getAddressSpace() == LangAS::Default;
4944}
4945
4946/// Pointers and references to pointers in the default address space.
4947static bool isValidSwiftErrorResultType(QualType Ty) {
4948 if (const auto *PtrType = Ty->getAs<PointerType>()) {
4949 Ty = PtrType->getPointeeType();
4950 } else if (const auto *RefType = Ty->getAs<ReferenceType>()) {
4951 Ty = RefType->getPointeeType();
4952 } else {
4953 return Ty->isDependentType();
4954 }
4955 if (!Ty.getQualifiers().empty())
4956 return false;
4957 return isValidSwiftContextType(Ty);
4958}
4959
4960void Sema::AddParameterABIAttr(Decl *D, const AttributeCommonInfo &CI,
4961 ParameterABI abi) {
4962
4963 QualType type = cast<ParmVarDecl>(D)->getType();
4964
4965 if (auto existingAttr = D->getAttr<ParameterABIAttr>()) {
4966 if (existingAttr->getABI() != abi) {
4967 Diag(CI.getLoc(), diag::err_attributes_are_not_compatible)
4968 << getParameterABISpelling(abi) << existingAttr;
4969 Diag(existingAttr->getLocation(), diag::note_conflicting_attribute);
4970 return;
4971 }
4972 }
4973
4974 switch (abi) {
4975 case ParameterABI::Ordinary:
4976 llvm_unreachable("explicit attribute for ordinary parameter ABI?")::llvm::llvm_unreachable_internal("explicit attribute for ordinary parameter ABI?"
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 4976)
;
4977
4978 case ParameterABI::SwiftContext:
4979 if (!isValidSwiftContextType(type)) {
4980 Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
4981 << getParameterABISpelling(abi) << /*pointer to pointer */ 0 << type;
4982 }
4983 D->addAttr(::new (Context) SwiftContextAttr(Context, CI));
4984 return;
4985
4986 case ParameterABI::SwiftErrorResult:
4987 if (!isValidSwiftErrorResultType(type)) {
4988 Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
4989 << getParameterABISpelling(abi) << /*pointer to pointer */ 1 << type;
4990 }
4991 D->addAttr(::new (Context) SwiftErrorResultAttr(Context, CI));
4992 return;
4993
4994 case ParameterABI::SwiftIndirectResult:
4995 if (!isValidSwiftIndirectResultType(type)) {
4996 Diag(CI.getLoc(), diag::err_swift_abi_parameter_wrong_type)
4997 << getParameterABISpelling(abi) << /*pointer*/ 0 << type;
4998 }
4999 D->addAttr(::new (Context) SwiftIndirectResultAttr(Context, CI));
5000 return;
5001 }
5002 llvm_unreachable("bad parameter ABI attribute")::llvm::llvm_unreachable_internal("bad parameter ABI attribute"
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 5002)
;
5003}
5004
5005/// Checks a regparm attribute, returning true if it is ill-formed and
5006/// otherwise setting numParams to the appropriate value.
5007bool Sema::CheckRegparmAttr(const ParsedAttr &AL, unsigned &numParams) {
5008 if (AL.isInvalid())
5009 return true;
5010
5011 if (!checkAttributeNumArgs(*this, AL, 1)) {
5012 AL.setInvalid();
5013 return true;
5014 }
5015
5016 uint32_t NP;
5017 Expr *NumParamsExpr = AL.getArgAsExpr(0);
5018 if (!checkUInt32Argument(*this, AL, NumParamsExpr, NP)) {
5019 AL.setInvalid();
5020 return true;
5021 }
5022
5023 if (Context.getTargetInfo().getRegParmMax() == 0) {
5024 Diag(AL.getLoc(), diag::err_attribute_regparm_wrong_platform)
5025 << NumParamsExpr->getSourceRange();
5026 AL.setInvalid();
5027 return true;
5028 }
5029
5030 numParams = NP;
5031 if (numParams > Context.getTargetInfo().getRegParmMax()) {
5032 Diag(AL.getLoc(), diag::err_attribute_regparm_invalid_number)
5033 << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
5034 AL.setInvalid();
5035 return true;
5036 }
5037
5038 return false;
5039}
5040
5041// Checks whether an argument of launch_bounds attribute is
5042// acceptable, performs implicit conversion to Rvalue, and returns
5043// non-nullptr Expr result on success. Otherwise, it returns nullptr
5044// and may output an error.
5045static Expr *makeLaunchBoundsArgExpr(Sema &S, Expr *E,
5046 const CUDALaunchBoundsAttr &AL,
5047 const unsigned Idx) {
5048 if (S.DiagnoseUnexpandedParameterPack(E))
5049 return nullptr;
5050
5051 // Accept template arguments for now as they depend on something else.
5052 // We'll get to check them when they eventually get instantiated.
5053 if (E->isValueDependent())
5054 return E;
5055
5056 Optional<llvm::APSInt> I = llvm::APSInt(64);
5057 if (!(I = E->getIntegerConstantExpr(S.Context))) {
5058 S.Diag(E->getExprLoc(), diag::err_attribute_argument_n_type)
5059 << &AL << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
5060 return nullptr;
5061 }
5062 // Make sure we can fit it in 32 bits.
5063 if (!I->isIntN(32)) {
5064 S.Diag(E->getExprLoc(), diag::err_ice_too_large)
5065 << I->toString(10, false) << 32 << /* Unsigned */ 1;
5066 return nullptr;
5067 }
5068 if (*I < 0)
5069 S.Diag(E->getExprLoc(), diag::warn_attribute_argument_n_negative)
5070 << &AL << Idx << E->getSourceRange();
5071
5072 // We may need to perform implicit conversion of the argument.
5073 InitializedEntity Entity = InitializedEntity::InitializeParameter(
5074 S.Context, S.Context.getConstType(S.Context.IntTy), /*consume*/ false);
5075 ExprResult ValArg = S.PerformCopyInitialization(Entity, SourceLocation(), E);
5076 assert(!ValArg.isInvalid() &&((!ValArg.isInvalid() && "Unexpected PerformCopyInitialization() failure."
) ? static_cast<void> (0) : __assert_fail ("!ValArg.isInvalid() && \"Unexpected PerformCopyInitialization() failure.\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 5077, __PRETTY_FUNCTION__))
5077 "Unexpected PerformCopyInitialization() failure.")((!ValArg.isInvalid() && "Unexpected PerformCopyInitialization() failure."
) ? static_cast<void> (0) : __assert_fail ("!ValArg.isInvalid() && \"Unexpected PerformCopyInitialization() failure.\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 5077, __PRETTY_FUNCTION__))
;
5078
5079 return ValArg.getAs<Expr>();
5080}
5081
5082void Sema::AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI,
5083 Expr *MaxThreads, Expr *MinBlocks) {
5084 CUDALaunchBoundsAttr TmpAttr(Context, CI, MaxThreads, MinBlocks);
5085 MaxThreads = makeLaunchBoundsArgExpr(*this, MaxThreads, TmpAttr, 0);
5086 if (MaxThreads == nullptr)
5087 return;
5088
5089 if (MinBlocks) {
5090 MinBlocks = makeLaunchBoundsArgExpr(*this, MinBlocks, TmpAttr, 1);
5091 if (MinBlocks == nullptr)
5092 return;
5093 }
5094
5095 D->addAttr(::new (Context)
5096 CUDALaunchBoundsAttr(Context, CI, MaxThreads, MinBlocks));
5097}
5098
5099static void handleLaunchBoundsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5100 if (!checkAttributeAtLeastNumArgs(S, AL, 1) ||
5101 !checkAttributeAtMostNumArgs(S, AL, 2))
5102 return;
5103
5104 S.AddLaunchBoundsAttr(D, AL, AL.getArgAsExpr(0),
5105 AL.getNumArgs() > 1 ? AL.getArgAsExpr(1) : nullptr);
5106}
5107
5108static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
5109 const ParsedAttr &AL) {
5110 if (!AL.isArgIdent(0)) {
5111 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
5112 << AL << /* arg num = */ 1 << AANT_ArgumentIdentifier;
5113 return;
5114 }
5115
5116 ParamIdx ArgumentIdx;
5117 if (!checkFunctionOrMethodParameterIndex(S, D, AL, 2, AL.getArgAsExpr(1),
5118 ArgumentIdx))
5119 return;
5120
5121 ParamIdx TypeTagIdx;
5122 if (!checkFunctionOrMethodParameterIndex(S, D, AL, 3, AL.getArgAsExpr(2),
5123 TypeTagIdx))
5124 return;
5125
5126 bool IsPointer = AL.getAttrName()->getName() == "pointer_with_type_tag";
5127 if (IsPointer) {
5128 // Ensure that buffer has a pointer type.
5129 unsigned ArgumentIdxAST = ArgumentIdx.getASTIndex();
5130 if (ArgumentIdxAST >= getFunctionOrMethodNumParams(D) ||
5131 !getFunctionOrMethodParamType(D, ArgumentIdxAST)->isPointerType())
5132 S.Diag(AL.getLoc(), diag::err_attribute_pointers_only) << AL << 0;
5133 }
5134
5135 D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr(
5136 S.Context, AL, AL.getArgAsIdent(0)->Ident, ArgumentIdx, TypeTagIdx,
5137 IsPointer));
5138}
5139
5140static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
5141 const ParsedAttr &AL) {
5142 if (!AL.isArgIdent(0)) {
5143 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
5144 << AL << 1 << AANT_ArgumentIdentifier;
5145 return;
5146 }
5147
5148 if (!checkAttributeNumArgs(S, AL, 1))
5149 return;
5150
5151 if (!isa<VarDecl>(D)) {
5152 S.Diag(AL.getLoc(), diag::err_attribute_wrong_decl_type)
5153 << AL << ExpectedVariable;
5154 return;
5155 }
5156
5157 IdentifierInfo *PointerKind = AL.getArgAsIdent(0)->Ident;
5158 TypeSourceInfo *MatchingCTypeLoc = nullptr;
5159 S.GetTypeFromParser(AL.getMatchingCType(), &MatchingCTypeLoc);
5160 assert(MatchingCTypeLoc && "no type source info for attribute argument")((MatchingCTypeLoc && "no type source info for attribute argument"
) ? static_cast<void> (0) : __assert_fail ("MatchingCTypeLoc && \"no type source info for attribute argument\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 5160, __PRETTY_FUNCTION__))
;
5161
5162 D->addAttr(::new (S.Context) TypeTagForDatatypeAttr(
5163 S.Context, AL, PointerKind, MatchingCTypeLoc, AL.getLayoutCompatible(),
5164 AL.getMustBeNull()));
5165}
5166
5167static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5168 ParamIdx ArgCount;
5169
5170 if (!checkFunctionOrMethodParameterIndex(S, D, AL, 1, AL.getArgAsExpr(0),
5171 ArgCount,
5172 true /* CanIndexImplicitThis */))
5173 return;
5174
5175 // ArgCount isn't a parameter index [0;n), it's a count [1;n]
5176 D->addAttr(::new (S.Context)
5177 XRayLogArgsAttr(S.Context, AL, ArgCount.getSourceIndex()));
5178}
5179
5180static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D,
5181 const ParsedAttr &AL) {
5182 uint32_t Count = 0, Offset = 0;
5183 if (!checkUInt32Argument(S, AL, AL.getArgAsExpr(0), Count, 0, true))
5184 return;
5185 if (AL.getNumArgs() == 2) {
5186 Expr *Arg = AL.getArgAsExpr(1);
5187 if (!checkUInt32Argument(S, AL, Arg, Offset, 1, true))
5188 return;
5189 if (Count < Offset) {
5190 S.Diag(getAttrLoc(AL), diag::err_attribute_argument_out_of_range)
5191 << &AL << 0 << Count << Arg->getBeginLoc();
5192 return;
5193 }
5194 }
5195 D->addAttr(::new (S.Context)
5196 PatchableFunctionEntryAttr(S.Context, AL, Count, Offset));
5197}
5198
5199namespace {
5200struct IntrinToName {
5201 uint32_t Id;
5202 int32_t FullName;
5203 int32_t ShortName;
5204};
5205} // unnamed namespace
5206
5207static bool ArmBuiltinAliasValid(unsigned BuiltinID, StringRef AliasName,
5208 ArrayRef<IntrinToName> Map,
5209 const char *IntrinNames) {
5210 if (AliasName.startswith("__arm_"))
5211 AliasName = AliasName.substr(6);
5212 const IntrinToName *It = std::lower_bound(
5213 Map.begin(), Map.end(), BuiltinID,
5214 [](const IntrinToName &L, unsigned Id) { return L.Id < Id; });
5215 if (It == Map.end() || It->Id != BuiltinID)
5216 return false;
5217 StringRef FullName(&IntrinNames[It->FullName]);
5218 if (AliasName == FullName)
5219 return true;
5220 if (It->ShortName == -1)
5221 return false;
5222 StringRef ShortName(&IntrinNames[It->ShortName]);
5223 return AliasName == ShortName;
5224}
5225
5226static bool ArmMveAliasValid(unsigned BuiltinID, StringRef AliasName) {
5227#include "clang/Basic/arm_mve_builtin_aliases.inc"
5228 // The included file defines:
5229 // - ArrayRef<IntrinToName> Map
5230 // - const char IntrinNames[]
5231 return ArmBuiltinAliasValid(BuiltinID, AliasName, Map, IntrinNames);
5232}
5233
5234static bool ArmCdeAliasValid(unsigned BuiltinID, StringRef AliasName) {
5235#include "clang/Basic/arm_cde_builtin_aliases.inc"
5236 return ArmBuiltinAliasValid(BuiltinID, AliasName, Map, IntrinNames);
5237}
5238
5239static bool ArmSveAliasValid(unsigned BuiltinID, StringRef AliasName) {
5240 switch (BuiltinID) {
5241 default:
5242 return false;
5243#define GET_SVE_BUILTINS
5244#define BUILTIN(name, types, attr)case SVE::BIname: case SVE::BI##name:
5245#include "clang/Basic/arm_sve_builtins.inc"
5246 return true;
5247 }
5248}
5249
5250static void handleArmBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5251 if (!AL.isArgIdent(0)) {
5252 S.Diag(AL.getLoc(), diag::err_attribute_argument_n_type)
5253 << AL << 1 << AANT_ArgumentIdentifier;
5254 return;
5255 }
5256
5257 IdentifierInfo *Ident = AL.getArgAsIdent(0)->Ident;
5258 unsigned BuiltinID = Ident->getBuiltinID();
5259 StringRef AliasName = cast<FunctionDecl>(D)->getIdentifier()->getName();
5260
5261 bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
5262 if ((IsAArch64 && !ArmSveAliasValid(BuiltinID, AliasName)) ||
5263 (!IsAArch64 && !ArmMveAliasValid(BuiltinID, AliasName) &&
5264 !ArmCdeAliasValid(BuiltinID, AliasName))) {
5265 S.Diag(AL.getLoc(), diag::err_attribute_arm_builtin_alias);
5266 return;
5267 }
5268
5269 D->addAttr(::new (S.Context) ArmBuiltinAliasAttr(S.Context, AL, Ident));
5270}
5271
5272//===----------------------------------------------------------------------===//
5273// Checker-specific attribute handlers.
5274//===----------------------------------------------------------------------===//
5275static bool isValidSubjectOfNSReturnsRetainedAttribute(QualType QT) {
5276 return QT->isDependentType() || QT->isObjCRetainableType();
5277}
5278
5279static bool isValidSubjectOfNSAttribute(QualType QT) {
5280 return QT->isDependentType() || QT->isObjCObjectPointerType() ||
5281 QT->isObjCNSObjectType();
5282}
5283
5284static bool isValidSubjectOfCFAttribute(QualType QT) {
5285 return QT->isDependentType() || QT->isPointerType() ||
5286 isValidSubjectOfNSAttribute(QT);
5287}
5288
5289static bool isValidSubjectOfOSAttribute(QualType QT) {
5290 if (QT->isDependentType())
5291 return true;
5292 QualType PT = QT->getPointeeType();
5293 return !PT.isNull() && PT->getAsCXXRecordDecl() != nullptr;
5294}
5295
5296void Sema::AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI,
5297 RetainOwnershipKind K,
5298 bool IsTemplateInstantiation) {
5299 ValueDecl *VD = cast<ValueDecl>(D);
5300 switch (K) {
5301 case RetainOwnershipKind::OS:
5302 handleSimpleAttributeOrDiagnose<OSConsumedAttr>(
5303 *this, VD, CI, isValidSubjectOfOSAttribute(VD->getType()),
5304 diag::warn_ns_attribute_wrong_parameter_type,
5305 /*ExtraArgs=*/CI.getRange(), "os_consumed", /*pointers*/ 1);
5306 return;
5307 case RetainOwnershipKind::NS:
5308 handleSimpleAttributeOrDiagnose<NSConsumedAttr>(
5309 *this, VD, CI, isValidSubjectOfNSAttribute(VD->getType()),
5310
5311 // These attributes are normally just advisory, but in ARC, ns_consumed
5312 // is significant. Allow non-dependent code to contain inappropriate
5313 // attributes even in ARC, but require template instantiations to be
5314 // set up correctly.
5315 ((IsTemplateInstantiation && getLangOpts().ObjCAutoRefCount)
5316 ? diag::err_ns_attribute_wrong_parameter_type
5317 : diag::warn_ns_attribute_wrong_parameter_type),
5318 /*ExtraArgs=*/CI.getRange(), "ns_consumed", /*objc pointers*/ 0);
5319 return;
5320 case RetainOwnershipKind::CF:
5321 handleSimpleAttributeOrDiagnose<CFConsumedAttr>(
5322 *this, VD, CI, isValidSubjectOfCFAttribute(VD->getType()),
5323 diag::warn_ns_attribute_wrong_parameter_type,
5324 /*ExtraArgs=*/CI.getRange(), "cf_consumed", /*pointers*/ 1);
5325 return;
5326 }
5327}
5328
5329static Sema::RetainOwnershipKind
5330parsedAttrToRetainOwnershipKind(const ParsedAttr &AL) {
5331 switch (AL.getKind()) {
5332 case ParsedAttr::AT_CFConsumed:
5333 case ParsedAttr::AT_CFReturnsRetained:
5334 case ParsedAttr::AT_CFReturnsNotRetained:
5335 return Sema::RetainOwnershipKind::CF;
5336 case ParsedAttr::AT_OSConsumesThis:
5337 case ParsedAttr::AT_OSConsumed:
5338 case ParsedAttr::AT_OSReturnsRetained:
5339 case ParsedAttr::AT_OSReturnsNotRetained:
5340 case ParsedAttr::AT_OSReturnsRetainedOnZero:
5341 case ParsedAttr::AT_OSReturnsRetainedOnNonZero:
5342 return Sema::RetainOwnershipKind::OS;
5343 case ParsedAttr::AT_NSConsumesSelf:
5344 case ParsedAttr::AT_NSConsumed:
5345 case ParsedAttr::AT_NSReturnsRetained:
5346 case ParsedAttr::AT_NSReturnsNotRetained:
5347 case ParsedAttr::AT_NSReturnsAutoreleased:
5348 return Sema::RetainOwnershipKind::NS;
5349 default:
5350 llvm_unreachable("Wrong argument supplied")::llvm::llvm_unreachable_internal("Wrong argument supplied", "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 5350)
;
5351 }
5352}
5353
5354bool Sema::checkNSReturnsRetainedReturnType(SourceLocation Loc, QualType QT) {
5355 if (isValidSubjectOfNSReturnsRetainedAttribute(QT))
5356 return false;
5357
5358 Diag(Loc, diag::warn_ns_attribute_wrong_return_type)
5359 << "'ns_returns_retained'" << 0 << 0;
5360 return true;
5361}
5362
5363/// \return whether the parameter is a pointer to OSObject pointer.
5364static bool isValidOSObjectOutParameter(const Decl *D) {
5365 const auto *PVD = dyn_cast<ParmVarDecl>(D);
5366 if (!PVD)
5367 return false;
5368 QualType QT = PVD->getType();
5369 QualType PT = QT->getPointeeType();
5370 return !PT.isNull() && isValidSubjectOfOSAttribute(PT);
5371}
5372
5373static void handleXReturnsXRetainedAttr(Sema &S, Decl *D,
5374 const ParsedAttr &AL) {
5375 QualType ReturnType;
5376 Sema::RetainOwnershipKind K = parsedAttrToRetainOwnershipKind(AL);
5377
5378 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
5379 ReturnType = MD->getReturnType();
5380 } else if (S.getLangOpts().ObjCAutoRefCount && hasDeclarator(D) &&
5381 (AL.getKind() == ParsedAttr::AT_NSReturnsRetained)) {
5382 return; // ignore: was handled as a type attribute
5383 } else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(D)) {
5384 ReturnType = PD->getType();
5385 } else if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
5386 ReturnType = FD->getReturnType();
5387 } else if (const auto *Param = dyn_cast<ParmVarDecl>(D)) {
5388 // Attributes on parameters are used for out-parameters,
5389 // passed as pointers-to-pointers.
5390 unsigned DiagID = K == Sema::RetainOwnershipKind::CF
5391 ? /*pointer-to-CF-pointer*/2
5392 : /*pointer-to-OSObject-pointer*/3;
5393 ReturnType = Param->getType()->getPointeeType();
5394 if (ReturnType.isNull()) {
5395 S.Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type)
5396 << AL << DiagID << AL.getRange();
5397 return;
5398 }
5399 } else if (AL.isUsedAsTypeAttr()) {
5400 return;
5401 } else {
5402 AttributeDeclKind ExpectedDeclKind;
5403 switch (AL.getKind()) {
5404 default: llvm_unreachable("invalid ownership attribute")::llvm::llvm_unreachable_internal("invalid ownership attribute"
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 5404)
;
5405 case ParsedAttr::AT_NSReturnsRetained:
5406 case ParsedAttr::AT_NSReturnsAutoreleased:
5407 case ParsedAttr::AT_NSReturnsNotRetained:
5408 ExpectedDeclKind = ExpectedFunctionOrMethod;
5409 break;
5410
5411 case ParsedAttr::AT_OSReturnsRetained:
5412 case ParsedAttr::AT_OSReturnsNotRetained:
5413 case ParsedAttr::AT_CFReturnsRetained:
5414 case ParsedAttr::AT_CFReturnsNotRetained:
5415 ExpectedDeclKind = ExpectedFunctionMethodOrParameter;
5416 break;
5417 }
5418 S.Diag(D->getBeginLoc(), diag::warn_attribute_wrong_decl_type)
5419 << AL.getRange() << AL << ExpectedDeclKind;
5420 return;
5421 }
5422
5423 bool TypeOK;
5424 bool Cf;
5425 unsigned ParmDiagID = 2; // Pointer-to-CF-pointer
5426 switch (AL.getKind()) {
5427 default: llvm_unreachable("invalid ownership attribute")::llvm::llvm_unreachable_internal("invalid ownership attribute"
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 5427)
;
5428 case ParsedAttr::AT_NSReturnsRetained:
5429 TypeOK = isValidSubjectOfNSReturnsRetainedAttribute(ReturnType);
5430 Cf = false;
5431 break;
5432
5433 case ParsedAttr::AT_NSReturnsAutoreleased:
5434 case ParsedAttr::AT_NSReturnsNotRetained:
5435 TypeOK = isValidSubjectOfNSAttribute(ReturnType);
5436 Cf = false;
5437 break;
5438
5439 case ParsedAttr::AT_CFReturnsRetained:
5440 case ParsedAttr::AT_CFReturnsNotRetained:
5441 TypeOK = isValidSubjectOfCFAttribute(ReturnType);
5442 Cf = true;
5443 break;
5444
5445 case ParsedAttr::AT_OSReturnsRetained:
5446 case ParsedAttr::AT_OSReturnsNotRetained:
5447 TypeOK = isValidSubjectOfOSAttribute(ReturnType);
5448 Cf = true;
5449 ParmDiagID = 3; // Pointer-to-OSObject-pointer
5450 break;
5451 }
5452
5453 if (!TypeOK) {
5454 if (AL.isUsedAsTypeAttr())
5455 return;
5456
5457 if (isa<ParmVarDecl>(D)) {
5458 S.Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_parameter_type)
5459 << AL << ParmDiagID << AL.getRange();
5460 } else {
5461 // Needs to be kept in sync with warn_ns_attribute_wrong_return_type.
5462 enum : unsigned {
5463 Function,
5464 Method,
5465 Property
5466 } SubjectKind = Function;
5467 if (isa<ObjCMethodDecl>(D))
5468 SubjectKind = Method;
5469 else if (isa<ObjCPropertyDecl>(D))
5470 SubjectKind = Property;
5471 S.Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type)
5472 << AL << SubjectKind << Cf << AL.getRange();
5473 }
5474 return;
5475 }
5476
5477 switch (AL.getKind()) {
5478 default:
5479 llvm_unreachable("invalid ownership attribute")::llvm::llvm_unreachable_internal("invalid ownership attribute"
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 5479)
;
5480 case ParsedAttr::AT_NSReturnsAutoreleased:
5481 handleSimpleAttribute<NSReturnsAutoreleasedAttr>(S, D, AL);
5482 return;
5483 case ParsedAttr::AT_CFReturnsNotRetained:
5484 handleSimpleAttribute<CFReturnsNotRetainedAttr>(S, D, AL);
5485 return;
5486 case ParsedAttr::AT_NSReturnsNotRetained:
5487 handleSimpleAttribute<NSReturnsNotRetainedAttr>(S, D, AL);
5488 return;
5489 case ParsedAttr::AT_CFReturnsRetained:
5490 handleSimpleAttribute<CFReturnsRetainedAttr>(S, D, AL);
5491 return;
5492 case ParsedAttr::AT_NSReturnsRetained:
5493 handleSimpleAttribute<NSReturnsRetainedAttr>(S, D, AL);
5494 return;
5495 case ParsedAttr::AT_OSReturnsRetained:
5496 handleSimpleAttribute<OSReturnsRetainedAttr>(S, D, AL);
5497 return;
5498 case ParsedAttr::AT_OSReturnsNotRetained:
5499 handleSimpleAttribute<OSReturnsNotRetainedAttr>(S, D, AL);
5500 return;
5501 };
5502}
5503
5504static void handleObjCReturnsInnerPointerAttr(Sema &S, Decl *D,
5505 const ParsedAttr &Attrs) {
5506 const int EP_ObjCMethod = 1;
5507 const int EP_ObjCProperty = 2;
5508
5509 SourceLocation loc = Attrs.getLoc();
5510 QualType resultType;
5511 if (isa<ObjCMethodDecl>(D))
5512 resultType = cast<ObjCMethodDecl>(D)->getReturnType();
5513 else
5514 resultType = cast<ObjCPropertyDecl>(D)->getType();
5515
5516 if (!resultType->isReferenceType() &&
5517 (!resultType->isPointerType() || resultType->isObjCRetainableType())) {
5518 S.Diag(D->getBeginLoc(), diag::warn_ns_attribute_wrong_return_type)
5519 << SourceRange(loc) << Attrs
5520 << (isa<ObjCMethodDecl>(D) ? EP_ObjCMethod : EP_ObjCProperty)
5521 << /*non-retainable pointer*/ 2;
5522
5523 // Drop the attribute.
5524 return;
5525 }
5526
5527 D->addAttr(::new (S.Context) ObjCReturnsInnerPointerAttr(S.Context, Attrs));
5528}
5529
5530static void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
5531 const ParsedAttr &Attrs) {
5532 const auto *Method = cast<ObjCMethodDecl>(D);
5533
5534 const DeclContext *DC = Method->getDeclContext();
5535 if (const auto *PDecl = dyn_cast_or_null<ObjCProtocolDecl>(DC)) {
5536 S.Diag(D->getBeginLoc(), diag::warn_objc_requires_super_protocol) << Attrs
5537 << 0;
5538 S.Diag(PDecl->getLocation(), diag::note_protocol_decl);
5539 return;
5540 }
5541 if (Method->getMethodFamily() == OMF_dealloc) {
5542 S.Diag(D->getBeginLoc(), diag::warn_objc_requires_super_protocol) << Attrs
5543 << 1;
5544 return;
5545 }
5546
5547 D->addAttr(::new (S.Context) ObjCRequiresSuperAttr(S.Context, Attrs));
5548}
5549
5550static void handleNSErrorDomain(Sema &S, Decl *D, const ParsedAttr &AL) {
5551 auto *E = AL.getArgAsExpr(0);
5552 auto Loc = E ? E->getBeginLoc() : AL.getLoc();
5553
5554 auto *DRE = dyn_cast<DeclRefExpr>(AL.getArgAsExpr(0));
5555 if (!DRE) {
5556 S.Diag(Loc, diag::err_nserrordomain_invalid_decl) << 0;
5557 return;
5558 }
5559
5560 auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
5561 if (!VD) {
5562 S.Diag(Loc, diag::err_nserrordomain_invalid_decl) << 1 << DRE->getDecl();
5563 return;
5564 }
5565
5566 if (!isNSStringType(VD->getType(), S.Context) &&
5567 !isCFStringType(VD->getType(), S.Context)) {
5568 S.Diag(Loc, diag::err_nserrordomain_wrong_type) << VD;
5569 return;
5570 }
5571
5572 D->addAttr(::new (S.Context) NSErrorDomainAttr(S.Context, AL, VD));
5573}
5574
5575static void handleObjCBridgeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5576 IdentifierLoc *Parm = AL.isArgIdent(0) ? AL.getArgAsIdent(0) : nullptr;
5577
5578 if (!Parm) {
5579 S.Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;
5580 return;
5581 }
5582
5583 // Typedefs only allow objc_bridge(id) and have some additional checking.
5584 if (const auto *TD = dyn_cast<TypedefNameDecl>(D)) {
5585 if (!Parm->Ident->isStr("id")) {
5586 S.Diag(AL.getLoc(), diag::err_objc_attr_typedef_not_id) << AL;
5587 return;
5588 }
5589
5590 // Only allow 'cv void *'.
5591 QualType T = TD->getUnderlyingType();
5592 if (!T->isVoidPointerType()) {
5593 S.Diag(AL.getLoc(), diag::err_objc_attr_typedef_not_void_pointer);
5594 return;
5595 }
5596 }
5597
5598 D->addAttr(::new (S.Context) ObjCBridgeAttr(S.Context, AL, Parm->Ident));
5599}
5600
5601static void handleObjCBridgeMutableAttr(Sema &S, Decl *D,
5602 const ParsedAttr &AL) {
5603 IdentifierLoc *Parm = AL.isArgIdent(0) ? AL.getArgAsIdent(0) : nullptr;
5604
5605 if (!Parm) {
5606 S.Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;
5607 return;
5608 }
5609
5610 D->addAttr(::new (S.Context)
5611 ObjCBridgeMutableAttr(S.Context, AL, Parm->Ident));
5612}
5613
5614static void handleObjCBridgeRelatedAttr(Sema &S, Decl *D,
5615 const ParsedAttr &AL) {
5616 IdentifierInfo *RelatedClass =
5617 AL.isArgIdent(0) ? AL.getArgAsIdent(0)->Ident : nullptr;
5618 if (!RelatedClass) {
5619 S.Diag(D->getBeginLoc(), diag::err_objc_attr_not_id) << AL << 0;
5620 return;
5621 }
5622 IdentifierInfo *ClassMethod =
5623 AL.getArgAsIdent(1) ? AL.getArgAsIdent(1)->Ident : nullptr;
5624 IdentifierInfo *InstanceMethod =
5625 AL.getArgAsIdent(2) ? AL.getArgAsIdent(2)->Ident : nullptr;
5626 D->addAttr(::new (S.Context) ObjCBridgeRelatedAttr(
5627 S.Context, AL, RelatedClass, ClassMethod, InstanceMethod));
5628}
5629
5630static void handleObjCDesignatedInitializer(Sema &S, Decl *D,
5631 const ParsedAttr &AL) {
5632 DeclContext *Ctx = D->getDeclContext();
5633
5634 // This attribute can only be applied to methods in interfaces or class
5635 // extensions.
5636 if (!isa<ObjCInterfaceDecl>(Ctx) &&
5637 !(isa<ObjCCategoryDecl>(Ctx) &&
5638 cast<ObjCCategoryDecl>(Ctx)->IsClassExtension())) {
5639 S.Diag(D->getLocation(), diag::err_designated_init_attr_non_init);
5640 return;
5641 }
5642
5643 ObjCInterfaceDecl *IFace;
5644 if (auto *CatDecl = dyn_cast<ObjCCategoryDecl>(Ctx))
5645 IFace = CatDecl->getClassInterface();
5646 else
5647 IFace = cast<ObjCInterfaceDecl>(Ctx);
5648
5649 if (!IFace)
5650 return;
5651
5652 IFace->setHasDesignatedInitializers();
5653 D->addAttr(::new (S.Context) ObjCDesignatedInitializerAttr(S.Context, AL));
5654}
5655
5656static void handleObjCRuntimeName(Sema &S, Decl *D, const ParsedAttr &AL) {
5657 StringRef MetaDataName;
5658 if (!S.checkStringLiteralArgumentAttr(AL, 0, MetaDataName))
5659 return;
5660 D->addAttr(::new (S.Context)
5661 ObjCRuntimeNameAttr(S.Context, AL, MetaDataName));
5662}
5663
5664// When a user wants to use objc_boxable with a union or struct
5665// but they don't have access to the declaration (legacy/third-party code)
5666// then they can 'enable' this feature with a typedef:
5667// typedef struct __attribute((objc_boxable)) legacy_struct legacy_struct;
5668static void handleObjCBoxable(Sema &S, Decl *D, const ParsedAttr &AL) {
5669 bool notify = false;
5670
5671 auto *RD = dyn_cast<RecordDecl>(D);
5672 if (RD && RD->getDefinition()) {
5673 RD = RD->getDefinition();
5674 notify = true;
5675 }
5676
5677 if (RD) {
5678 ObjCBoxableAttr *BoxableAttr =
5679 ::new (S.Context) ObjCBoxableAttr(S.Context, AL);
5680 RD->addAttr(BoxableAttr);
5681 if (notify) {
5682 // we need to notify ASTReader/ASTWriter about
5683 // modification of existing declaration
5684 if (ASTMutationListener *L = S.getASTMutationListener())
5685 L->AddedAttributeToRecord(BoxableAttr, RD);
5686 }
5687 }
5688}
5689
5690static void handleObjCOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5691 if (hasDeclarator(D)) return;
5692
5693 S.Diag(D->getBeginLoc(), diag::err_attribute_wrong_decl_type)
5694 << AL.getRange() << AL << ExpectedVariable;
5695}
5696
5697static void handleObjCPreciseLifetimeAttr(Sema &S, Decl *D,
5698 const ParsedAttr &AL) {
5699 const auto *VD = cast<ValueDecl>(D);
5700 QualType QT = VD->getType();
5701
5702 if (!QT->isDependentType() &&
5703 !QT->isObjCLifetimeType()) {
5704 S.Diag(AL.getLoc(), diag::err_objc_precise_lifetime_bad_type)
5705 << QT;
5706 return;
5707 }
5708
5709 Qualifiers::ObjCLifetime Lifetime = QT.getObjCLifetime();
5710
5711 // If we have no lifetime yet, check the lifetime we're presumably
5712 // going to infer.
5713 if (Lifetime == Qualifiers::OCL_None && !QT->isDependentType())
5714 Lifetime = QT->getObjCARCImplicitLifetime();
5715
5716 switch (Lifetime) {
5717 case Qualifiers::OCL_None:
5718 assert(QT->isDependentType() &&((QT->isDependentType() && "didn't infer lifetime for non-dependent type?"
) ? static_cast<void> (0) : __assert_fail ("QT->isDependentType() && \"didn't infer lifetime for non-dependent type?\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 5719, __PRETTY_FUNCTION__))
5719 "didn't infer lifetime for non-dependent type?")((QT->isDependentType() && "didn't infer lifetime for non-dependent type?"
) ? static_cast<void> (0) : __assert_fail ("QT->isDependentType() && \"didn't infer lifetime for non-dependent type?\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 5719, __PRETTY_FUNCTION__))
;
5720 break;
5721
5722 case Qualifiers::OCL_Weak: // meaningful
5723 case Qualifiers::OCL_Strong: // meaningful
5724 break;
5725
5726 case Qualifiers::OCL_ExplicitNone:
5727 case Qualifiers::OCL_Autoreleasing:
5728 S.Diag(AL.getLoc(), diag::warn_objc_precise_lifetime_meaningless)
5729 << (Lifetime == Qualifiers::OCL_Autoreleasing);
5730 break;
5731 }
5732
5733 D->addAttr(::new (S.Context) ObjCPreciseLifetimeAttr(S.Context, AL));
5734}
5735
5736static void handleSwiftAttrAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5737 // Make sure that there is a string literal as the annotation's single
5738 // argument.
5739 StringRef Str;
5740 if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
5741 return;
5742
5743 D->addAttr(::new (S.Context) SwiftAttrAttr(S.Context, AL, Str));
5744}
5745
5746static void handleSwiftBridge(Sema &S, Decl *D, const ParsedAttr &AL) {
5747 // Make sure that there is a string literal as the annotation's single
5748 // argument.
5749 StringRef BT;
5750 if (!S.checkStringLiteralArgumentAttr(AL, 0, BT))
5751 return;
5752
5753 // Warn about duplicate attributes if they have different arguments, but drop
5754 // any duplicate attributes regardless.
5755 if (const auto *Other = D->getAttr<SwiftBridgeAttr>()) {
5756 if (Other->getSwiftType() != BT)
5757 S.Diag(AL.getLoc(), diag::warn_duplicate_attribute) << AL;
5758 return;
5759 }
5760
5761 D->addAttr(::new (S.Context) SwiftBridgeAttr(S.Context, AL, BT));
5762}
5763
5764static bool isErrorParameter(Sema &S, QualType QT) {
5765 const auto *PT = QT->getAs<PointerType>();
5766 if (!PT)
5767 return false;
5768
5769 QualType Pointee = PT->getPointeeType();
5770
5771 // Check for NSError**.
5772 if (const auto *OPT = Pointee->getAs<ObjCObjectPointerType>())
5773 if (const auto *ID = OPT->getInterfaceDecl())
5774 if (ID->getIdentifier() == S.getNSErrorIdent())
5775 return true;
5776
5777 // Check for CFError**.
5778 if (const auto *PT = Pointee->getAs<PointerType>())
5779 if (const auto *RT = PT->getPointeeType()->getAs<RecordType>())
5780 if (S.isCFError(RT->getDecl()))
5781 return true;
5782
5783 return false;
5784}
5785
5786static void handleSwiftError(Sema &S, Decl *D, const ParsedAttr &AL) {
5787 auto hasErrorParameter = [](Sema &S, Decl *D, const ParsedAttr &AL) -> bool {
5788 for (unsigned I = 0, E = getFunctionOrMethodNumParams(D); I != E; ++I) {
5789 if (isErrorParameter(S, getFunctionOrMethodParamType(D, I)))
5790 return true;
5791 }
5792
5793 S.Diag(AL.getLoc(), diag::err_attr_swift_error_no_error_parameter)
5794 << AL << isa<ObjCMethodDecl>(D);
5795 return false;
5796 };
5797
5798 auto hasPointerResult = [](Sema &S, Decl *D, const ParsedAttr &AL) -> bool {
5799 // - C, ObjC, and block pointers are definitely okay.
5800 // - References are definitely not okay.
5801 // - nullptr_t is weird, but acceptable.
5802 QualType RT = getFunctionOrMethodResultType(D);
5803 if (RT->hasPointerRepresentation() && !RT->isReferenceType())
5804 return true;
5805
5806 S.Diag(AL.getLoc(), diag::err_attr_swift_error_return_type)
5807 << AL << AL.getArgAsIdent(0)->Ident->getName() << isa<ObjCMethodDecl>(D)
5808 << /*pointer*/ 1;
5809 return false;
5810 };
5811
5812 auto hasIntegerResult = [](Sema &S, Decl *D, const ParsedAttr &AL) -> bool {
5813 QualType RT = getFunctionOrMethodResultType(D);
5814 if (RT->isIntegralType(S.Context))
5815 return true;
5816
5817 S.Diag(AL.getLoc(), diag::err_attr_swift_error_return_type)
5818 << AL << AL.getArgAsIdent(0)->Ident->getName() << isa<ObjCMethodDecl>(D)
5819 << /*integral*/ 0;
5820 return false;
5821 };
5822
5823 if (D->isInvalidDecl())
5824 return;
5825
5826 IdentifierLoc *Loc = AL.getArgAsIdent(0);
5827 SwiftErrorAttr::ConventionKind Convention;
5828 if (!SwiftErrorAttr::ConvertStrToConventionKind(Loc->Ident->getName(),
5829 Convention)) {
5830 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
5831 << AL << Loc->Ident;
5832 return;
5833 }
5834
5835 switch (Convention) {
5836 case SwiftErrorAttr::None:
5837 // No additional validation required.
5838 break;
5839
5840 case SwiftErrorAttr::NonNullError:
5841 if (!hasErrorParameter(S, D, AL))
5842 return;
5843 break;
5844
5845 case SwiftErrorAttr::NullResult:
5846 if (!hasErrorParameter(S, D, AL) || !hasPointerResult(S, D, AL))
5847 return;
5848 break;
5849
5850 case SwiftErrorAttr::NonZeroResult:
5851 case SwiftErrorAttr::ZeroResult:
5852 if (!hasErrorParameter(S, D, AL) || !hasIntegerResult(S, D, AL))
5853 return;
5854 break;
5855 }
5856
5857 D->addAttr(::new (S.Context) SwiftErrorAttr(S.Context, AL, Convention));
5858}
5859
5860static void checkSwiftAsyncErrorBlock(Sema &S, Decl *D,
5861 const SwiftAsyncErrorAttr *ErrorAttr,
5862 const SwiftAsyncAttr *AsyncAttr) {
5863 if (AsyncAttr->getKind() == SwiftAsyncAttr::None) {
1
Assuming the condition is false
2
Taking false branch
5864 if (ErrorAttr->getConvention() != SwiftAsyncErrorAttr::None) {
5865 S.Diag(AsyncAttr->getLocation(),
5866 diag::err_swift_async_error_without_swift_async)
5867 << AsyncAttr << isa<ObjCMethodDecl>(D);
5868 }
5869 return;
5870 }
5871
5872 const ParmVarDecl *HandlerParam = getFunctionOrMethodParam(
5873 D, AsyncAttr->getCompletionHandlerIndex().getASTIndex());
5874 // handleSwiftAsyncAttr already verified the type is correct, so no need to
5875 // double-check it here.
5876 const auto *FuncTy = HandlerParam->getType()
3
Assuming the object is not a 'BlockPointerType'
4
Called C++ object pointer is null
5877 ->getAs<BlockPointerType>()
5878 ->getPointeeType()
5879 ->getAs<FunctionProtoType>();
5880 ArrayRef<QualType> BlockParams;
5881 if (FuncTy)
5882 BlockParams = FuncTy->getParamTypes();
5883
5884 switch (ErrorAttr->getConvention()) {
5885 case SwiftAsyncErrorAttr::ZeroArgument:
5886 case SwiftAsyncErrorAttr::NonZeroArgument: {
5887 uint32_t ParamIdx = ErrorAttr->getHandlerParamIdx();
5888 if (ParamIdx == 0 || ParamIdx > BlockParams.size()) {
5889 S.Diag(ErrorAttr->getLocation(),
5890 diag::err_attribute_argument_out_of_bounds) << ErrorAttr << 2;
5891 return;
5892 }
5893 QualType ErrorParam = BlockParams[ParamIdx - 1];
5894 if (!ErrorParam->isIntegralType(S.Context)) {
5895 StringRef ConvStr =
5896 ErrorAttr->getConvention() == SwiftAsyncErrorAttr::ZeroArgument
5897 ? "zero_argument"
5898 : "nonzero_argument";
5899 S.Diag(ErrorAttr->getLocation(), diag::err_swift_async_error_non_integral)
5900 << ErrorAttr << ConvStr << ParamIdx << ErrorParam;
5901 return;
5902 }
5903 break;
5904 }
5905 case SwiftAsyncErrorAttr::NonNullError: {
5906 bool AnyErrorParams = false;
5907 for (QualType Param : BlockParams) {
5908 // Check for NSError *.
5909 if (const auto *ObjCPtrTy = Param->getAs<ObjCObjectPointerType>()) {
5910 if (const auto *ID = ObjCPtrTy->getInterfaceDecl()) {
5911 if (ID->getIdentifier() == S.getNSErrorIdent()) {
5912 AnyErrorParams = true;
5913 break;
5914 }
5915 }
5916 }
5917 // Check for CFError *.
5918 if (const auto *PtrTy = Param->getAs<PointerType>()) {
5919 if (const auto *RT = PtrTy->getPointeeType()->getAs<RecordType>()) {
5920 if (S.isCFError(RT->getDecl())) {
5921 AnyErrorParams = true;
5922 break;
5923 }
5924 }
5925 }
5926 }
5927
5928 if (!AnyErrorParams) {
5929 S.Diag(ErrorAttr->getLocation(),
5930 diag::err_swift_async_error_no_error_parameter)
5931 << ErrorAttr << isa<ObjCMethodDecl>(D);
5932 return;
5933 }
5934 break;
5935 }
5936 case SwiftAsyncErrorAttr::None:
5937 break;
5938 }
5939}
5940
5941static void handleSwiftAsyncError(Sema &S, Decl *D, const ParsedAttr &AL) {
5942 IdentifierLoc *IDLoc = AL.getArgAsIdent(0);
5943 SwiftAsyncErrorAttr::ConventionKind ConvKind;
5944 if (!SwiftAsyncErrorAttr::ConvertStrToConventionKind(IDLoc->Ident->getName(),
5945 ConvKind)) {
5946 S.Diag(AL.getLoc(), diag::warn_attribute_type_not_supported)
5947 << AL << IDLoc->Ident;
5948 return;
5949 }
5950
5951 uint32_t ParamIdx = 0;
5952 switch (ConvKind) {
5953 case SwiftAsyncErrorAttr::ZeroArgument:
5954 case SwiftAsyncErrorAttr::NonZeroArgument: {
5955 if (!checkAttributeNumArgs(S, AL, 2))
5956 return;
5957
5958 Expr *IdxExpr = AL.getArgAsExpr(1);
5959 if (!checkUInt32Argument(S, AL, IdxExpr, ParamIdx))
5960 return;
5961 break;
5962 }
5963 case SwiftAsyncErrorAttr::NonNullError:
5964 case SwiftAsyncErrorAttr::None: {
5965 if (!checkAttributeNumArgs(S, AL, 1))
5966 return;
5967 break;
5968 }
5969 }
5970
5971 auto *ErrorAttr =
5972 ::new (S.Context) SwiftAsyncErrorAttr(S.Context, AL, ConvKind, ParamIdx);
5973 D->addAttr(ErrorAttr);
5974
5975 if (auto *AsyncAttr = D->getAttr<SwiftAsyncAttr>())
5976 checkSwiftAsyncErrorBlock(S, D, ErrorAttr, AsyncAttr);
5977}
5978
5979// For a function, this will validate a compound Swift name, e.g.
5980// <code>init(foo:bar:baz:)</code> or <code>controllerForName(_:)</code>, and
5981// the function will output the number of parameter names, and whether this is a
5982// single-arg initializer.
5983//
5984// For a type, enum constant, property, or variable declaration, this will
5985// validate either a simple identifier, or a qualified
5986// <code>context.identifier</code> name.
5987static bool
5988validateSwiftFunctionName(Sema &S, const ParsedAttr &AL, SourceLocation Loc,
5989 StringRef Name, unsigned &SwiftParamCount,
5990 bool &IsSingleParamInit) {
5991 SwiftParamCount = 0;
5992 IsSingleParamInit = false;
5993
5994 // Check whether this will be mapped to a getter or setter of a property.
5995 bool IsGetter = false, IsSetter = false;
5996 if (Name.startswith("getter:")) {
5997 IsGetter = true;
5998 Name = Name.substr(7);
5999 } else if (Name.startswith("setter:")) {
6000 IsSetter = true;
6001 Name = Name.substr(7);
6002 }
6003
6004 if (Name.back() != ')') {
6005 S.Diag(Loc, diag::warn_attr_swift_name_function) << AL;
6006 return false;
6007 }
6008
6009 bool IsMember = false;
6010 StringRef ContextName, BaseName, Parameters;
6011
6012 std::tie(BaseName, Parameters) = Name.split('(');
6013
6014 // Split at the first '.', if it exists, which separates the context name
6015 // from the base name.
6016 std::tie(ContextName, BaseName) = BaseName.split('.');
6017 if (BaseName.empty()) {
6018 BaseName = ContextName;
6019 ContextName = StringRef();
6020 } else if (ContextName.empty() || !isValidIdentifier(ContextName)) {
6021 S.Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
6022 << AL << /*context*/ 1;
6023 return false;
6024 } else {
6025 IsMember = true;
6026 }
6027
6028 if (!isValidIdentifier(BaseName) || BaseName == "_") {
6029 S.Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
6030 << AL << /*basename*/ 0;
6031 return false;
6032 }
6033
6034 bool IsSubscript = BaseName == "subscript";
6035 // A subscript accessor must be a getter or setter.
6036 if (IsSubscript && !IsGetter && !IsSetter) {
6037 S.Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
6038 << AL << /* getter or setter */ 0;
6039 return false;
6040 }
6041
6042 if (Parameters.empty()) {
6043 S.Diag(Loc, diag::warn_attr_swift_name_missing_parameters) << AL;
6044 return false;
6045 }
6046
6047 assert(Parameters.back() == ')' && "expected ')'")((Parameters.back() == ')' && "expected ')'") ? static_cast
<void> (0) : __assert_fail ("Parameters.back() == ')' && \"expected ')'\""
, "/build/llvm-toolchain-snapshot-13~++20210308111132+66e3a4abe99c/clang/lib/Sema/SemaDeclAttr.cpp"
, 6047, __PRETTY_FUNCTION__))
;
6048 Parameters = Parameters.drop_back(); // ')'
6049
6050 if (Parameters.empty()) {
6051 // Setters and subscripts must have at least one parameter.
6052 if (IsSubscript) {
6053 S.Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
6054 << AL << /* have at least one parameter */1;
6055 return false;
6056 }
6057
6058 if (IsSetter) {
6059 S.Diag(Loc, diag::warn_attr_swift_name_setter_parameters) << AL;
6060 return false;
6061 }
6062
6063 return true;
6064 }
6065
6066 if (Parameters.back() != ':') {
6067 S.Diag(Loc, diag::warn_attr_swift_name_function) << AL;
6068 return false;
6069 }
6070
6071 StringRef CurrentParam;
6072 llvm::Optional<unsigned> SelfLocation;
6073 unsigned NewValueCount = 0;
6074 llvm::Optional<unsigned> NewValueLocation;
6075 do {
6076 std::tie(CurrentParam, Parameters) = Parameters.split(':');
6077
6078 if (!isValidIdentifier(CurrentParam)) {
6079 S.Diag(Loc, diag::warn_attr_swift_name_invalid_identifier)
6080 << AL << /*parameter*/2;
6081 return false;
6082 }
6083
6084 if (IsMember && CurrentParam == "self") {
6085 // "self" indicates the "self" argument for a member.
6086
6087 // More than one "self"?
6088 if (SelfLocation) {
6089 S.Diag(Loc, diag::warn_attr_swift_name_multiple_selfs) << AL;
6090 return false;
6091 }
6092
6093 // The "self" location is the current parameter.
6094 SelfLocation = SwiftParamCount;
6095 } else if (CurrentParam == "newValue") {
6096 // "newValue" indicates the "newValue" argument for a setter.
6097
6098 // There should only be one 'newValue', but it's only significant for
6099 // subscript accessors, so don't error right away.
6100 ++NewValueCount;
6101
6102 NewValueLocation = SwiftParamCount;
6103 }
6104
6105 ++SwiftParamCount;
6106 } while (!Parameters.empty());
6107
6108 // Only instance subscripts are currently supported.
6109 if (IsSubscript && !SelfLocation) {
6110 S.Diag(Loc, diag::warn_attr_swift_name_subscript_invalid_parameter)
6111 << AL << /*have a 'self:' parameter*/2;
6112 return false;
6113 }
6114
6115 IsSingleParamInit =
6116 SwiftParamCount == 1 && BaseName == "init" && CurrentParam != "_";
6117
6118 // Check the number of parameters for a getter/setter.
6119 if (IsGetter || IsSetter) {
6120 // Setters have one parameter for the new value.
6121 unsigned NumExpectedParams = IsGetter ? 0 : 1;
6122 unsigned ParamDiag =
6123 IsGetter ? diag::warn_attr_swift_name_getter_parameters
6124 : diag::warn_attr_swift_name_setter_parameters;
6125
6126 // Instance methods have one parameter for "self".
6127 if (SelfLocation)
6128 ++NumExpectedParams;
6129
6130 // Subscripts may have additional parameters beyond the expected params for
6131 // the index.
6132 if (IsSubscript) {
6133 if (SwiftParamCount < NumExpectedParams) {
6134 S.Diag(Loc, ParamDiag) << AL;
6135 return false;
6136 }
6137
6138 // A subscript setter must explicitly label its newValue parameter to
6139 // distinguish it from index parameters.
6140 if (IsSetter) {
6141 if (!NewValueLocation) {
6142 S.Diag(Loc, diag::warn_attr_swift_name_subscript_setter_no_newValue)
6143 << AL;
6144 return false;
6145 }
6146 if (NewValueCount > 1) {
6147 S.Diag(Loc, diag::warn_attr_swift_name_subscript_setter_multiple_newValues)
6148 << AL;
6149 return false;
6150 }
6151 } else {
6152 // Subscript getters should have no 'newValue:' parameter.
6153 if (NewValueLocation) {
6154 S.Diag(Loc, diag::warn_attr_swift_name_subscript_getter_newValue)
6155 << AL;
6156 return false;
6157 }
6158 }
6159 } else {
6160 // Property accessors must have exactly the number of expected params.
6161 if (SwiftParamCount != NumExpectedParams) {
6162 S.Diag(Loc, ParamDiag) << AL;
6163 return false;
6164 }
6165 }
6166 }
6167
6168 return true;
6169}
6170
6171bool Sema::DiagnoseSwiftName(Decl *D, StringRef Name, SourceLocation Loc,
6172 const ParsedAttr &AL, bool IsAsync) {
6173 if (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D)) {
6174 ArrayRef<ParmVarDecl*> Params;
6175 unsigned ParamCount;
6176
6177 if (const auto *Method = dyn_cast<ObjCMethodDecl>(D)) {
6178 ParamCount = Method->getSelector().getNumArgs();
6179 Params = Method->parameters().slice(0, ParamCount);
6180 } else {
6181 const auto *F = cast<FunctionDecl>(D);
6182
6183 ParamCount = F->getNumParams();
6184 Params = F->parameters();
6185
6186 if (!F->hasWrittenPrototype()) {
6187 Diag(Loc, diag::warn_attribute_wrong_decl_type) << AL
6188 << ExpectedFunctionWithProtoType;
6189 return false;
6190 }
6191 }
6192
6193 // The async name drops the last callback parameter.
6194 if (IsAsync) {
6195 if (ParamCount == 0) {
6196 Diag(Loc, diag::warn_attr_swift_name_decl_missing_params)
6197 << AL << isa<ObjCMethodDecl>(D);
6198 return false;
6199 }
6200 ParamCount -= 1;
6201 }
6202
6203 unsigned SwiftParamCount;
6204 bool IsSingleParamInit;
6205 if (!validateSwiftFunctionName(*this, AL, Loc, Name,
6206 SwiftParamCount, IsSingleParamInit))
6207 return false;
6208
6209 bool ParamCountValid;
6210 if (SwiftParamCount == ParamCount) {
6211 ParamCountValid = true;
6212 } else if (SwiftParamCount > ParamCount) {
6213 ParamCountValid = IsSingleParamInit && ParamCount == 0;
6214 } else {
6215 // We have fewer Swift parameters than Objective-C parameters, but that
6216 // might be because we've transformed some of them. Check for potential
6217 // "out" parameters and err on the side of not warning.
6218 unsigned MaybeOutParamCount =
6219 std::count_if(Params.begin(), Params.end(),
6220 [](const ParmVarDecl *Param) -> bool {
6221 QualType ParamTy = Param->getType();