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/APValue.h"
14#include "clang/AST/ASTConsumer.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/ASTMutationListener.h"
17#include "clang/AST/CXXInheritance.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclCXX.h"
20#include "clang/AST/DeclObjC.h"
21#include "clang/AST/DeclTemplate.h"
22#include "clang/AST/DynamicRecursiveASTVisitor.h"
23#include "clang/AST/Expr.h"
24#include "clang/AST/ExprCXX.h"
25#include "clang/AST/Mangle.h"
26#include "clang/AST/Type.h"
27#include "clang/Basic/CharInfo.h"
28#include "clang/Basic/Cuda.h"
29#include "clang/Basic/DarwinSDKInfo.h"
30#include "clang/Basic/IdentifierTable.h"
31#include "clang/Basic/LangOptions.h"
32#include "clang/Basic/SourceLocation.h"
33#include "clang/Basic/SourceManager.h"
34#include "clang/Basic/TargetInfo.h"
35#include "clang/Lex/Preprocessor.h"
36#include "clang/Sema/Attr.h"
37#include "clang/Sema/DeclSpec.h"
38#include "clang/Sema/DelayedDiagnostic.h"
39#include "clang/Sema/Initialization.h"
40#include "clang/Sema/Lookup.h"
41#include "clang/Sema/ParsedAttr.h"
42#include "clang/Sema/Scope.h"
43#include "clang/Sema/ScopeInfo.h"
44#include "clang/Sema/Sema.h"
45#include "clang/Sema/SemaAMDGPU.h"
46#include "clang/Sema/SemaARM.h"
47#include "clang/Sema/SemaAVR.h"
48#include "clang/Sema/SemaBPF.h"
49#include "clang/Sema/SemaCUDA.h"
50#include "clang/Sema/SemaHLSL.h"
51#include "clang/Sema/SemaInternal.h"
52#include "clang/Sema/SemaM68k.h"
53#include "clang/Sema/SemaMIPS.h"
54#include "clang/Sema/SemaMSP430.h"
55#include "clang/Sema/SemaObjC.h"
56#include "clang/Sema/SemaOpenCL.h"
57#include "clang/Sema/SemaOpenMP.h"
58#include "clang/Sema/SemaRISCV.h"
59#include "clang/Sema/SemaSYCL.h"
60#include "clang/Sema/SemaSwift.h"
61#include "clang/Sema/SemaWasm.h"
62#include "clang/Sema/SemaX86.h"
63#include "llvm/ADT/APSInt.h"
64#include "llvm/ADT/STLExtras.h"
65#include "llvm/ADT/StringExtras.h"
66#include "llvm/Demangle/Demangle.h"
67#include "llvm/IR/DerivedTypes.h"
68#include "llvm/MC/MCSectionMachO.h"
69#include "llvm/Support/Error.h"
70#include "llvm/Support/ErrorHandling.h"
71#include "llvm/Support/MathExtras.h"
72#include "llvm/Support/raw_ostream.h"
73#include "llvm/TargetParser/Triple.h"
74#include <optional>
75
76using namespace clang;
77using namespace sema;
78
79namespace AttributeLangSupport {
80 enum LANG {
81 C,
82 Cpp,
83 ObjC
84 };
85} // end namespace AttributeLangSupport
86
87static unsigned getNumAttributeArgs(const ParsedAttr &AL) {
88 // FIXME: Include the type in the argument list.
89 return AL.getNumArgs() + AL.hasParsedType();
90}
91
92SourceLocation Sema::getAttrLoc(const AttributeCommonInfo &CI) {
93 return CI.getLoc();
94}
95
96/// Wrapper around checkUInt32Argument, with an extra check to be sure
97/// that the result will fit into a regular (signed) int. All args have the same
98/// purpose as they do in checkUInt32Argument.
99template <typename AttrInfo>
100static bool checkPositiveIntArgument(Sema &S, const AttrInfo &AI, const Expr *Expr,
101 int &Val, unsigned Idx = UINT_MAX) {
102 uint32_t UVal;
103 if (!S.checkUInt32Argument(AI, Expr, UVal, Idx))
104 return false;
105
106 if (UVal > (uint32_t)std::numeric_limits<int>::max()) {
107 llvm::APSInt I(32); // for toString
108 I = UVal;
109 S.Diag(Loc: Expr->getExprLoc(), DiagID: diag::err_ice_too_large)
110 << toString(I, Radix: 10, Signed: false) << 32 << /* Unsigned */ 0;
111 return false;
112 }
113
114 Val = UVal;
115 return true;
116}
117
118bool Sema::checkStringLiteralArgumentAttr(const AttributeCommonInfo &CI,
119 const Expr *E, StringRef &Str,
120 SourceLocation *ArgLocation) {
121 const auto *Literal = dyn_cast<StringLiteral>(Val: E->IgnoreParenCasts());
122 if (ArgLocation)
123 *ArgLocation = E->getBeginLoc();
124
125 if (!Literal || (!Literal->isUnevaluated() && !Literal->isOrdinary())) {
126 Diag(Loc: E->getBeginLoc(), DiagID: diag::err_attribute_argument_type)
127 << CI << AANT_ArgumentString;
128 return false;
129 }
130
131 Str = Literal->getString();
132 return true;
133}
134
135bool Sema::checkStringLiteralArgumentAttr(const ParsedAttr &AL, unsigned ArgNum,
136 StringRef &Str,
137 SourceLocation *ArgLocation) {
138 // Look for identifiers. If we have one emit a hint to fix it to a literal.
139 if (AL.isArgIdent(Arg: ArgNum)) {
140 IdentifierLoc *Loc = AL.getArgAsIdent(Arg: ArgNum);
141 Diag(Loc: Loc->getLoc(), DiagID: diag::err_attribute_argument_type)
142 << AL << AANT_ArgumentString
143 << FixItHint::CreateInsertion(InsertionLoc: Loc->getLoc(), Code: "\"")
144 << FixItHint::CreateInsertion(InsertionLoc: getLocForEndOfToken(Loc: Loc->getLoc()), Code: "\"");
145 Str = Loc->getIdentifierInfo()->getName();
146 if (ArgLocation)
147 *ArgLocation = Loc->getLoc();
148 return true;
149 }
150
151 // Now check for an actual string literal.
152 Expr *ArgExpr = AL.getArgAsExpr(Arg: ArgNum);
153 const auto *Literal = dyn_cast<StringLiteral>(Val: ArgExpr->IgnoreParenCasts());
154 if (ArgLocation)
155 *ArgLocation = ArgExpr->getBeginLoc();
156
157 if (!Literal || (!Literal->isUnevaluated() && !Literal->isOrdinary())) {
158 Diag(Loc: ArgExpr->getBeginLoc(), DiagID: diag::err_attribute_argument_type)
159 << AL << AANT_ArgumentString;
160 return false;
161 }
162 Str = Literal->getString();
163 return checkStringLiteralArgumentAttr(CI: AL, E: ArgExpr, Str, ArgLocation);
164}
165
166/// Check if the passed-in expression is of type int or bool.
167static bool isIntOrBool(Expr *Exp) {
168 QualType QT = Exp->getType();
169 return QT->isBooleanType() || QT->isIntegerType();
170}
171
172
173// Check to see if the type is a smart pointer of some kind. We assume
174// it's a smart pointer if it defines both operator-> and operator*.
175static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordDecl *Record) {
176 auto IsOverloadedOperatorPresent = [&S](const RecordDecl *Record,
177 OverloadedOperatorKind Op) {
178 DeclContextLookupResult Result =
179 Record->lookup(Name: S.Context.DeclarationNames.getCXXOperatorName(Op));
180 return !Result.empty();
181 };
182
183 bool foundStarOperator = IsOverloadedOperatorPresent(Record, OO_Star);
184 bool foundArrowOperator = IsOverloadedOperatorPresent(Record, OO_Arrow);
185 if (foundStarOperator && foundArrowOperator)
186 return true;
187
188 const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Val: Record);
189 if (!CXXRecord)
190 return false;
191
192 for (const auto &BaseSpecifier : CXXRecord->bases()) {
193 if (!foundStarOperator)
194 foundStarOperator = IsOverloadedOperatorPresent(
195 BaseSpecifier.getType()->getAsRecordDecl(), OO_Star);
196 if (!foundArrowOperator)
197 foundArrowOperator = IsOverloadedOperatorPresent(
198 BaseSpecifier.getType()->getAsRecordDecl(), OO_Arrow);
199 }
200
201 if (foundStarOperator && foundArrowOperator)
202 return true;
203
204 return false;
205}
206
207/// Check if passed in Decl is a pointer type.
208/// Note that this function may produce an error message.
209/// \return true if the Decl is a pointer type; false otherwise
210static bool threadSafetyCheckIsPointer(Sema &S, const Decl *D,
211 const ParsedAttr &AL) {
212 const auto *VD = cast<ValueDecl>(Val: D);
213 QualType QT = VD->getType();
214 if (QT->isAnyPointerType())
215 return true;
216
217 if (const auto *RD = QT->getAsRecordDecl()) {
218 // If it's an incomplete type, it could be a smart pointer; skip it.
219 // (We don't want to force template instantiation if we can avoid it,
220 // since that would alter the order in which templates are instantiated.)
221 if (!RD->isCompleteDefinition())
222 return true;
223
224 if (threadSafetyCheckIsSmartPointer(S, Record: RD))
225 return true;
226 }
227
228 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_thread_attribute_decl_not_pointer) << AL << QT;
229 return false;
230}
231
232/// Checks that the passed in QualType either is of RecordType or points
233/// to RecordType. Returns the relevant RecordType, null if it does not exit.
234static const RecordDecl *getRecordDecl(QualType QT) {
235 if (const auto *RD = QT->getAsRecordDecl())
236 return RD;
237
238 // Now check if we point to a record.
239 if (const auto *PT = QT->getAsCanonical<PointerType>())
240 return PT->getPointeeType()->getAsRecordDecl();
241
242 return nullptr;
243}
244
245template <typename AttrType>
246static bool checkRecordDeclForAttr(const RecordDecl *RD) {
247 // Check if the record itself has the attribute.
248 if (RD->hasAttr<AttrType>())
249 return true;
250
251 // Else check if any base classes have the attribute.
252 if (const auto *CRD = dyn_cast<CXXRecordDecl>(Val: RD)) {
253 if (!CRD->forallBases(BaseMatches: [](const CXXRecordDecl *Base) {
254 return !Base->hasAttr<AttrType>();
255 }))
256 return true;
257 }
258 return false;
259}
260
261static bool checkRecordTypeForCapability(Sema &S, QualType Ty) {
262 const auto *RD = getRecordDecl(QT: Ty);
263
264 if (!RD)
265 return false;
266
267 // Don't check for the capability if the class hasn't been defined yet.
268 if (!RD->isCompleteDefinition())
269 return true;
270
271 // Allow smart pointers to be used as capability objects.
272 // FIXME -- Check the type that the smart pointer points to.
273 if (threadSafetyCheckIsSmartPointer(S, Record: RD))
274 return true;
275
276 return checkRecordDeclForAttr<CapabilityAttr>(RD);
277}
278
279static bool checkRecordTypeForScopedCapability(Sema &S, QualType Ty) {
280 const auto *RD = getRecordDecl(QT: Ty);
281
282 if (!RD)
283 return false;
284
285 // Don't check for the capability if the class hasn't been defined yet.
286 if (!RD->isCompleteDefinition())
287 return true;
288
289 return checkRecordDeclForAttr<ScopedLockableAttr>(RD);
290}
291
292static bool checkTypedefTypeForCapability(QualType Ty) {
293 const auto *TD = Ty->getAs<TypedefType>();
294 if (!TD)
295 return false;
296
297 TypedefNameDecl *TN = TD->getDecl();
298 if (!TN)
299 return false;
300
301 return TN->hasAttr<CapabilityAttr>();
302}
303
304static bool typeHasCapability(Sema &S, QualType Ty) {
305 if (checkTypedefTypeForCapability(Ty))
306 return true;
307
308 if (checkRecordTypeForCapability(S, Ty))
309 return true;
310
311 return false;
312}
313
314static bool isCapabilityExpr(Sema &S, const Expr *Ex) {
315 // Capability expressions are simple expressions involving the boolean logic
316 // operators &&, || or !, a simple DeclRefExpr, CastExpr or a ParenExpr. Once
317 // a DeclRefExpr is found, its type should be checked to determine whether it
318 // is a capability or not.
319
320 if (const auto *E = dyn_cast<CastExpr>(Val: Ex))
321 return isCapabilityExpr(S, Ex: E->getSubExpr());
322 else if (const auto *E = dyn_cast<ParenExpr>(Val: Ex))
323 return isCapabilityExpr(S, Ex: E->getSubExpr());
324 else if (const auto *E = dyn_cast<UnaryOperator>(Val: Ex)) {
325 if (E->getOpcode() == UO_LNot || E->getOpcode() == UO_AddrOf ||
326 E->getOpcode() == UO_Deref)
327 return isCapabilityExpr(S, Ex: E->getSubExpr());
328 return false;
329 } else if (const auto *E = dyn_cast<BinaryOperator>(Val: Ex)) {
330 if (E->getOpcode() == BO_LAnd || E->getOpcode() == BO_LOr)
331 return isCapabilityExpr(S, Ex: E->getLHS()) &&
332 isCapabilityExpr(S, Ex: E->getRHS());
333 return false;
334 }
335
336 return typeHasCapability(S, Ty: Ex->getType());
337}
338
339/// Checks that all attribute arguments, starting from Sidx, resolve to
340/// a capability object.
341/// \param Sidx The attribute argument index to start checking with.
342/// \param ParamIdxOk Whether an argument can be indexing into a function
343/// parameter list.
344static void checkAttrArgsAreCapabilityObjs(Sema &S, Decl *D,
345 const ParsedAttr &AL,
346 SmallVectorImpl<Expr *> &Args,
347 unsigned Sidx = 0,
348 bool ParamIdxOk = false) {
349 if (Sidx == AL.getNumArgs()) {
350 // If we don't have any capability arguments, the attribute implicitly
351 // refers to 'this'. So we need to make sure that 'this' exists, i.e. we're
352 // a non-static method, and that the class is a (scoped) capability.
353 const auto *MD = dyn_cast<const CXXMethodDecl>(Val: D);
354 if (MD && !MD->isStatic()) {
355 const CXXRecordDecl *RD = MD->getParent();
356 // FIXME -- need to check this again on template instantiation
357 if (!checkRecordDeclForAttr<CapabilityAttr>(RD) &&
358 !checkRecordDeclForAttr<ScopedLockableAttr>(RD))
359 S.Diag(Loc: AL.getLoc(),
360 DiagID: diag::warn_thread_attribute_not_on_capability_member)
361 << AL << MD->getParent();
362 } else {
363 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_thread_attribute_not_on_non_static_member)
364 << AL;
365 }
366 }
367
368 for (unsigned Idx = Sidx; Idx < AL.getNumArgs(); ++Idx) {
369 Expr *ArgExp = AL.getArgAsExpr(Arg: Idx);
370
371 if (ArgExp->isTypeDependent()) {
372 // FIXME -- need to check this again on template instantiation
373 Args.push_back(Elt: ArgExp);
374 continue;
375 }
376
377 if (const auto *StrLit = dyn_cast<StringLiteral>(Val: ArgExp)) {
378 if (StrLit->getLength() == 0 ||
379 (StrLit->isOrdinary() && StrLit->getString() == "*")) {
380 // Pass empty strings to the analyzer without warnings.
381 // Treat "*" as the universal lock.
382 Args.push_back(Elt: ArgExp);
383 continue;
384 }
385
386 // We allow constant strings to be used as a placeholder for expressions
387 // that are not valid C++ syntax, but warn that they are ignored.
388 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_thread_attribute_ignored) << AL;
389 Args.push_back(Elt: ArgExp);
390 continue;
391 }
392
393 QualType ArgTy = ArgExp->getType();
394
395 // A pointer to member expression of the form &MyClass::mu is treated
396 // specially -- we need to look at the type of the member.
397 if (const auto *UOp = dyn_cast<UnaryOperator>(Val: ArgExp))
398 if (UOp->getOpcode() == UO_AddrOf)
399 if (const auto *DRE = dyn_cast<DeclRefExpr>(Val: UOp->getSubExpr()))
400 if (DRE->getDecl()->isCXXInstanceMember())
401 ArgTy = DRE->getDecl()->getType();
402
403 // First see if we can just cast to record type, or pointer to record type.
404 const auto *RD = getRecordDecl(QT: ArgTy);
405
406 // Now check if we index into a record type function param.
407 if (!RD && ParamIdxOk) {
408 const auto *FD = dyn_cast<FunctionDecl>(Val: D);
409 const auto *IL = dyn_cast<IntegerLiteral>(Val: ArgExp);
410 if(FD && IL) {
411 unsigned int NumParams = FD->getNumParams();
412 llvm::APInt ArgValue = IL->getValue();
413 uint64_t ParamIdxFromOne = ArgValue.getZExtValue();
414 uint64_t ParamIdxFromZero = ParamIdxFromOne - 1;
415 if (!ArgValue.isStrictlyPositive() || ParamIdxFromOne > NumParams) {
416 S.Diag(Loc: AL.getLoc(),
417 DiagID: diag::err_attribute_argument_out_of_bounds_extra_info)
418 << AL << Idx + 1 << NumParams;
419 continue;
420 }
421 ArgTy = FD->getParamDecl(i: ParamIdxFromZero)->getType();
422 }
423 }
424
425 // If the type does not have a capability, see if the components of the
426 // expression have capabilities. This allows for writing C code where the
427 // capability may be on the type, and the expression is a capability
428 // boolean logic expression. Eg) requires_capability(A || B && !C)
429 if (!typeHasCapability(S, Ty: ArgTy) && !isCapabilityExpr(S, Ex: ArgExp))
430 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_thread_attribute_argument_not_lockable)
431 << AL << ArgTy;
432
433 Args.push_back(Elt: ArgExp);
434 }
435}
436
437static bool checkFunParamsAreScopedLockable(Sema &S,
438 const ParmVarDecl *ParamDecl,
439 const ParsedAttr &AL) {
440 QualType ParamType = ParamDecl->getType();
441 if (const auto *RefType = ParamType->getAs<ReferenceType>();
442 RefType &&
443 checkRecordTypeForScopedCapability(S, Ty: RefType->getPointeeType()))
444 return true;
445 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_thread_attribute_not_on_scoped_lockable_param)
446 << AL;
447 return false;
448}
449
450//===----------------------------------------------------------------------===//
451// Attribute Implementations
452//===----------------------------------------------------------------------===//
453
454static void handlePtGuardedVarAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
455 if (!threadSafetyCheckIsPointer(S, D, AL))
456 return;
457
458 D->addAttr(A: ::new (S.Context) PtGuardedVarAttr(S.Context, AL));
459}
460
461static bool checkGuardedByAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
462 Expr *&Arg) {
463 SmallVector<Expr *, 1> Args;
464 // check that all arguments are lockable objects
465 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
466 unsigned Size = Args.size();
467 if (Size != 1)
468 return false;
469
470 Arg = Args[0];
471
472 return true;
473}
474
475static void handleGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
476 Expr *Arg = nullptr;
477 if (!checkGuardedByAttrCommon(S, D, AL, Arg))
478 return;
479
480 D->addAttr(A: ::new (S.Context) GuardedByAttr(S.Context, AL, Arg));
481}
482
483static void handlePtGuardedByAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
484 Expr *Arg = nullptr;
485 if (!checkGuardedByAttrCommon(S, D, AL, Arg))
486 return;
487
488 if (!threadSafetyCheckIsPointer(S, D, AL))
489 return;
490
491 D->addAttr(A: ::new (S.Context) PtGuardedByAttr(S.Context, AL, Arg));
492}
493
494static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
495 SmallVectorImpl<Expr *> &Args) {
496 if (!AL.checkAtLeastNumArgs(S, Num: 1))
497 return false;
498
499 // Check that this attribute only applies to lockable types.
500 QualType QT = cast<ValueDecl>(Val: D)->getType();
501 if (!QT->isDependentType() && !typeHasCapability(S, Ty: QT)) {
502 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_thread_attribute_decl_not_lockable) << AL;
503 return false;
504 }
505
506 // Check that all arguments are lockable objects.
507 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
508 if (Args.empty())
509 return false;
510
511 return true;
512}
513
514static void handleAcquiredAfterAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
515 SmallVector<Expr *, 1> Args;
516 if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
517 return;
518
519 Expr **StartArg = &Args[0];
520 D->addAttr(A: ::new (S.Context)
521 AcquiredAfterAttr(S.Context, AL, StartArg, Args.size()));
522}
523
524static void handleAcquiredBeforeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
525 SmallVector<Expr *, 1> Args;
526 if (!checkAcquireOrderAttrCommon(S, D, AL, Args))
527 return;
528
529 Expr **StartArg = &Args[0];
530 D->addAttr(A: ::new (S.Context)
531 AcquiredBeforeAttr(S.Context, AL, StartArg, Args.size()));
532}
533
534static bool checkLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
535 SmallVectorImpl<Expr *> &Args) {
536 // zero or more arguments ok
537 // check that all arguments are lockable objects
538 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, Sidx: 0, /*ParamIdxOk=*/true);
539
540 return true;
541}
542
543/// Checks to be sure that the given parameter number is in bounds, and
544/// is an integral type. Will emit appropriate diagnostics if this returns
545/// false.
546///
547/// AttrArgNo is used to actually retrieve the argument, so it's base-0.
548template <typename AttrInfo>
549static bool checkParamIsIntegerType(Sema &S, const Decl *D, const AttrInfo &AI,
550 unsigned AttrArgNo) {
551 assert(AI.isArgExpr(AttrArgNo) && "Expected expression argument");
552 Expr *AttrArg = AI.getArgAsExpr(AttrArgNo);
553 ParamIdx Idx;
554 if (!S.checkFunctionOrMethodParameterIndex(D, AI, AttrArgNo + 1, AttrArg,
555 Idx))
556 return false;
557
558 QualType ParamTy = getFunctionOrMethodParamType(D, Idx: Idx.getASTIndex());
559 if (!ParamTy->isIntegerType() && !ParamTy->isCharType()) {
560 SourceLocation SrcLoc = AttrArg->getBeginLoc();
561 S.Diag(Loc: SrcLoc, DiagID: diag::err_attribute_integers_only)
562 << AI << getFunctionOrMethodParamRange(D, Idx: Idx.getASTIndex());
563 return false;
564 }
565 return true;
566}
567
568static void handleAllocSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
569 if (!AL.checkAtLeastNumArgs(S, Num: 1) || !AL.checkAtMostNumArgs(S, Num: 2))
570 return;
571
572 assert(isFuncOrMethodForAttrSubject(D) && hasFunctionProto(D));
573
574 QualType RetTy = getFunctionOrMethodResultType(D);
575 if (!RetTy->isPointerType()) {
576 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_return_pointers_only) << AL;
577 return;
578 }
579
580 const Expr *SizeExpr = AL.getArgAsExpr(Arg: 0);
581 int SizeArgNoVal;
582 // Parameter indices are 1-indexed, hence Index=1
583 if (!checkPositiveIntArgument(S, AI: AL, Expr: SizeExpr, Val&: SizeArgNoVal, /*Idx=*/1))
584 return;
585 if (!checkParamIsIntegerType(S, D, AI: AL, /*AttrArgNo=*/0))
586 return;
587 ParamIdx SizeArgNo(SizeArgNoVal, D);
588
589 ParamIdx NumberArgNo;
590 if (AL.getNumArgs() == 2) {
591 const Expr *NumberExpr = AL.getArgAsExpr(Arg: 1);
592 int Val;
593 // Parameter indices are 1-based, hence Index=2
594 if (!checkPositiveIntArgument(S, AI: AL, Expr: NumberExpr, Val, /*Idx=*/2))
595 return;
596 if (!checkParamIsIntegerType(S, D, AI: AL, /*AttrArgNo=*/1))
597 return;
598 NumberArgNo = ParamIdx(Val, D);
599 }
600
601 D->addAttr(A: ::new (S.Context)
602 AllocSizeAttr(S.Context, AL, SizeArgNo, NumberArgNo));
603}
604
605static bool checkTryLockFunAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
606 SmallVectorImpl<Expr *> &Args) {
607 if (!AL.checkAtLeastNumArgs(S, Num: 1))
608 return false;
609
610 if (!isIntOrBool(Exp: AL.getArgAsExpr(Arg: 0))) {
611 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
612 << AL << 1 << AANT_ArgumentIntOrBool;
613 return false;
614 }
615
616 // check that all arguments are lockable objects
617 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, Sidx: 1);
618
619 return true;
620}
621
622static void handleLockReturnedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
623 // check that the argument is lockable object
624 SmallVector<Expr*, 1> Args;
625 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
626 unsigned Size = Args.size();
627 if (Size == 0)
628 return;
629
630 D->addAttr(A: ::new (S.Context) LockReturnedAttr(S.Context, AL, Args[0]));
631}
632
633static void handleLocksExcludedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
634 if (const auto *ParmDecl = dyn_cast<ParmVarDecl>(Val: D);
635 ParmDecl && !checkFunParamsAreScopedLockable(S, ParamDecl: ParmDecl, AL))
636 return;
637
638 if (!AL.checkAtLeastNumArgs(S, Num: 1))
639 return;
640
641 // check that all arguments are lockable objects
642 SmallVector<Expr*, 1> Args;
643 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
644 unsigned Size = Args.size();
645 if (Size == 0)
646 return;
647 Expr **StartArg = &Args[0];
648
649 D->addAttr(A: ::new (S.Context)
650 LocksExcludedAttr(S.Context, AL, StartArg, Size));
651}
652
653static bool checkFunctionConditionAttr(Sema &S, Decl *D, const ParsedAttr &AL,
654 Expr *&Cond, StringRef &Msg) {
655 Cond = AL.getArgAsExpr(Arg: 0);
656 if (!Cond->isTypeDependent()) {
657 ExprResult Converted = S.PerformContextuallyConvertToBool(From: Cond);
658 if (Converted.isInvalid())
659 return false;
660 Cond = Converted.get();
661 }
662
663 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 1, Str&: Msg))
664 return false;
665
666 if (Msg.empty())
667 Msg = "<no message provided>";
668
669 SmallVector<PartialDiagnosticAt, 8> Diags;
670 if (isa<FunctionDecl>(Val: D) && !Cond->isValueDependent() &&
671 !Expr::isPotentialConstantExprUnevaluated(E: Cond, FD: cast<FunctionDecl>(Val: D),
672 Diags)) {
673 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attr_cond_never_constant_expr) << AL;
674 for (const PartialDiagnosticAt &PDiag : Diags)
675 S.Diag(Loc: PDiag.first, PD: PDiag.second);
676 return false;
677 }
678 return true;
679}
680
681static void handleEnableIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
682 S.Diag(Loc: AL.getLoc(), DiagID: diag::ext_clang_enable_if);
683
684 Expr *Cond;
685 StringRef Msg;
686 if (checkFunctionConditionAttr(S, D, AL, Cond, Msg))
687 D->addAttr(A: ::new (S.Context) EnableIfAttr(S.Context, AL, Cond, Msg));
688}
689
690static void handleErrorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
691 StringRef NewUserDiagnostic;
692 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: NewUserDiagnostic))
693 return;
694 if (ErrorAttr *EA = S.mergeErrorAttr(D, CI: AL, NewUserDiagnostic))
695 D->addAttr(A: EA);
696}
697
698static void handleExcludeFromExplicitInstantiationAttr(Sema &S, Decl *D,
699 const ParsedAttr &AL) {
700 const auto *PD = isa<CXXRecordDecl>(Val: D)
701 ? cast<DeclContext>(Val: D)
702 : D->getDeclContext()->getRedeclContext();
703 if (const auto *RD = dyn_cast<CXXRecordDecl>(Val: PD); RD && RD->isLocalClass()) {
704 S.Diag(Loc: AL.getLoc(),
705 DiagID: diag::warn_attribute_exclude_from_explicit_instantiation_local_class)
706 << AL << /*IsMember=*/!isa<CXXRecordDecl>(Val: D);
707 return;
708 }
709
710 if (auto *DA = getDLLAttr(D); DA && !DA->isInherited()) {
711 S.Diag(Loc: DA->getLoc(), DiagID: diag::warn_dllattr_ignored_exclusion_takes_precedence)
712 << DA << AL;
713 D->dropAttrs<DLLExportAttr, DLLImportAttr>();
714 }
715
716 D->addAttr(A: ::new (S.Context)
717 ExcludeFromExplicitInstantiationAttr(S.Context, AL));
718}
719
720namespace {
721/// Determines if a given Expr references any of the given function's
722/// ParmVarDecls, or the function's implicit `this` parameter (if applicable).
723class ArgumentDependenceChecker : public DynamicRecursiveASTVisitor {
724#ifndef NDEBUG
725 const CXXRecordDecl *ClassType;
726#endif
727 llvm::SmallPtrSet<const ParmVarDecl *, 16> Parms;
728 bool Result;
729
730public:
731 ArgumentDependenceChecker(const FunctionDecl *FD) {
732#ifndef NDEBUG
733 if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
734 ClassType = MD->getParent();
735 else
736 ClassType = nullptr;
737#endif
738 Parms.insert(I: FD->param_begin(), E: FD->param_end());
739 }
740
741 bool referencesArgs(Expr *E) {
742 Result = false;
743 TraverseStmt(S: E);
744 return Result;
745 }
746
747 bool VisitCXXThisExpr(CXXThisExpr *E) override {
748 assert(E->getType()->getPointeeCXXRecordDecl() == ClassType &&
749 "`this` doesn't refer to the enclosing class?");
750 Result = true;
751 return false;
752 }
753
754 bool VisitDeclRefExpr(DeclRefExpr *DRE) override {
755 if (const auto *PVD = dyn_cast<ParmVarDecl>(Val: DRE->getDecl()))
756 if (Parms.count(Ptr: PVD)) {
757 Result = true;
758 return false;
759 }
760 return true;
761 }
762};
763}
764
765static void handleDiagnoseAsBuiltinAttr(Sema &S, Decl *D,
766 const ParsedAttr &AL) {
767 const auto *DeclFD = cast<FunctionDecl>(Val: D);
768
769 if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(Val: DeclFD))
770 if (!MethodDecl->isStatic()) {
771 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_no_member_function) << AL;
772 return;
773 }
774
775 auto DiagnoseType = [&](unsigned Index, AttributeArgumentNType T) {
776 SourceLocation Loc = [&]() {
777 auto Union = AL.getArg(Arg: Index - 1);
778 if (auto *E = dyn_cast<Expr *>(Val&: Union))
779 return E->getBeginLoc();
780 return cast<IdentifierLoc *>(Val&: Union)->getLoc();
781 }();
782
783 S.Diag(Loc, DiagID: diag::err_attribute_argument_n_type) << AL << Index << T;
784 };
785
786 FunctionDecl *AttrFD = [&]() -> FunctionDecl * {
787 if (!AL.isArgExpr(Arg: 0))
788 return nullptr;
789 auto *F = dyn_cast_if_present<DeclRefExpr>(Val: AL.getArgAsExpr(Arg: 0));
790 if (!F)
791 return nullptr;
792 return dyn_cast_if_present<FunctionDecl>(Val: F->getFoundDecl());
793 }();
794
795 if (!AttrFD || !AttrFD->getBuiltinID(ConsiderWrapperFunctions: true)) {
796 DiagnoseType(1, AANT_ArgumentBuiltinFunction);
797 return;
798 }
799
800 if (AttrFD->getNumParams() != AL.getNumArgs() - 1) {
801 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_wrong_number_arguments_for)
802 << AL << AttrFD << AttrFD->getNumParams();
803 return;
804 }
805
806 SmallVector<unsigned, 8> Indices;
807
808 for (unsigned I = 1; I < AL.getNumArgs(); ++I) {
809 if (!AL.isArgExpr(Arg: I)) {
810 DiagnoseType(I + 1, AANT_ArgumentIntegerConstant);
811 return;
812 }
813
814 const Expr *IndexExpr = AL.getArgAsExpr(Arg: I);
815 uint32_t Index;
816
817 if (!S.checkUInt32Argument(AI: AL, Expr: IndexExpr, Val&: Index, Idx: I + 1, StrictlyUnsigned: false))
818 return;
819
820 if (Index > DeclFD->getNumParams()) {
821 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_bounds_for_function)
822 << AL << Index << DeclFD << DeclFD->getNumParams();
823 return;
824 }
825
826 QualType T1 = AttrFD->getParamDecl(i: I - 1)->getType();
827 QualType T2 = DeclFD->getParamDecl(i: Index - 1)->getType();
828
829 if (T1.getCanonicalType().getUnqualifiedType() !=
830 T2.getCanonicalType().getUnqualifiedType()) {
831 S.Diag(Loc: IndexExpr->getBeginLoc(), DiagID: diag::err_attribute_parameter_types)
832 << AL << Index << DeclFD << T2 << I << AttrFD << T1;
833 return;
834 }
835
836 Indices.push_back(Elt: Index - 1);
837 }
838
839 D->addAttr(A: ::new (S.Context) DiagnoseAsBuiltinAttr(
840 S.Context, AL, AttrFD, Indices.data(), Indices.size()));
841}
842
843static void handleDiagnoseIfAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
844 S.Diag(Loc: AL.getLoc(), DiagID: diag::ext_clang_diagnose_if);
845
846 Expr *Cond;
847 StringRef Msg;
848 if (!checkFunctionConditionAttr(S, D, AL, Cond, Msg))
849 return;
850
851 StringRef DefaultSevStr;
852 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 2, Str&: DefaultSevStr))
853 return;
854
855 DiagnoseIfAttr::DefaultSeverity DefaultSev;
856 if (!DiagnoseIfAttr::ConvertStrToDefaultSeverity(Val: DefaultSevStr, Out&: DefaultSev)) {
857 S.Diag(Loc: AL.getArgAsExpr(Arg: 2)->getBeginLoc(),
858 DiagID: diag::err_diagnose_if_invalid_diagnostic_type);
859 return;
860 }
861
862 StringRef WarningGroup;
863 if (AL.getNumArgs() > 3) {
864 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 3, Str&: WarningGroup))
865 return;
866 if (WarningGroup.empty() ||
867 !S.getDiagnostics().getDiagnosticIDs()->getGroupForWarningOption(
868 WarningGroup)) {
869 S.Diag(Loc: AL.getArgAsExpr(Arg: 3)->getBeginLoc(),
870 DiagID: diag::err_diagnose_if_unknown_warning)
871 << WarningGroup;
872 return;
873 }
874 }
875
876 bool ArgDependent = false;
877 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D))
878 ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(E: Cond);
879 D->addAttr(A: ::new (S.Context) DiagnoseIfAttr(
880 S.Context, AL, Cond, Msg, DefaultSev, WarningGroup, ArgDependent,
881 cast<NamedDecl>(Val: D)));
882}
883
884static void handleCFIUncheckedCalleeAttr(Sema &S, Decl *D,
885 const ParsedAttr &Attrs) {
886 if (hasDeclarator(D))
887 return;
888
889 if (!isa<ObjCMethodDecl>(Val: D)) {
890 S.Diag(Loc: Attrs.getLoc(), DiagID: diag::warn_attribute_wrong_decl_type)
891 << Attrs << Attrs.isRegularKeywordAttribute()
892 << ExpectedFunctionOrMethod;
893 return;
894 }
895
896 D->addAttr(A: ::new (S.Context) CFIUncheckedCalleeAttr(S.Context, Attrs));
897}
898
899static void handleNoBuiltinAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
900 static constexpr const StringRef kWildcard = "*";
901
902 llvm::SmallVector<StringRef, 16> Names;
903 bool HasWildcard = false;
904
905 const auto AddBuiltinName = [&Names, &HasWildcard](StringRef Name) {
906 if (Name == kWildcard)
907 HasWildcard = true;
908 Names.push_back(Elt: Name);
909 };
910
911 // Add previously defined attributes.
912 if (const auto *NBA = D->getAttr<NoBuiltinAttr>())
913 for (StringRef BuiltinName : NBA->builtinNames())
914 AddBuiltinName(BuiltinName);
915
916 // Add current attributes.
917 if (AL.getNumArgs() == 0)
918 AddBuiltinName(kWildcard);
919 else
920 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
921 StringRef BuiltinName;
922 SourceLocation LiteralLoc;
923 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: BuiltinName, ArgLocation: &LiteralLoc))
924 return;
925
926 if (Builtin::Context::isBuiltinFunc(Name: BuiltinName))
927 AddBuiltinName(BuiltinName);
928 else
929 S.Diag(Loc: LiteralLoc, DiagID: diag::warn_attribute_no_builtin_invalid_builtin_name)
930 << BuiltinName << AL;
931 }
932
933 // Repeating the same attribute is fine.
934 llvm::sort(C&: Names);
935 Names.erase(CS: llvm::unique(R&: Names), CE: Names.end());
936
937 // Empty no_builtin must be on its own.
938 if (HasWildcard && Names.size() > 1)
939 S.Diag(Loc: D->getLocation(),
940 DiagID: diag::err_attribute_no_builtin_wildcard_or_builtin_name)
941 << AL;
942
943 if (D->hasAttr<NoBuiltinAttr>())
944 D->dropAttr<NoBuiltinAttr>();
945 D->addAttr(A: ::new (S.Context)
946 NoBuiltinAttr(S.Context, AL, Names.data(), Names.size()));
947}
948
949static void handlePassObjectSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
950 if (D->hasAttr<PassObjectSizeAttr>()) {
951 S.Diag(Loc: D->getBeginLoc(), DiagID: diag::err_attribute_only_once_per_parameter) << AL;
952 return;
953 }
954
955 Expr *E = AL.getArgAsExpr(Arg: 0);
956 uint32_t Type;
957 if (!S.checkUInt32Argument(AI: AL, Expr: E, Val&: Type, /*Idx=*/1))
958 return;
959
960 // pass_object_size's argument is passed in as the second argument of
961 // __builtin_object_size. So, it has the same constraints as that second
962 // argument; namely, it must be in the range [0, 3].
963 if (Type > 3) {
964 S.Diag(Loc: E->getBeginLoc(), DiagID: diag::err_attribute_argument_out_of_range)
965 << AL << 0 << 3 << E->getSourceRange();
966 return;
967 }
968
969 // pass_object_size is only supported on constant pointer parameters; as a
970 // kindness to users, we allow the parameter to be non-const for declarations.
971 // At this point, we have no clue if `D` belongs to a function declaration or
972 // definition, so we defer the constness check until later.
973 if (!cast<ParmVarDecl>(Val: D)->getType()->isPointerType()) {
974 S.Diag(Loc: D->getBeginLoc(), DiagID: diag::err_attribute_pointers_only) << AL << 1;
975 return;
976 }
977
978 D->addAttr(A: ::new (S.Context) PassObjectSizeAttr(S.Context, AL, (int)Type));
979}
980
981static void handleConsumableAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
982 ConsumableAttr::ConsumedState DefaultState;
983
984 if (AL.isArgIdent(Arg: 0)) {
985 IdentifierLoc *IL = AL.getArgAsIdent(Arg: 0);
986 if (!ConsumableAttr::ConvertStrToConsumedState(
987 Val: IL->getIdentifierInfo()->getName(), Out&: DefaultState)) {
988 S.Diag(Loc: IL->getLoc(), DiagID: diag::warn_attribute_type_not_supported)
989 << AL << IL->getIdentifierInfo();
990 return;
991 }
992 } else {
993 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
994 << AL << AANT_ArgumentIdentifier;
995 return;
996 }
997
998 D->addAttr(A: ::new (S.Context) ConsumableAttr(S.Context, AL, DefaultState));
999}
1000
1001static bool checkForConsumableClass(Sema &S, const CXXMethodDecl *MD,
1002 const ParsedAttr &AL) {
1003 QualType ThisType = MD->getFunctionObjectParameterType();
1004
1005 if (const CXXRecordDecl *RD = ThisType->getAsCXXRecordDecl()) {
1006 if (!RD->hasAttr<ConsumableAttr>()) {
1007 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attr_on_unconsumable_class) << RD;
1008
1009 return false;
1010 }
1011 }
1012
1013 return true;
1014}
1015
1016static void handleCallableWhenAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1017 if (!AL.checkAtLeastNumArgs(S, Num: 1))
1018 return;
1019
1020 if (!checkForConsumableClass(S, MD: cast<CXXMethodDecl>(Val: D), AL))
1021 return;
1022
1023 SmallVector<CallableWhenAttr::ConsumedState, 3> States;
1024 for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); ++ArgIndex) {
1025 CallableWhenAttr::ConsumedState CallableState;
1026
1027 StringRef StateString;
1028 SourceLocation Loc;
1029 if (AL.isArgIdent(Arg: ArgIndex)) {
1030 IdentifierLoc *Ident = AL.getArgAsIdent(Arg: ArgIndex);
1031 StateString = Ident->getIdentifierInfo()->getName();
1032 Loc = Ident->getLoc();
1033 } else {
1034 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: ArgIndex, Str&: StateString, ArgLocation: &Loc))
1035 return;
1036 }
1037
1038 if (!CallableWhenAttr::ConvertStrToConsumedState(Val: StateString,
1039 Out&: CallableState)) {
1040 S.Diag(Loc, DiagID: diag::warn_attribute_type_not_supported) << AL << StateString;
1041 return;
1042 }
1043
1044 States.push_back(Elt: CallableState);
1045 }
1046
1047 D->addAttr(A: ::new (S.Context)
1048 CallableWhenAttr(S.Context, AL, States.data(), States.size()));
1049}
1050
1051static void handleParamTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1052 ParamTypestateAttr::ConsumedState ParamState;
1053
1054 if (AL.isArgIdent(Arg: 0)) {
1055 IdentifierLoc *Ident = AL.getArgAsIdent(Arg: 0);
1056 StringRef StateString = Ident->getIdentifierInfo()->getName();
1057
1058 if (!ParamTypestateAttr::ConvertStrToConsumedState(Val: StateString,
1059 Out&: ParamState)) {
1060 S.Diag(Loc: Ident->getLoc(), DiagID: diag::warn_attribute_type_not_supported)
1061 << AL << StateString;
1062 return;
1063 }
1064 } else {
1065 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
1066 << AL << AANT_ArgumentIdentifier;
1067 return;
1068 }
1069
1070 // FIXME: This check is currently being done in the analysis. It can be
1071 // enabled here only after the parser propagates attributes at
1072 // template specialization definition, not declaration.
1073 //QualType ReturnType = cast<ParmVarDecl>(D)->getType();
1074 //const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1075 //
1076 //if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1077 // S.Diag(AL.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1078 // ReturnType.getAsString();
1079 // return;
1080 //}
1081
1082 D->addAttr(A: ::new (S.Context) ParamTypestateAttr(S.Context, AL, ParamState));
1083}
1084
1085static void handleReturnTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1086 ReturnTypestateAttr::ConsumedState ReturnState;
1087
1088 if (AL.isArgIdent(Arg: 0)) {
1089 IdentifierLoc *IL = AL.getArgAsIdent(Arg: 0);
1090 if (!ReturnTypestateAttr::ConvertStrToConsumedState(
1091 Val: IL->getIdentifierInfo()->getName(), Out&: ReturnState)) {
1092 S.Diag(Loc: IL->getLoc(), DiagID: diag::warn_attribute_type_not_supported)
1093 << AL << IL->getIdentifierInfo();
1094 return;
1095 }
1096 } else {
1097 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
1098 << AL << AANT_ArgumentIdentifier;
1099 return;
1100 }
1101
1102 // FIXME: This check is currently being done in the analysis. It can be
1103 // enabled here only after the parser propagates attributes at
1104 // template specialization definition, not declaration.
1105 // QualType ReturnType;
1106 //
1107 // if (const ParmVarDecl *Param = dyn_cast<ParmVarDecl>(D)) {
1108 // ReturnType = Param->getType();
1109 //
1110 //} else if (const CXXConstructorDecl *Constructor =
1111 // dyn_cast<CXXConstructorDecl>(D)) {
1112 // ReturnType = Constructor->getFunctionObjectParameterType();
1113 //
1114 //} else {
1115 //
1116 // ReturnType = cast<FunctionDecl>(D)->getCallResultType();
1117 //}
1118 //
1119 // const CXXRecordDecl *RD = ReturnType->getAsCXXRecordDecl();
1120 //
1121 // if (!RD || !RD->hasAttr<ConsumableAttr>()) {
1122 // S.Diag(Attr.getLoc(), diag::warn_return_state_for_unconsumable_type) <<
1123 // ReturnType.getAsString();
1124 // return;
1125 //}
1126
1127 D->addAttr(A: ::new (S.Context) ReturnTypestateAttr(S.Context, AL, ReturnState));
1128}
1129
1130static void handleSetTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1131 if (!checkForConsumableClass(S, MD: cast<CXXMethodDecl>(Val: D), AL))
1132 return;
1133
1134 SetTypestateAttr::ConsumedState NewState;
1135 if (AL.isArgIdent(Arg: 0)) {
1136 IdentifierLoc *Ident = AL.getArgAsIdent(Arg: 0);
1137 StringRef Param = Ident->getIdentifierInfo()->getName();
1138 if (!SetTypestateAttr::ConvertStrToConsumedState(Val: Param, Out&: NewState)) {
1139 S.Diag(Loc: Ident->getLoc(), DiagID: diag::warn_attribute_type_not_supported)
1140 << AL << Param;
1141 return;
1142 }
1143 } else {
1144 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
1145 << AL << AANT_ArgumentIdentifier;
1146 return;
1147 }
1148
1149 D->addAttr(A: ::new (S.Context) SetTypestateAttr(S.Context, AL, NewState));
1150}
1151
1152static void handleTestTypestateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1153 if (!checkForConsumableClass(S, MD: cast<CXXMethodDecl>(Val: D), AL))
1154 return;
1155
1156 TestTypestateAttr::ConsumedState TestState;
1157 if (AL.isArgIdent(Arg: 0)) {
1158 IdentifierLoc *Ident = AL.getArgAsIdent(Arg: 0);
1159 StringRef Param = Ident->getIdentifierInfo()->getName();
1160 if (!TestTypestateAttr::ConvertStrToConsumedState(Val: Param, Out&: TestState)) {
1161 S.Diag(Loc: Ident->getLoc(), DiagID: diag::warn_attribute_type_not_supported)
1162 << AL << Param;
1163 return;
1164 }
1165 } else {
1166 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
1167 << AL << AANT_ArgumentIdentifier;
1168 return;
1169 }
1170
1171 D->addAttr(A: ::new (S.Context) TestTypestateAttr(S.Context, AL, TestState));
1172}
1173
1174static void handleExtVectorTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1175 // Remember this typedef decl, we will need it later for diagnostics.
1176 if (isa<TypedefNameDecl>(Val: D))
1177 S.ExtVectorDecls.push_back(LocalValue: cast<TypedefNameDecl>(Val: D));
1178}
1179
1180static void handlePackedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1181 if (auto *TD = dyn_cast<TagDecl>(Val: D))
1182 TD->addAttr(A: ::new (S.Context) PackedAttr(S.Context, AL));
1183 else if (auto *FD = dyn_cast<FieldDecl>(Val: D)) {
1184 bool BitfieldByteAligned = (!FD->getType()->isDependentType() &&
1185 !FD->getType()->isIncompleteType() &&
1186 FD->isBitField() &&
1187 S.Context.getTypeAlign(T: FD->getType()) <= 8);
1188
1189 if (S.getASTContext().getTargetInfo().getTriple().isPS()) {
1190 if (BitfieldByteAligned)
1191 // The PS4/PS5 targets need to maintain ABI backwards compatibility.
1192 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_ignored_for_field_of_type)
1193 << AL << FD->getType();
1194 else
1195 FD->addAttr(A: ::new (S.Context) PackedAttr(S.Context, AL));
1196 } else {
1197 // Report warning about changed offset in the newer compiler versions.
1198 if (BitfieldByteAligned)
1199 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_packed_for_bitfield);
1200
1201 FD->addAttr(A: ::new (S.Context) PackedAttr(S.Context, AL));
1202 }
1203
1204 } else
1205 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_ignored) << AL;
1206}
1207
1208static void handlePreferredName(Sema &S, Decl *D, const ParsedAttr &AL) {
1209 auto *RD = cast<CXXRecordDecl>(Val: D);
1210 ClassTemplateDecl *CTD = RD->getDescribedClassTemplate();
1211 assert(CTD && "attribute does not appertain to this declaration");
1212
1213 ParsedType PT = AL.getTypeArg();
1214 TypeSourceInfo *TSI = nullptr;
1215 QualType T = S.GetTypeFromParser(Ty: PT, TInfo: &TSI);
1216 if (!TSI)
1217 TSI = S.Context.getTrivialTypeSourceInfo(T, Loc: AL.getLoc());
1218
1219 if (!T.hasQualifiers() && T->isTypedefNameType()) {
1220 // Find the template name, if this type names a template specialization.
1221 const TemplateDecl *Template = nullptr;
1222 if (const auto *CTSD = dyn_cast_if_present<ClassTemplateSpecializationDecl>(
1223 Val: T->getAsCXXRecordDecl())) {
1224 Template = CTSD->getSpecializedTemplate();
1225 } else if (const auto *TST = T->getAs<TemplateSpecializationType>()) {
1226 while (TST && TST->isTypeAlias())
1227 TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
1228 if (TST)
1229 Template = TST->getTemplateName().getAsTemplateDecl();
1230 }
1231
1232 if (Template && declaresSameEntity(D1: Template, D2: CTD)) {
1233 D->addAttr(A: ::new (S.Context) PreferredNameAttr(S.Context, AL, TSI));
1234 return;
1235 }
1236 }
1237
1238 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_not_typedef_for_specialization)
1239 << T << AL << CTD;
1240 if (const auto *TT = T->getAs<TypedefType>())
1241 S.Diag(Loc: TT->getDecl()->getLocation(), DiagID: diag::note_entity_declared_at)
1242 << TT->getDecl();
1243}
1244
1245static void handleNoSpecializations(Sema &S, Decl *D, const ParsedAttr &AL) {
1246 StringRef Message;
1247 if (AL.getNumArgs() != 0)
1248 S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: Message);
1249 D->getDescribedTemplate()->addAttr(
1250 A: NoSpecializationsAttr::Create(Ctx&: S.Context, Message, CommonInfo: AL));
1251}
1252
1253bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) {
1254 if (T->isDependentType())
1255 return true;
1256 if (RefOkay) {
1257 if (T->isReferenceType())
1258 return true;
1259 } else {
1260 T = T.getNonReferenceType();
1261 }
1262
1263 // The nonnull attribute, and other similar attributes, can be applied to a
1264 // transparent union that contains a pointer type.
1265 if (const RecordType *UT = T->getAsUnionType()) {
1266 RecordDecl *UD = UT->getDecl()->getDefinitionOrSelf();
1267 if (UD->hasAttr<TransparentUnionAttr>()) {
1268 for (const auto *I : UD->fields()) {
1269 QualType QT = I->getType();
1270 if (QT->isAnyPointerType() || QT->isBlockPointerType())
1271 return true;
1272 }
1273 }
1274 }
1275
1276 return T->isAnyPointerType() || T->isBlockPointerType();
1277}
1278
1279static bool attrNonNullArgCheck(Sema &S, QualType T, const ParsedAttr &AL,
1280 SourceRange AttrParmRange,
1281 SourceRange TypeRange,
1282 bool isReturnValue = false) {
1283 if (!S.isValidPointerAttrType(T)) {
1284 if (isReturnValue)
1285 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_return_pointers_only)
1286 << AL << AttrParmRange << TypeRange;
1287 else
1288 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_pointers_only)
1289 << AL << AttrParmRange << TypeRange << 0;
1290 return false;
1291 }
1292 return true;
1293}
1294
1295static void handleNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1296 SmallVector<ParamIdx, 8> NonNullArgs;
1297 for (unsigned I = 0; I < AL.getNumArgs(); ++I) {
1298 Expr *Ex = AL.getArgAsExpr(Arg: I);
1299 ParamIdx Idx;
1300 if (!S.checkFunctionOrMethodParameterIndex(
1301 D, AI: AL, AttrArgNum: I + 1, IdxExpr: Ex, Idx,
1302 /*CanIndexImplicitThis=*/false,
1303 /*CanIndexVariadicArguments=*/true))
1304 return;
1305
1306 // Is the function argument a pointer type?
1307 if (Idx.getASTIndex() < getFunctionOrMethodNumParams(D) &&
1308 !attrNonNullArgCheck(
1309 S, T: getFunctionOrMethodParamType(D, Idx: Idx.getASTIndex()), AL,
1310 AttrParmRange: Ex->getSourceRange(),
1311 TypeRange: getFunctionOrMethodParamRange(D, Idx: Idx.getASTIndex())))
1312 continue;
1313
1314 NonNullArgs.push_back(Elt: Idx);
1315 }
1316
1317 // If no arguments were specified to __attribute__((nonnull)) then all pointer
1318 // arguments have a nonnull attribute; warn if there aren't any. Skip this
1319 // check if the attribute came from a macro expansion or a template
1320 // instantiation.
1321 if (NonNullArgs.empty() && AL.getLoc().isFileID() &&
1322 !S.inTemplateInstantiation()) {
1323 bool AnyPointers = isFunctionOrMethodVariadic(D);
1324 for (unsigned I = 0, E = getFunctionOrMethodNumParams(D);
1325 I != E && !AnyPointers; ++I) {
1326 QualType T = getFunctionOrMethodParamType(D, Idx: I);
1327 if (S.isValidPointerAttrType(T))
1328 AnyPointers = true;
1329 }
1330
1331 if (!AnyPointers)
1332 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_nonnull_no_pointers);
1333 }
1334
1335 ParamIdx *Start = NonNullArgs.data();
1336 unsigned Size = NonNullArgs.size();
1337 llvm::array_pod_sort(Start, End: Start + Size);
1338 D->addAttr(A: ::new (S.Context) NonNullAttr(S.Context, AL, Start, Size));
1339}
1340
1341static void handleNonNullAttrParameter(Sema &S, ParmVarDecl *D,
1342 const ParsedAttr &AL) {
1343 if (AL.getNumArgs() > 0) {
1344 if (D->getFunctionType()) {
1345 handleNonNullAttr(S, D, AL);
1346 } else {
1347 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_nonnull_parm_no_args)
1348 << D->getSourceRange();
1349 }
1350 return;
1351 }
1352
1353 // Is the argument a pointer type?
1354 if (!attrNonNullArgCheck(S, T: D->getType(), AL, AttrParmRange: SourceRange(),
1355 TypeRange: D->getSourceRange()))
1356 return;
1357
1358 D->addAttr(A: ::new (S.Context) NonNullAttr(S.Context, AL, nullptr, 0));
1359}
1360
1361static void handleReturnsNonNullAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1362 QualType ResultType = getFunctionOrMethodResultType(D);
1363 SourceRange SR = getFunctionOrMethodResultSourceRange(D);
1364 if (!attrNonNullArgCheck(S, T: ResultType, AL, AttrParmRange: SourceRange(), TypeRange: SR,
1365 /* isReturnValue */ true))
1366 return;
1367
1368 D->addAttr(A: ::new (S.Context) ReturnsNonNullAttr(S.Context, AL));
1369}
1370
1371static void handleNoEscapeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1372 if (D->isInvalidDecl())
1373 return;
1374
1375 // noescape only applies to pointer types.
1376 QualType T = cast<ParmVarDecl>(Val: D)->getType();
1377 if (!S.isValidPointerAttrType(T, /* RefOkay */ true)) {
1378 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_pointers_only)
1379 << AL << AL.getRange() << 0;
1380 return;
1381 }
1382
1383 D->addAttr(A: ::new (S.Context) NoEscapeAttr(S.Context, AL));
1384}
1385
1386static void handleAssumeAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1387 Expr *E = AL.getArgAsExpr(Arg: 0),
1388 *OE = AL.getNumArgs() > 1 ? AL.getArgAsExpr(Arg: 1) : nullptr;
1389 S.AddAssumeAlignedAttr(D, CI: AL, E, OE);
1390}
1391
1392static void handleAllocAlignAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1393 S.AddAllocAlignAttr(D, CI: AL, ParamExpr: AL.getArgAsExpr(Arg: 0));
1394}
1395
1396void Sema::AddAssumeAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
1397 Expr *OE) {
1398 QualType ResultType = getFunctionOrMethodResultType(D);
1399 SourceRange SR = getFunctionOrMethodResultSourceRange(D);
1400 SourceLocation AttrLoc = CI.getLoc();
1401
1402 if (!isValidPointerAttrType(T: ResultType, /* RefOkay */ true)) {
1403 Diag(Loc: AttrLoc, DiagID: diag::warn_attribute_return_pointers_refs_only)
1404 << CI << CI.getRange() << SR;
1405 return;
1406 }
1407
1408 if (!E->isValueDependent()) {
1409 std::optional<llvm::APSInt> I = llvm::APSInt(64);
1410 if (!(I = E->getIntegerConstantExpr(Ctx: Context))) {
1411 if (OE)
1412 Diag(Loc: AttrLoc, DiagID: diag::err_attribute_argument_n_type)
1413 << CI << 1 << AANT_ArgumentIntegerConstant << E->getSourceRange();
1414 else
1415 Diag(Loc: AttrLoc, DiagID: diag::err_attribute_argument_type)
1416 << CI << AANT_ArgumentIntegerConstant << E->getSourceRange();
1417 return;
1418 }
1419
1420 if (!I->isPowerOf2()) {
1421 Diag(Loc: AttrLoc, DiagID: diag::err_alignment_not_power_of_two)
1422 << E->getSourceRange();
1423 return;
1424 }
1425
1426 if (*I > Sema::MaximumAlignment)
1427 Diag(Loc: CI.getLoc(), DiagID: diag::warn_assume_aligned_too_great)
1428 << CI.getRange() << Sema::MaximumAlignment;
1429 }
1430
1431 if (OE && !OE->isValueDependent() && !OE->isIntegerConstantExpr(Ctx: Context)) {
1432 Diag(Loc: AttrLoc, DiagID: diag::err_attribute_argument_n_type)
1433 << CI << 2 << AANT_ArgumentIntegerConstant << OE->getSourceRange();
1434 return;
1435 }
1436
1437 D->addAttr(A: ::new (Context) AssumeAlignedAttr(Context, CI, E, OE));
1438}
1439
1440void Sema::AddAllocAlignAttr(Decl *D, const AttributeCommonInfo &CI,
1441 Expr *ParamExpr) {
1442 QualType ResultType = getFunctionOrMethodResultType(D);
1443 SourceLocation AttrLoc = CI.getLoc();
1444
1445 if (!isValidPointerAttrType(T: ResultType, /* RefOkay */ true)) {
1446 Diag(Loc: AttrLoc, DiagID: diag::warn_attribute_return_pointers_refs_only)
1447 << CI << CI.getRange() << getFunctionOrMethodResultSourceRange(D);
1448 return;
1449 }
1450
1451 ParamIdx Idx;
1452 const auto *FuncDecl = cast<FunctionDecl>(Val: D);
1453 if (!checkFunctionOrMethodParameterIndex(D: FuncDecl, AI: CI,
1454 /*AttrArgNum=*/1, IdxExpr: ParamExpr, Idx))
1455 return;
1456
1457 QualType Ty = getFunctionOrMethodParamType(D, Idx: Idx.getASTIndex());
1458 if (!Ty->isDependentType() && !Ty->isIntegralType(Ctx: Context) &&
1459 !Ty->isAlignValT()) {
1460 Diag(Loc: ParamExpr->getBeginLoc(), DiagID: diag::err_attribute_integers_only)
1461 << CI << FuncDecl->getParamDecl(i: Idx.getASTIndex())->getSourceRange();
1462 return;
1463 }
1464
1465 D->addAttr(A: ::new (Context) AllocAlignAttr(Context, CI, Idx));
1466}
1467
1468/// Normalize the attribute, __foo__ becomes foo.
1469/// Returns true if normalization was applied.
1470static bool normalizeName(StringRef &AttrName) {
1471 if (AttrName.size() > 4 && AttrName.starts_with(Prefix: "__") &&
1472 AttrName.ends_with(Suffix: "__")) {
1473 AttrName = AttrName.drop_front(N: 2).drop_back(N: 2);
1474 return true;
1475 }
1476 return false;
1477}
1478
1479static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1480 // This attribute must be applied to a function declaration. The first
1481 // argument to the attribute must be an identifier, the name of the resource,
1482 // for example: malloc. The following arguments must be argument indexes, the
1483 // arguments must be of integer type for Returns, otherwise of pointer type.
1484 // The difference between Holds and Takes is that a pointer may still be used
1485 // after being held. free() should be __attribute((ownership_takes)), whereas
1486 // a list append function may well be __attribute((ownership_holds)).
1487
1488 if (!AL.isArgIdent(Arg: 0)) {
1489 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
1490 << AL << 1 << AANT_ArgumentIdentifier;
1491 return;
1492 }
1493
1494 // Figure out our Kind.
1495 OwnershipAttr::OwnershipKind K =
1496 OwnershipAttr(S.Context, AL, nullptr, nullptr, 0).getOwnKind();
1497
1498 // Check arguments.
1499 switch (K) {
1500 case OwnershipAttr::Takes:
1501 case OwnershipAttr::Holds:
1502 if (AL.getNumArgs() < 2) {
1503 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_too_few_arguments) << AL << 2;
1504 return;
1505 }
1506 break;
1507 case OwnershipAttr::Returns:
1508 if (AL.getNumArgs() > 2) {
1509 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_too_many_arguments) << AL << 2;
1510 return;
1511 }
1512 break;
1513 }
1514
1515 // Allow only pointers to be return type for functions with ownership_returns
1516 // attribute. This matches with current OwnershipAttr::Takes semantics
1517 if (K == OwnershipAttr::Returns &&
1518 !getFunctionOrMethodResultType(D)->isPointerType()) {
1519 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_ownership_takes_return_type) << AL;
1520 return;
1521 }
1522
1523 IdentifierInfo *Module = AL.getArgAsIdent(Arg: 0)->getIdentifierInfo();
1524
1525 StringRef ModuleName = Module->getName();
1526 if (normalizeName(AttrName&: ModuleName)) {
1527 Module = &S.PP.getIdentifierTable().get(Name: ModuleName);
1528 }
1529
1530 SmallVector<ParamIdx, 8> OwnershipArgs;
1531 for (unsigned i = 1; i < AL.getNumArgs(); ++i) {
1532 Expr *Ex = AL.getArgAsExpr(Arg: i);
1533 ParamIdx Idx;
1534 if (!S.checkFunctionOrMethodParameterIndex(D, AI: AL, AttrArgNum: i, IdxExpr: Ex, Idx))
1535 return;
1536
1537 // Is the function argument a pointer type?
1538 QualType T = getFunctionOrMethodParamType(D, Idx: Idx.getASTIndex());
1539 int Err = -1; // No error
1540 switch (K) {
1541 case OwnershipAttr::Takes:
1542 case OwnershipAttr::Holds:
1543 if (!T->isAnyPointerType() && !T->isBlockPointerType())
1544 Err = 0;
1545 break;
1546 case OwnershipAttr::Returns:
1547 if (!T->isIntegerType())
1548 Err = 1;
1549 break;
1550 }
1551 if (-1 != Err) {
1552 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_ownership_type) << AL << Err
1553 << Ex->getSourceRange();
1554 return;
1555 }
1556
1557 // Check we don't have a conflict with another ownership attribute.
1558 for (const auto *I : D->specific_attrs<OwnershipAttr>()) {
1559 // Cannot have two ownership attributes of different kinds for the same
1560 // index.
1561 if (I->getOwnKind() != K && llvm::is_contained(Range: I->args(), Element: Idx)) {
1562 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attributes_are_not_compatible)
1563 << AL << I
1564 << (AL.isRegularKeywordAttribute() ||
1565 I->isRegularKeywordAttribute());
1566 return;
1567 } else if (K == OwnershipAttr::Returns &&
1568 I->getOwnKind() == OwnershipAttr::Returns) {
1569 // A returns attribute conflicts with any other returns attribute using
1570 // a different index.
1571 if (!llvm::is_contained(Range: I->args(), Element: Idx)) {
1572 S.Diag(Loc: I->getLocation(), DiagID: diag::err_ownership_returns_index_mismatch)
1573 << I->args_begin()->getSourceIndex();
1574 if (I->args_size())
1575 S.Diag(Loc: AL.getLoc(), DiagID: diag::note_ownership_returns_index_mismatch)
1576 << Idx.getSourceIndex() << Ex->getSourceRange();
1577 return;
1578 }
1579 } else if (K == OwnershipAttr::Takes &&
1580 I->getOwnKind() == OwnershipAttr::Takes) {
1581 if (I->getModule()->getName() != ModuleName) {
1582 S.Diag(Loc: I->getLocation(), DiagID: diag::err_ownership_takes_class_mismatch)
1583 << I->getModule()->getName();
1584 S.Diag(Loc: AL.getLoc(), DiagID: diag::note_ownership_takes_class_mismatch)
1585 << ModuleName << Ex->getSourceRange();
1586
1587 return;
1588 }
1589 }
1590 }
1591 OwnershipArgs.push_back(Elt: Idx);
1592 }
1593
1594 ParamIdx *Start = OwnershipArgs.data();
1595 unsigned Size = OwnershipArgs.size();
1596 llvm::array_pod_sort(Start, End: Start + Size);
1597 D->addAttr(A: ::new (S.Context)
1598 OwnershipAttr(S.Context, AL, Module, Start, Size));
1599}
1600
1601static void handleWeakRefAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1602 // Check the attribute arguments.
1603 if (AL.getNumArgs() > 1) {
1604 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_wrong_number_arguments) << AL << 1;
1605 return;
1606 }
1607
1608 // gcc rejects
1609 // class c {
1610 // static int a __attribute__((weakref ("v2")));
1611 // static int b() __attribute__((weakref ("f3")));
1612 // };
1613 // and ignores the attributes of
1614 // void f(void) {
1615 // static int a __attribute__((weakref ("v2")));
1616 // }
1617 // we reject them
1618 const DeclContext *Ctx = D->getDeclContext()->getRedeclContext();
1619 if (!Ctx->isFileContext()) {
1620 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_weakref_not_global_context)
1621 << cast<NamedDecl>(Val: D);
1622 return;
1623 }
1624
1625 // The GCC manual says
1626 //
1627 // At present, a declaration to which `weakref' is attached can only
1628 // be `static'.
1629 //
1630 // It also says
1631 //
1632 // Without a TARGET,
1633 // given as an argument to `weakref' or to `alias', `weakref' is
1634 // equivalent to `weak'.
1635 //
1636 // gcc 4.4.1 will accept
1637 // int a7 __attribute__((weakref));
1638 // as
1639 // int a7 __attribute__((weak));
1640 // This looks like a bug in gcc. We reject that for now. We should revisit
1641 // it if this behaviour is actually used.
1642
1643 // GCC rejects
1644 // static ((alias ("y"), weakref)).
1645 // Should we? How to check that weakref is before or after alias?
1646
1647 // FIXME: it would be good for us to keep the WeakRefAttr as-written instead
1648 // of transforming it into an AliasAttr. The WeakRefAttr never uses the
1649 // StringRef parameter it was given anyway.
1650 StringRef Str;
1651 if (AL.getNumArgs() && S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str))
1652 // GCC will accept anything as the argument of weakref. Should we
1653 // check for an existing decl?
1654 D->addAttr(A: ::new (S.Context) AliasAttr(S.Context, AL, Str));
1655
1656 D->addAttr(A: ::new (S.Context) WeakRefAttr(S.Context, AL));
1657}
1658
1659// Mark alias/ifunc target as used. Due to name mangling, we look up the
1660// demangled name ignoring parameters (not supported by microsoftDemangle
1661// https://github.com/llvm/llvm-project/issues/88825). This should handle the
1662// majority of use cases while leaving namespace scope names unmarked.
1663static void markUsedForAliasOrIfunc(Sema &S, Decl *D, const ParsedAttr &AL,
1664 StringRef Str) {
1665 std::unique_ptr<char, llvm::FreeDeleter> Demangled;
1666 if (S.getASTContext().getCXXABIKind() != TargetCXXABI::Microsoft)
1667 Demangled.reset(p: llvm::itaniumDemangle(mangled_name: Str, /*ParseParams=*/false));
1668 std::unique_ptr<MangleContext> MC(S.Context.createMangleContext());
1669 SmallString<256> Name;
1670
1671 const DeclarationNameInfo Target(
1672 &S.Context.Idents.get(Name: Demangled ? Demangled.get() : Str), AL.getLoc());
1673 LookupResult LR(S, Target, Sema::LookupOrdinaryName);
1674 if (S.LookupName(R&: LR, S: S.TUScope)) {
1675 for (NamedDecl *ND : LR) {
1676 if (!isa<FunctionDecl>(Val: ND) && !isa<VarDecl>(Val: ND))
1677 continue;
1678 if (MC->shouldMangleDeclName(D: ND)) {
1679 llvm::raw_svector_ostream Out(Name);
1680 Name.clear();
1681 MC->mangleName(GD: GlobalDecl(ND), Out);
1682 } else {
1683 Name = ND->getIdentifier()->getName();
1684 }
1685 if (Name == Str)
1686 ND->markUsed(C&: S.Context);
1687 }
1688 }
1689}
1690
1691static void handleIFuncAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1692 StringRef Str;
1693 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str))
1694 return;
1695
1696 // Aliases should be on declarations, not definitions.
1697 const auto *FD = cast<FunctionDecl>(Val: D);
1698 if (FD->isThisDeclarationADefinition()) {
1699 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_alias_is_definition) << FD << 1;
1700 return;
1701 }
1702
1703 markUsedForAliasOrIfunc(S, D, AL, Str);
1704 D->addAttr(A: ::new (S.Context) IFuncAttr(S.Context, AL, Str));
1705}
1706
1707static void handleAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1708 StringRef Str;
1709 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str))
1710 return;
1711
1712 if (S.Context.getTargetInfo().getTriple().isOSDarwin()) {
1713 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_alias_not_supported_on_darwin);
1714 return;
1715 }
1716
1717 if (S.Context.getTargetInfo().getTriple().isNVPTX()) {
1718 CudaVersion Version =
1719 ToCudaVersion(S.Context.getTargetInfo().getSDKVersion());
1720 if (Version != CudaVersion::UNKNOWN && Version < CudaVersion::CUDA_100)
1721 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_alias_not_supported_on_nvptx);
1722 }
1723
1724 // Aliases should be on declarations, not definitions.
1725 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
1726 if (FD->isThisDeclarationADefinition()) {
1727 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_alias_is_definition) << FD << 0;
1728 return;
1729 }
1730 } else {
1731 const auto *VD = cast<VarDecl>(Val: D);
1732 if (VD->isThisDeclarationADefinition() && VD->isExternallyVisible()) {
1733 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_alias_is_definition) << VD << 0;
1734 return;
1735 }
1736 }
1737
1738 markUsedForAliasOrIfunc(S, D, AL, Str);
1739 D->addAttr(A: ::new (S.Context) AliasAttr(S.Context, AL, Str));
1740}
1741
1742static void handleTLSModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1743 StringRef Model;
1744 SourceLocation LiteralLoc;
1745 // Check that it is a string.
1746 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: Model, ArgLocation: &LiteralLoc))
1747 return;
1748
1749 // Check that the value.
1750 if (Model != "global-dynamic" && Model != "local-dynamic"
1751 && Model != "initial-exec" && Model != "local-exec") {
1752 S.Diag(Loc: LiteralLoc, DiagID: diag::err_attr_tlsmodel_arg);
1753 return;
1754 }
1755
1756 D->addAttr(A: ::new (S.Context) TLSModelAttr(S.Context, AL, Model));
1757}
1758
1759static void handleRestrictAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1760 QualType ResultType = getFunctionOrMethodResultType(D);
1761 if (!ResultType->isAnyPointerType() && !ResultType->isBlockPointerType()) {
1762 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_return_pointers_only)
1763 << AL << getFunctionOrMethodResultSourceRange(D);
1764 return;
1765 }
1766
1767 if (AL.getNumArgs() == 0) {
1768 D->addAttr(A: ::new (S.Context) RestrictAttr(S.Context, AL));
1769 return;
1770 }
1771
1772 if (AL.getAttributeSpellingListIndex() == RestrictAttr::Declspec_restrict) {
1773 // __declspec(restrict) accepts no arguments
1774 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_wrong_number_arguments) << AL << 0;
1775 return;
1776 }
1777
1778 // [[gnu::malloc(deallocator)]] with args specifies a deallocator function
1779 Expr *DeallocE = AL.getArgAsExpr(Arg: 0);
1780 SourceLocation DeallocLoc = DeallocE->getExprLoc();
1781 FunctionDecl *DeallocFD = nullptr;
1782 DeclarationNameInfo DeallocNI;
1783
1784 if (auto *DRE = dyn_cast<DeclRefExpr>(Val: DeallocE)) {
1785 DeallocFD = dyn_cast<FunctionDecl>(Val: DRE->getDecl());
1786 DeallocNI = DRE->getNameInfo();
1787 if (!DeallocFD) {
1788 S.Diag(Loc: DeallocLoc, DiagID: diag::err_attribute_malloc_arg_not_function)
1789 << 1 << DeallocNI.getName();
1790 return;
1791 }
1792 } else if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(Val: DeallocE)) {
1793 DeallocFD = S.ResolveSingleFunctionTemplateSpecialization(ovl: ULE, Complain: true);
1794 DeallocNI = ULE->getNameInfo();
1795 if (!DeallocFD) {
1796 S.Diag(Loc: DeallocLoc, DiagID: diag::err_attribute_malloc_arg_not_function)
1797 << 2 << DeallocNI.getName();
1798 if (ULE->getType() == S.Context.OverloadTy)
1799 S.NoteAllOverloadCandidates(E: ULE);
1800 return;
1801 }
1802 } else {
1803 S.Diag(Loc: DeallocLoc, DiagID: diag::err_attribute_malloc_arg_not_function) << 0;
1804 return;
1805 }
1806
1807 // 2nd arg of [[gnu::malloc(deallocator, 2)]] with args specifies the param
1808 // of deallocator that deallocates the pointer (defaults to 1)
1809 ParamIdx DeallocPtrIdx;
1810 if (AL.getNumArgs() == 1) {
1811 DeallocPtrIdx = ParamIdx(1, DeallocFD);
1812
1813 // FIXME: We could probably be better about diagnosing that there IS no
1814 // argument, or that the function doesn't have a prototype, but this is how
1815 // GCC diagnoses this, and is reasonably clear.
1816 if (!DeallocPtrIdx.isValid() || !hasFunctionProto(D: DeallocFD) ||
1817 getFunctionOrMethodNumParams(D: DeallocFD) < 1 ||
1818 !getFunctionOrMethodParamType(D: DeallocFD, Idx: DeallocPtrIdx.getASTIndex())
1819 .getCanonicalType()
1820 ->isPointerType()) {
1821 S.Diag(Loc: DeallocLoc,
1822 DiagID: diag::err_attribute_malloc_arg_not_function_with_pointer_arg)
1823 << DeallocNI.getName();
1824 return;
1825 }
1826 } else {
1827 if (!S.checkFunctionOrMethodParameterIndex(
1828 D: DeallocFD, AI: AL, AttrArgNum: 2, IdxExpr: AL.getArgAsExpr(Arg: 1), Idx&: DeallocPtrIdx,
1829 /* CanIndexImplicitThis=*/false))
1830 return;
1831
1832 QualType DeallocPtrArgType =
1833 getFunctionOrMethodParamType(D: DeallocFD, Idx: DeallocPtrIdx.getASTIndex());
1834 if (!DeallocPtrArgType.getCanonicalType()->isPointerType()) {
1835 S.Diag(Loc: DeallocLoc,
1836 DiagID: diag::err_attribute_malloc_arg_refers_to_non_pointer_type)
1837 << DeallocPtrIdx.getSourceIndex() << DeallocPtrArgType
1838 << DeallocNI.getName();
1839 return;
1840 }
1841 }
1842
1843 // FIXME: we should add this attribute to Clang's AST, so that clang-analyzer
1844 // can use it, see -Wmismatched-dealloc in GCC for what we can do with this.
1845 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_form_ignored) << AL;
1846 D->addAttr(A: ::new (S.Context)
1847 RestrictAttr(S.Context, AL, DeallocE, DeallocPtrIdx));
1848}
1849
1850bool Sema::CheckSpanLikeType(const AttributeCommonInfo &CI,
1851 const QualType &Ty) {
1852 // Note that there may also be numerous cases of pointer + integer /
1853 // pointer + pointer / integer + pointer structures not actually exhibiting
1854 // a span-like semantics, so sometimes these heuristics expectedly
1855 // lead to false positive results.
1856 auto emitWarning = [this, &CI](unsigned NoteDiagID) {
1857 Diag(Loc: CI.getLoc(), DiagID: diag::warn_attribute_return_span_only) << CI;
1858 return Diag(Loc: CI.getLoc(), DiagID: NoteDiagID);
1859 };
1860 if (Ty->isDependentType())
1861 return false;
1862 // isCompleteType is used to force template class instantiation.
1863 if (!isCompleteType(Loc: CI.getLoc(), T: Ty))
1864 return emitWarning(diag::note_returned_incomplete_type);
1865 const RecordDecl *RD = Ty->getAsRecordDecl();
1866 if (!RD || RD->isUnion())
1867 return emitWarning(diag::note_returned_not_struct);
1868 if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(Val: RD)) {
1869 if (CXXRD->getNumBases() > 0) {
1870 return emitWarning(diag::note_type_inherits_from_base);
1871 }
1872 }
1873 auto FieldsBegin = RD->field_begin();
1874 auto FieldsCount = std::distance(first: FieldsBegin, last: RD->field_end());
1875 if (FieldsCount != 2)
1876 return emitWarning(diag::note_returned_not_two_field_struct) << FieldsCount;
1877 QualType FirstFieldType = FieldsBegin->getType();
1878 QualType SecondFieldType = std::next(x: FieldsBegin)->getType();
1879 auto validatePointerType = [](const QualType &T) {
1880 // It must not point to functions.
1881 return T->isPointerType() && !T->isFunctionPointerType();
1882 };
1883 auto checkIntegerType = [this, emitWarning](const QualType &T,
1884 const int FieldNo) -> bool {
1885 const auto *BT = dyn_cast<BuiltinType>(Val: T.getCanonicalType());
1886 if (!BT || !BT->isInteger())
1887 return emitWarning(diag::note_returned_not_integer_field) << FieldNo;
1888 auto IntSize = Context.getTypeSize(T: Context.IntTy);
1889 if (Context.getTypeSize(T: BT) < IntSize)
1890 return emitWarning(diag::note_returned_not_wide_enough_field)
1891 << FieldNo << IntSize;
1892 return false;
1893 };
1894 if (validatePointerType(FirstFieldType) &&
1895 validatePointerType(SecondFieldType)) {
1896 // Pointer + pointer.
1897 return false;
1898 } else if (validatePointerType(FirstFieldType)) {
1899 // Pointer + integer?
1900 return checkIntegerType(SecondFieldType, 2);
1901 } else if (validatePointerType(SecondFieldType)) {
1902 // Integer + pointer?
1903 return checkIntegerType(FirstFieldType, 1);
1904 }
1905 return emitWarning(diag::note_returned_not_span_struct);
1906}
1907
1908static void handleMallocSpanAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1909 QualType ResultType = getFunctionOrMethodResultType(D);
1910 if (!S.CheckSpanLikeType(CI: AL, Ty: ResultType))
1911 D->addAttr(A: ::new (S.Context) MallocSpanAttr(S.Context, AL));
1912}
1913
1914static void handleCPUSpecificAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1915 // Ensure we don't combine these with themselves, since that causes some
1916 // confusing behavior.
1917 if (AL.getParsedKind() == ParsedAttr::AT_CPUDispatch) {
1918 if (checkAttrMutualExclusion<CPUSpecificAttr>(S, D, AL))
1919 return;
1920
1921 if (const auto *Other = D->getAttr<CPUDispatchAttr>()) {
1922 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_disallowed_duplicate_attribute) << AL;
1923 S.Diag(Loc: Other->getLocation(), DiagID: diag::note_conflicting_attribute);
1924 return;
1925 }
1926 } else if (AL.getParsedKind() == ParsedAttr::AT_CPUSpecific) {
1927 if (checkAttrMutualExclusion<CPUDispatchAttr>(S, D, AL))
1928 return;
1929
1930 if (const auto *Other = D->getAttr<CPUSpecificAttr>()) {
1931 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_disallowed_duplicate_attribute) << AL;
1932 S.Diag(Loc: Other->getLocation(), DiagID: diag::note_conflicting_attribute);
1933 return;
1934 }
1935 }
1936
1937 FunctionDecl *FD = cast<FunctionDecl>(Val: D);
1938
1939 if (const auto *MD = dyn_cast<CXXMethodDecl>(Val: D)) {
1940 if (MD->getParent()->isLambda()) {
1941 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_dll_lambda) << AL;
1942 return;
1943 }
1944 }
1945
1946 if (!AL.checkAtLeastNumArgs(S, Num: 1))
1947 return;
1948
1949 SmallVector<const IdentifierInfo *, 8> CPUs;
1950 for (unsigned ArgNo = 0; ArgNo < getNumAttributeArgs(AL); ++ArgNo) {
1951 if (!AL.isArgIdent(Arg: ArgNo)) {
1952 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
1953 << AL << AANT_ArgumentIdentifier;
1954 return;
1955 }
1956
1957 IdentifierLoc *CPUArg = AL.getArgAsIdent(Arg: ArgNo);
1958 StringRef CPUName = CPUArg->getIdentifierInfo()->getName().trim();
1959
1960 if (!S.Context.getTargetInfo().validateCPUSpecificCPUDispatch(Name: CPUName)) {
1961 S.Diag(Loc: CPUArg->getLoc(), DiagID: diag::err_invalid_cpu_specific_dispatch_value)
1962 << CPUName << (AL.getKind() == ParsedAttr::AT_CPUDispatch);
1963 return;
1964 }
1965
1966 const TargetInfo &Target = S.Context.getTargetInfo();
1967 if (llvm::any_of(Range&: CPUs, P: [CPUName, &Target](const IdentifierInfo *Cur) {
1968 return Target.CPUSpecificManglingCharacter(Name: CPUName) ==
1969 Target.CPUSpecificManglingCharacter(Name: Cur->getName());
1970 })) {
1971 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_multiversion_duplicate_entries);
1972 return;
1973 }
1974 CPUs.push_back(Elt: CPUArg->getIdentifierInfo());
1975 }
1976
1977 FD->setIsMultiVersion(true);
1978 if (AL.getKind() == ParsedAttr::AT_CPUSpecific)
1979 D->addAttr(A: ::new (S.Context)
1980 CPUSpecificAttr(S.Context, AL, CPUs.data(), CPUs.size()));
1981 else
1982 D->addAttr(A: ::new (S.Context)
1983 CPUDispatchAttr(S.Context, AL, CPUs.data(), CPUs.size()));
1984}
1985
1986static void handleCommonAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1987 if (S.LangOpts.CPlusPlus) {
1988 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_not_supported_in_lang)
1989 << AL << AttributeLangSupport::Cpp;
1990 return;
1991 }
1992
1993 D->addAttr(A: ::new (S.Context) CommonAttr(S.Context, AL));
1994}
1995
1996static void handleNakedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
1997 if (AL.isDeclspecAttribute()) {
1998 const auto &Triple = S.getASTContext().getTargetInfo().getTriple();
1999 const auto &Arch = Triple.getArch();
2000 if (Arch != llvm::Triple::x86 &&
2001 (Arch != llvm::Triple::arm && Arch != llvm::Triple::thumb)) {
2002 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_not_supported_on_arch)
2003 << AL << Triple.getArchName();
2004 return;
2005 }
2006
2007 // This form is not allowed to be written on a member function (static or
2008 // nonstatic) when in Microsoft compatibility mode.
2009 if (S.getLangOpts().MSVCCompat && isa<CXXMethodDecl>(Val: D)) {
2010 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_wrong_decl_type)
2011 << AL << AL.isRegularKeywordAttribute() << ExpectedNonMemberFunction;
2012 return;
2013 }
2014 }
2015
2016 D->addAttr(A: ::new (S.Context) NakedAttr(S.Context, AL));
2017}
2018
2019// FIXME: This is a best-effort heuristic.
2020// Currently only handles single throw expressions (optionally with
2021// ExprWithCleanups). We could expand this to perform control-flow analysis for
2022// more complex patterns.
2023static bool isKnownToAlwaysThrow(const FunctionDecl *FD) {
2024 if (!FD->hasBody())
2025 return false;
2026 const Stmt *Body = FD->getBody();
2027 const Stmt *OnlyStmt = nullptr;
2028
2029 if (const auto *Compound = dyn_cast<CompoundStmt>(Val: Body)) {
2030 if (Compound->size() != 1)
2031 return false; // More than one statement, can't be known to always throw.
2032 OnlyStmt = *Compound->body_begin();
2033 } else {
2034 OnlyStmt = Body;
2035 }
2036
2037 // Unwrap ExprWithCleanups if necessary.
2038 if (const auto *EWC = dyn_cast<ExprWithCleanups>(Val: OnlyStmt)) {
2039 OnlyStmt = EWC->getSubExpr();
2040 }
2041
2042 if (isa<CXXThrowExpr>(Val: OnlyStmt)) {
2043 const auto *MD = dyn_cast<CXXMethodDecl>(Val: FD);
2044 if (MD && MD->isVirtual()) {
2045 const auto *RD = MD->getParent();
2046 return MD->hasAttr<FinalAttr>() || (RD && RD->isEffectivelyFinal());
2047 }
2048 return true;
2049 }
2050 return false;
2051}
2052
2053void clang::inferNoReturnAttr(Sema &S, Decl *D) {
2054 auto *FD = dyn_cast<FunctionDecl>(Val: D);
2055 if (!FD)
2056 return;
2057
2058 // Skip explicit specializations here as they may have
2059 // a user-provided definition that may deliberately differ from the primary
2060 // template. If an explicit specialization truly never returns, the user
2061 // should explicitly mark it with [[noreturn]].
2062 if (FD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
2063 return;
2064
2065 DiagnosticsEngine &Diags = S.getDiagnostics();
2066 if (Diags.isIgnored(DiagID: diag::warn_falloff_nonvoid, Loc: FD->getLocation()) &&
2067 Diags.isIgnored(DiagID: diag::warn_suggest_noreturn_function, Loc: FD->getLocation()))
2068 return;
2069
2070 if (!FD->isNoReturn() && !FD->hasAttr<InferredNoReturnAttr>() &&
2071 isKnownToAlwaysThrow(FD)) {
2072 FD->addAttr(A: InferredNoReturnAttr::CreateImplicit(Ctx&: S.Context));
2073
2074 // [[noreturn]] can only be added to lambdas since C++23
2075 if (const auto *MD = dyn_cast<CXXMethodDecl>(Val: FD);
2076 MD && !S.getLangOpts().CPlusPlus23 && isLambdaCallOperator(MD))
2077 return;
2078
2079 // Emit a diagnostic suggesting the function being marked [[noreturn]].
2080 S.Diag(Loc: FD->getLocation(), DiagID: diag::warn_suggest_noreturn_function)
2081 << /*isFunction=*/0 << FD;
2082 }
2083}
2084
2085static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
2086 if (hasDeclarator(D)) return;
2087
2088 if (!isa<ObjCMethodDecl>(Val: D)) {
2089 S.Diag(Loc: Attrs.getLoc(), DiagID: diag::warn_attribute_wrong_decl_type)
2090 << Attrs << Attrs.isRegularKeywordAttribute()
2091 << ExpectedFunctionOrMethod;
2092 return;
2093 }
2094
2095 D->addAttr(A: ::new (S.Context) NoReturnAttr(S.Context, Attrs));
2096}
2097
2098static void handleStandardNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &A) {
2099 // The [[_Noreturn]] spelling is deprecated in C23, so if that was used,
2100 // issue an appropriate diagnostic. However, don't issue a diagnostic if the
2101 // attribute name comes from a macro expansion. We don't want to punish users
2102 // who write [[noreturn]] after including <stdnoreturn.h> (where 'noreturn'
2103 // is defined as a macro which expands to '_Noreturn').
2104 if (!S.getLangOpts().CPlusPlus &&
2105 A.getSemanticSpelling() == CXX11NoReturnAttr::C23_Noreturn &&
2106 !(A.getLoc().isMacroID() &&
2107 S.getSourceManager().isInSystemMacro(loc: A.getLoc())))
2108 S.Diag(Loc: A.getLoc(), DiagID: diag::warn_deprecated_noreturn_spelling) << A.getRange();
2109
2110 D->addAttr(A: ::new (S.Context) CXX11NoReturnAttr(S.Context, A));
2111}
2112
2113static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
2114 if (!S.getLangOpts().CFProtectionBranch)
2115 S.Diag(Loc: Attrs.getLoc(), DiagID: diag::warn_nocf_check_attribute_ignored);
2116 else
2117 handleSimpleAttribute<AnyX86NoCfCheckAttr>(S, D, CI: Attrs);
2118}
2119
2120bool Sema::CheckAttrNoArgs(const ParsedAttr &Attrs) {
2121 if (!Attrs.checkExactlyNumArgs(S&: *this, Num: 0)) {
2122 Attrs.setInvalid();
2123 return true;
2124 }
2125
2126 return false;
2127}
2128
2129bool Sema::CheckAttrTarget(const ParsedAttr &AL) {
2130 // Check whether the attribute is valid on the current target.
2131 if (!AL.existsInTarget(Target: Context.getTargetInfo())) {
2132 if (AL.isRegularKeywordAttribute())
2133 Diag(Loc: AL.getLoc(), DiagID: diag::err_keyword_not_supported_on_target)
2134 << AL << AL.getRange();
2135 else
2136 DiagnoseUnknownAttribute(AL);
2137 AL.setInvalid();
2138 return true;
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 (!isFunctionOrMethodOrBlockForAttrSubject(D)) {
2148 ValueDecl *VD = dyn_cast<ValueDecl>(Val: D);
2149 if (!VD || (!VD->getType()->isBlockPointerType() &&
2150 !VD->getType()->isFunctionPointerType())) {
2151 S.Diag(Loc: AL.getLoc(), DiagID: AL.isStandardAttributeSyntax()
2152 ? diag::err_attribute_wrong_decl_type
2153 : diag::warn_attribute_wrong_decl_type)
2154 << AL << AL.isRegularKeywordAttribute()
2155 << ExpectedFunctionMethodOrBlock;
2156 return;
2157 }
2158 }
2159
2160 D->addAttr(A: ::new (S.Context) AnalyzerNoReturnAttr(S.Context, AL));
2161}
2162
2163// PS3 PPU-specific.
2164static void handleVecReturnAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2165 /*
2166 Returning a Vector Class in Registers
2167
2168 According to the PPU ABI specifications, a class with a single member of
2169 vector type is returned in memory when used as the return value of a
2170 function.
2171 This results in inefficient code when implementing vector classes. To return
2172 the value in a single vector register, add the vecreturn attribute to the
2173 class definition. This attribute is also applicable to struct types.
2174
2175 Example:
2176
2177 struct Vector
2178 {
2179 __vector float xyzw;
2180 } __attribute__((vecreturn));
2181
2182 Vector Add(Vector lhs, Vector rhs)
2183 {
2184 Vector result;
2185 result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
2186 return result; // This will be returned in a register
2187 }
2188 */
2189 if (VecReturnAttr *A = D->getAttr<VecReturnAttr>()) {
2190 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_repeat_attribute) << A;
2191 return;
2192 }
2193
2194 const auto *R = cast<RecordDecl>(Val: D);
2195 int count = 0;
2196
2197 if (!isa<CXXRecordDecl>(Val: R)) {
2198 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_vecreturn_only_vector_member);
2199 return;
2200 }
2201
2202 if (!cast<CXXRecordDecl>(Val: R)->isPOD()) {
2203 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_vecreturn_only_pod_record);
2204 return;
2205 }
2206
2207 for (const auto *I : R->fields()) {
2208 if ((count == 1) || !I->getType()->isVectorType()) {
2209 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_vecreturn_only_vector_member);
2210 return;
2211 }
2212 count++;
2213 }
2214
2215 D->addAttr(A: ::new (S.Context) VecReturnAttr(S.Context, AL));
2216}
2217
2218static void handleDependencyAttr(Sema &S, Scope *Scope, Decl *D,
2219 const ParsedAttr &AL) {
2220 if (isa<ParmVarDecl>(Val: D)) {
2221 // [[carries_dependency]] can only be applied to a parameter if it is a
2222 // parameter of a function declaration or lambda.
2223 if (!(Scope->getFlags() & clang::Scope::FunctionDeclarationScope)) {
2224 S.Diag(Loc: AL.getLoc(),
2225 DiagID: diag::err_carries_dependency_param_not_function_decl);
2226 return;
2227 }
2228 }
2229
2230 D->addAttr(A: ::new (S.Context) CarriesDependencyAttr(S.Context, AL));
2231}
2232
2233static void handleUnusedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2234 bool IsCXX17Attr = AL.isCXX11Attribute() && !AL.getScopeName();
2235
2236 // If this is spelled as the standard C++17 attribute, but not in C++17, warn
2237 // about using it as an extension.
2238 if (!S.getLangOpts().CPlusPlus17 && IsCXX17Attr)
2239 S.Diag(Loc: AL.getLoc(), DiagID: diag::ext_cxx17_attr) << AL;
2240
2241 D->addAttr(A: ::new (S.Context) UnusedAttr(S.Context, AL));
2242}
2243
2244static ExprResult sharedGetConstructorDestructorAttrExpr(Sema &S,
2245 const ParsedAttr &AL) {
2246 // If no Expr node exists on the attribute, return a nullptr result (default
2247 // priority to be used). If Expr node exists but is not valid, return an
2248 // invalid result. Otherwise, return the Expr.
2249 Expr *E = nullptr;
2250 if (AL.getNumArgs() == 1) {
2251 E = AL.getArgAsExpr(Arg: 0);
2252 if (E->isValueDependent()) {
2253 if (!E->isTypeDependent() && !E->getType()->isIntegerType()) {
2254 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
2255 << AL << AANT_ArgumentIntegerConstant << E->getSourceRange();
2256 return ExprError();
2257 }
2258 } else {
2259 uint32_t priority;
2260 if (!S.checkUInt32Argument(AI: AL, Expr: AL.getArgAsExpr(Arg: 0), Val&: priority)) {
2261 return ExprError();
2262 }
2263 return ConstantExpr::Create(Context: S.Context, E,
2264 Result: APValue(llvm::APSInt::getUnsigned(X: priority)));
2265 }
2266 }
2267 return E;
2268}
2269
2270static void handleConstructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2271 if (S.getLangOpts().HLSL && AL.getNumArgs()) {
2272 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_hlsl_init_priority_unsupported);
2273 return;
2274 }
2275 ExprResult E = sharedGetConstructorDestructorAttrExpr(S, AL);
2276 if (E.isInvalid())
2277 return;
2278 S.Diag(Loc: D->getLocation(), DiagID: diag::warn_global_constructor)
2279 << D->getSourceRange();
2280 D->addAttr(A: ConstructorAttr::Create(Ctx&: S.Context, Priority: E.get(), CommonInfo: AL));
2281}
2282
2283static void handleDestructorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2284 ExprResult E = sharedGetConstructorDestructorAttrExpr(S, AL);
2285 if (E.isInvalid())
2286 return;
2287 S.Diag(Loc: D->getLocation(), DiagID: diag::warn_global_destructor) << D->getSourceRange();
2288 D->addAttr(A: DestructorAttr::Create(Ctx&: S.Context, Priority: E.get(), CommonInfo: AL));
2289}
2290
2291template <typename AttrTy>
2292static void handleAttrWithMessage(Sema &S, Decl *D, const ParsedAttr &AL) {
2293 // Handle the case where the attribute has a text message.
2294 StringRef Str;
2295 if (AL.getNumArgs() == 1 && !S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str))
2296 return;
2297
2298 D->addAttr(A: ::new (S.Context) AttrTy(S.Context, AL, Str));
2299}
2300
2301static bool checkAvailabilityAttr(Sema &S, SourceRange Range,
2302 const IdentifierInfo *Platform,
2303 VersionTuple Introduced,
2304 VersionTuple Deprecated,
2305 VersionTuple Obsoleted) {
2306 StringRef PlatformName
2307 = AvailabilityAttr::getPrettyPlatformName(Platform: Platform->getName());
2308 if (PlatformName.empty())
2309 PlatformName = Platform->getName();
2310
2311 // Ensure that Introduced <= Deprecated <= Obsoleted (although not all
2312 // of these steps are needed).
2313 if (!Introduced.empty() && !Deprecated.empty() &&
2314 !(Introduced <= Deprecated)) {
2315 S.Diag(Loc: Range.getBegin(), DiagID: diag::warn_availability_version_ordering)
2316 << 1 << PlatformName << Deprecated.getAsString()
2317 << 0 << Introduced.getAsString();
2318 return true;
2319 }
2320
2321 if (!Introduced.empty() && !Obsoleted.empty() &&
2322 !(Introduced <= Obsoleted)) {
2323 S.Diag(Loc: Range.getBegin(), DiagID: diag::warn_availability_version_ordering)
2324 << 2 << PlatformName << Obsoleted.getAsString()
2325 << 0 << Introduced.getAsString();
2326 return true;
2327 }
2328
2329 if (!Deprecated.empty() && !Obsoleted.empty() &&
2330 !(Deprecated <= Obsoleted)) {
2331 S.Diag(Loc: Range.getBegin(), DiagID: diag::warn_availability_version_ordering)
2332 << 2 << PlatformName << Obsoleted.getAsString()
2333 << 1 << Deprecated.getAsString();
2334 return true;
2335 }
2336
2337 return false;
2338}
2339
2340/// Check whether the two versions match.
2341///
2342/// If either version tuple is empty, then they are assumed to match. If
2343/// \p BeforeIsOkay is true, then \p X can be less than or equal to \p Y.
2344static bool versionsMatch(const VersionTuple &X, const VersionTuple &Y,
2345 bool BeforeIsOkay) {
2346 if (X.empty() || Y.empty())
2347 return true;
2348
2349 if (X == Y)
2350 return true;
2351
2352 if (BeforeIsOkay && X < Y)
2353 return true;
2354
2355 return false;
2356}
2357
2358AvailabilityAttr *Sema::mergeAvailabilityAttr(
2359 NamedDecl *D, const AttributeCommonInfo &CI, const IdentifierInfo *Platform,
2360 bool Implicit, VersionTuple Introduced, VersionTuple Deprecated,
2361 VersionTuple Obsoleted, bool IsUnavailable, StringRef Message,
2362 bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK,
2363 int Priority, const IdentifierInfo *Environment) {
2364 VersionTuple MergedIntroduced = Introduced;
2365 VersionTuple MergedDeprecated = Deprecated;
2366 VersionTuple MergedObsoleted = Obsoleted;
2367 bool FoundAny = false;
2368 bool OverrideOrImpl = false;
2369 switch (AMK) {
2370 case AvailabilityMergeKind::None:
2371 case AvailabilityMergeKind::Redeclaration:
2372 OverrideOrImpl = false;
2373 break;
2374
2375 case AvailabilityMergeKind::Override:
2376 case AvailabilityMergeKind::ProtocolImplementation:
2377 case AvailabilityMergeKind::OptionalProtocolImplementation:
2378 OverrideOrImpl = true;
2379 break;
2380 }
2381
2382 if (D->hasAttrs()) {
2383 AttrVec &Attrs = D->getAttrs();
2384 for (unsigned i = 0, e = Attrs.size(); i != e;) {
2385 const auto *OldAA = dyn_cast<AvailabilityAttr>(Val: Attrs[i]);
2386 if (!OldAA) {
2387 ++i;
2388 continue;
2389 }
2390
2391 const IdentifierInfo *OldPlatform = OldAA->getPlatform();
2392 if (OldPlatform != Platform) {
2393 ++i;
2394 continue;
2395 }
2396
2397 const IdentifierInfo *OldEnvironment = OldAA->getEnvironment();
2398 if (OldEnvironment != Environment) {
2399 ++i;
2400 continue;
2401 }
2402
2403 // If there is an existing availability attribute for this platform that
2404 // has a lower priority use the existing one and discard the new
2405 // attribute.
2406 if (OldAA->getPriority() < Priority)
2407 return nullptr;
2408
2409 // If there is an existing attribute for this platform that has a higher
2410 // priority than the new attribute then erase the old one and continue
2411 // processing the attributes.
2412 if (OldAA->getPriority() > Priority) {
2413 Attrs.erase(CI: Attrs.begin() + i);
2414 --e;
2415 continue;
2416 }
2417
2418 FoundAny = true;
2419 VersionTuple OldIntroduced = OldAA->getIntroduced();
2420 VersionTuple OldDeprecated = OldAA->getDeprecated();
2421 VersionTuple OldObsoleted = OldAA->getObsoleted();
2422 bool OldIsUnavailable = OldAA->getUnavailable();
2423
2424 if (!versionsMatch(X: OldIntroduced, Y: Introduced, BeforeIsOkay: OverrideOrImpl) ||
2425 !versionsMatch(X: Deprecated, Y: OldDeprecated, BeforeIsOkay: OverrideOrImpl) ||
2426 !versionsMatch(X: Obsoleted, Y: OldObsoleted, BeforeIsOkay: OverrideOrImpl) ||
2427 !(OldIsUnavailable == IsUnavailable ||
2428 (OverrideOrImpl && !OldIsUnavailable && IsUnavailable))) {
2429 if (OverrideOrImpl) {
2430 int Which = -1;
2431 VersionTuple FirstVersion;
2432 VersionTuple SecondVersion;
2433 if (!versionsMatch(X: OldIntroduced, Y: Introduced, BeforeIsOkay: OverrideOrImpl)) {
2434 Which = 0;
2435 FirstVersion = OldIntroduced;
2436 SecondVersion = Introduced;
2437 } else if (!versionsMatch(X: Deprecated, Y: OldDeprecated, BeforeIsOkay: OverrideOrImpl)) {
2438 Which = 1;
2439 FirstVersion = Deprecated;
2440 SecondVersion = OldDeprecated;
2441 } else if (!versionsMatch(X: Obsoleted, Y: OldObsoleted, BeforeIsOkay: OverrideOrImpl)) {
2442 Which = 2;
2443 FirstVersion = Obsoleted;
2444 SecondVersion = OldObsoleted;
2445 }
2446
2447 if (Which == -1) {
2448 Diag(Loc: OldAA->getLocation(),
2449 DiagID: diag::warn_mismatched_availability_override_unavail)
2450 << AvailabilityAttr::getPrettyPlatformName(Platform: Platform->getName())
2451 << (AMK == AvailabilityMergeKind::Override);
2452 } else if (Which != 1 && AMK == AvailabilityMergeKind::
2453 OptionalProtocolImplementation) {
2454 // Allow different 'introduced' / 'obsoleted' availability versions
2455 // on a method that implements an optional protocol requirement. It
2456 // makes less sense to allow this for 'deprecated' as the user can't
2457 // see if the method is 'deprecated' as 'respondsToSelector' will
2458 // still return true when the method is deprecated.
2459 ++i;
2460 continue;
2461 } else {
2462 Diag(Loc: OldAA->getLocation(),
2463 DiagID: diag::warn_mismatched_availability_override)
2464 << Which
2465 << AvailabilityAttr::getPrettyPlatformName(Platform: Platform->getName())
2466 << FirstVersion.getAsString() << SecondVersion.getAsString()
2467 << (AMK == AvailabilityMergeKind::Override);
2468 }
2469 if (AMK == AvailabilityMergeKind::Override)
2470 Diag(Loc: CI.getLoc(), DiagID: diag::note_overridden_method);
2471 else
2472 Diag(Loc: CI.getLoc(), DiagID: diag::note_protocol_method);
2473 } else {
2474 Diag(Loc: OldAA->getLocation(), DiagID: diag::warn_mismatched_availability);
2475 Diag(Loc: CI.getLoc(), DiagID: diag::note_previous_attribute);
2476 }
2477
2478 Attrs.erase(CI: Attrs.begin() + i);
2479 --e;
2480 continue;
2481 }
2482
2483 VersionTuple MergedIntroduced2 = MergedIntroduced;
2484 VersionTuple MergedDeprecated2 = MergedDeprecated;
2485 VersionTuple MergedObsoleted2 = MergedObsoleted;
2486
2487 if (MergedIntroduced2.empty())
2488 MergedIntroduced2 = OldIntroduced;
2489 if (MergedDeprecated2.empty())
2490 MergedDeprecated2 = OldDeprecated;
2491 if (MergedObsoleted2.empty())
2492 MergedObsoleted2 = OldObsoleted;
2493
2494 if (checkAvailabilityAttr(S&: *this, Range: OldAA->getRange(), Platform,
2495 Introduced: MergedIntroduced2, Deprecated: MergedDeprecated2,
2496 Obsoleted: MergedObsoleted2)) {
2497 Attrs.erase(CI: Attrs.begin() + i);
2498 --e;
2499 continue;
2500 }
2501
2502 MergedIntroduced = MergedIntroduced2;
2503 MergedDeprecated = MergedDeprecated2;
2504 MergedObsoleted = MergedObsoleted2;
2505 ++i;
2506 }
2507 }
2508
2509 if (FoundAny &&
2510 MergedIntroduced == Introduced &&
2511 MergedDeprecated == Deprecated &&
2512 MergedObsoleted == Obsoleted)
2513 return nullptr;
2514
2515 // Only create a new attribute if !OverrideOrImpl, but we want to do
2516 // the checking.
2517 if (!checkAvailabilityAttr(S&: *this, Range: CI.getRange(), Platform, Introduced: MergedIntroduced,
2518 Deprecated: MergedDeprecated, Obsoleted: MergedObsoleted) &&
2519 !OverrideOrImpl) {
2520 auto *Avail = ::new (Context) AvailabilityAttr(
2521 Context, CI, Platform, Introduced, Deprecated, Obsoleted, IsUnavailable,
2522 Message, IsStrict, Replacement, Priority, Environment);
2523 Avail->setImplicit(Implicit);
2524 return Avail;
2525 }
2526 return nullptr;
2527}
2528
2529/// Returns true if the given availability attribute should be inferred, and
2530/// adjusts the value of the attribute as necessary to facilitate that.
2531static bool shouldInferAvailabilityAttribute(const ParsedAttr &AL,
2532 IdentifierInfo *&II,
2533 bool &IsUnavailable,
2534 VersionTuple &Introduced,
2535 VersionTuple &Deprecated,
2536 VersionTuple &Obsolete, Sema &S) {
2537 const llvm::Triple &TT = S.Context.getTargetInfo().getTriple();
2538 const ASTContext &Context = S.Context;
2539 if (TT.getOS() != llvm::Triple::XROS)
2540 return false;
2541 IdentifierInfo *NewII = nullptr;
2542 if (II->getName() == "ios")
2543 NewII = &Context.Idents.get(Name: "xros");
2544 else if (II->getName() == "ios_app_extension")
2545 NewII = &Context.Idents.get(Name: "xros_app_extension");
2546 if (!NewII)
2547 return false;
2548 II = NewII;
2549
2550 auto MakeUnavailable = [&]() {
2551 IsUnavailable = true;
2552 // Reset introduced, deprecated, obsoleted.
2553 Introduced = VersionTuple();
2554 Deprecated = VersionTuple();
2555 Obsolete = VersionTuple();
2556 };
2557
2558 const DarwinSDKInfo *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking(
2559 Loc: AL.getRange().getBegin(), Platform: "ios");
2560
2561 if (!SDKInfo) {
2562 MakeUnavailable();
2563 return true;
2564 }
2565 // Map from the fallback platform availability to the current platform
2566 // availability.
2567 const auto *Mapping = SDKInfo->getVersionMapping(Kind: DarwinSDKInfo::OSEnvPair(
2568 llvm::Triple::IOS, llvm::Triple::UnknownEnvironment, llvm::Triple::XROS,
2569 llvm::Triple::UnknownEnvironment));
2570 if (!Mapping) {
2571 MakeUnavailable();
2572 return true;
2573 }
2574
2575 if (!Introduced.empty()) {
2576 auto NewIntroduced = Mapping->mapIntroducedAvailabilityVersion(Key: Introduced);
2577 if (!NewIntroduced) {
2578 MakeUnavailable();
2579 return true;
2580 }
2581 Introduced = *NewIntroduced;
2582 }
2583
2584 if (!Obsolete.empty()) {
2585 auto NewObsolete =
2586 Mapping->mapDeprecatedObsoletedAvailabilityVersion(Key: Obsolete);
2587 if (!NewObsolete) {
2588 MakeUnavailable();
2589 return true;
2590 }
2591 Obsolete = *NewObsolete;
2592 }
2593
2594 if (!Deprecated.empty()) {
2595 auto NewDeprecated =
2596 Mapping->mapDeprecatedObsoletedAvailabilityVersion(Key: Deprecated);
2597 Deprecated = NewDeprecated ? *NewDeprecated : VersionTuple();
2598 }
2599
2600 return true;
2601}
2602
2603static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
2604 if (isa<UsingDecl, UnresolvedUsingTypenameDecl, UnresolvedUsingValueDecl>(
2605 Val: D)) {
2606 S.Diag(Loc: AL.getRange().getBegin(), DiagID: diag::warn_deprecated_ignored_on_using)
2607 << AL;
2608 return;
2609 }
2610
2611 if (!AL.checkExactlyNumArgs(S, Num: 1))
2612 return;
2613 IdentifierLoc *Platform = AL.getArgAsIdent(Arg: 0);
2614
2615 IdentifierInfo *II = Platform->getIdentifierInfo();
2616 StringRef PrettyName = AvailabilityAttr::getPrettyPlatformName(Platform: II->getName());
2617 if (PrettyName.empty())
2618 S.Diag(Loc: Platform->getLoc(), DiagID: diag::warn_availability_unknown_platform)
2619 << Platform->getIdentifierInfo();
2620
2621 auto *ND = dyn_cast<NamedDecl>(Val: D);
2622 if (!ND) // We warned about this already, so just return.
2623 return;
2624
2625 AvailabilityChange Introduced = AL.getAvailabilityIntroduced();
2626 AvailabilityChange Deprecated = AL.getAvailabilityDeprecated();
2627 AvailabilityChange Obsoleted = AL.getAvailabilityObsoleted();
2628
2629 const llvm::Triple::OSType PlatformOS = AvailabilityAttr::getOSType(
2630 Platform: AvailabilityAttr::canonicalizePlatformName(Platform: II->getName()));
2631
2632 auto reportAndUpdateIfInvalidOS = [&](auto &InputVersion) -> void {
2633 const bool IsInValidRange =
2634 llvm::Triple::isValidVersionForOS(OSKind: PlatformOS, Version: InputVersion);
2635 // Canonicalize availability versions.
2636 auto CanonicalVersion = llvm::Triple::getCanonicalVersionForOS(
2637 OSKind: PlatformOS, Version: InputVersion, IsInValidRange);
2638 if (!IsInValidRange) {
2639 S.Diag(Loc: Platform->getLoc(), DiagID: diag::warn_availability_invalid_os_version)
2640 << InputVersion.getAsString() << PrettyName;
2641 S.Diag(Loc: Platform->getLoc(),
2642 DiagID: diag::note_availability_invalid_os_version_adjusted)
2643 << CanonicalVersion.getAsString();
2644 }
2645 InputVersion = CanonicalVersion;
2646 };
2647
2648 if (PlatformOS != llvm::Triple::OSType::UnknownOS) {
2649 reportAndUpdateIfInvalidOS(Introduced.Version);
2650 reportAndUpdateIfInvalidOS(Deprecated.Version);
2651 reportAndUpdateIfInvalidOS(Obsoleted.Version);
2652 }
2653
2654 bool IsUnavailable = AL.getUnavailableLoc().isValid();
2655 bool IsStrict = AL.getStrictLoc().isValid();
2656 StringRef Str;
2657 if (const auto *SE = dyn_cast_if_present<StringLiteral>(Val: AL.getMessageExpr()))
2658 Str = SE->getString();
2659 StringRef Replacement;
2660 if (const auto *SE =
2661 dyn_cast_if_present<StringLiteral>(Val: AL.getReplacementExpr()))
2662 Replacement = SE->getString();
2663
2664 if (II->isStr(Str: "swift")) {
2665 if (Introduced.isValid() || Obsoleted.isValid() ||
2666 (!IsUnavailable && !Deprecated.isValid())) {
2667 S.Diag(Loc: AL.getLoc(),
2668 DiagID: diag::warn_availability_swift_unavailable_deprecated_only);
2669 return;
2670 }
2671 }
2672
2673 if (II->isStr(Str: "fuchsia")) {
2674 std::optional<unsigned> Min, Sub;
2675 if ((Min = Introduced.Version.getMinor()) ||
2676 (Sub = Introduced.Version.getSubminor())) {
2677 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_availability_fuchsia_unavailable_minor);
2678 return;
2679 }
2680 }
2681
2682 if (S.getLangOpts().HLSL && IsStrict)
2683 S.Diag(Loc: AL.getStrictLoc(), DiagID: diag::err_availability_unexpected_parameter)
2684 << "strict" << /* HLSL */ 0;
2685
2686 int PriorityModifier = AL.isPragmaClangAttribute()
2687 ? Sema::AP_PragmaClangAttribute
2688 : Sema::AP_Explicit;
2689
2690 const IdentifierLoc *EnvironmentLoc = AL.getEnvironment();
2691 IdentifierInfo *IIEnvironment = nullptr;
2692 if (EnvironmentLoc) {
2693 if (S.getLangOpts().HLSL) {
2694 IIEnvironment = EnvironmentLoc->getIdentifierInfo();
2695 if (AvailabilityAttr::getEnvironmentType(
2696 Environment: EnvironmentLoc->getIdentifierInfo()->getName()) ==
2697 llvm::Triple::EnvironmentType::UnknownEnvironment)
2698 S.Diag(Loc: EnvironmentLoc->getLoc(),
2699 DiagID: diag::warn_availability_unknown_environment)
2700 << EnvironmentLoc->getIdentifierInfo();
2701 } else {
2702 S.Diag(Loc: EnvironmentLoc->getLoc(),
2703 DiagID: diag::err_availability_unexpected_parameter)
2704 << "environment" << /* C/C++ */ 1;
2705 }
2706 }
2707
2708 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2709 D: ND, CI: AL, Platform: II, Implicit: false /*Implicit*/, Introduced: Introduced.Version, Deprecated: Deprecated.Version,
2710 Obsoleted: Obsoleted.Version, IsUnavailable, Message: Str, IsStrict, Replacement,
2711 AMK: AvailabilityMergeKind::None, Priority: PriorityModifier, Environment: IIEnvironment);
2712 if (NewAttr)
2713 D->addAttr(A: NewAttr);
2714
2715 if (S.Context.getTargetInfo().getTriple().getOS() == llvm::Triple::XROS) {
2716 IdentifierInfo *NewII = II;
2717 bool NewIsUnavailable = IsUnavailable;
2718 VersionTuple NewIntroduced = Introduced.Version;
2719 VersionTuple NewDeprecated = Deprecated.Version;
2720 VersionTuple NewObsoleted = Obsoleted.Version;
2721 if (shouldInferAvailabilityAttribute(AL, II&: NewII, IsUnavailable&: NewIsUnavailable,
2722 Introduced&: NewIntroduced, Deprecated&: NewDeprecated,
2723 Obsolete&: NewObsoleted, S)) {
2724 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2725 D: ND, CI: AL, Platform: NewII, Implicit: true /*Implicit*/, Introduced: NewIntroduced, Deprecated: NewDeprecated,
2726 Obsoleted: NewObsoleted, IsUnavailable: NewIsUnavailable, Message: Str, IsStrict, Replacement,
2727 AMK: AvailabilityMergeKind::None,
2728 Priority: PriorityModifier + Sema::AP_InferredFromOtherPlatform, Environment: IIEnvironment);
2729 if (NewAttr)
2730 D->addAttr(A: NewAttr);
2731 }
2732 }
2733
2734 // Transcribe "ios" to "watchos" (and add a new attribute) if the versioning
2735 // matches before the start of the watchOS platform.
2736 if (S.Context.getTargetInfo().getTriple().isWatchOS()) {
2737 IdentifierInfo *NewII = nullptr;
2738 if (II->getName() == "ios")
2739 NewII = &S.Context.Idents.get(Name: "watchos");
2740 else if (II->getName() == "ios_app_extension")
2741 NewII = &S.Context.Idents.get(Name: "watchos_app_extension");
2742
2743 if (NewII) {
2744 const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
2745 const auto *IOSToWatchOSMapping =
2746 SDKInfo ? SDKInfo->getVersionMapping(
2747 Kind: DarwinSDKInfo::OSEnvPair::iOStoWatchOSPair())
2748 : nullptr;
2749
2750 auto adjustWatchOSVersion =
2751 [IOSToWatchOSMapping](VersionTuple Version) -> VersionTuple {
2752 if (Version.empty())
2753 return Version;
2754 auto MinimumWatchOSVersion = VersionTuple(2, 0);
2755
2756 if (IOSToWatchOSMapping) {
2757 if (auto MappedVersion = IOSToWatchOSMapping->map(
2758 Key: Version, MinimumValue: MinimumWatchOSVersion, MaximumValue: std::nullopt)) {
2759 return *MappedVersion;
2760 }
2761 }
2762
2763 auto Major = Version.getMajor();
2764 auto NewMajor = Major;
2765 if (Major < 9)
2766 NewMajor = 0;
2767 else if (Major < 12)
2768 NewMajor = Major - 7;
2769 if (NewMajor >= 2) {
2770 if (Version.getMinor()) {
2771 if (Version.getSubminor())
2772 return VersionTuple(NewMajor, *Version.getMinor(),
2773 *Version.getSubminor());
2774 else
2775 return VersionTuple(NewMajor, *Version.getMinor());
2776 }
2777 return VersionTuple(NewMajor);
2778 }
2779
2780 return MinimumWatchOSVersion;
2781 };
2782
2783 auto NewIntroduced = adjustWatchOSVersion(Introduced.Version);
2784 auto NewDeprecated = adjustWatchOSVersion(Deprecated.Version);
2785 auto NewObsoleted = adjustWatchOSVersion(Obsoleted.Version);
2786
2787 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2788 D: ND, CI: AL, Platform: NewII, Implicit: true /*Implicit*/, Introduced: NewIntroduced, Deprecated: NewDeprecated,
2789 Obsoleted: NewObsoleted, IsUnavailable, Message: Str, IsStrict, Replacement,
2790 AMK: AvailabilityMergeKind::None,
2791 Priority: PriorityModifier + Sema::AP_InferredFromOtherPlatform, Environment: IIEnvironment);
2792 if (NewAttr)
2793 D->addAttr(A: NewAttr);
2794 }
2795 } else if (S.Context.getTargetInfo().getTriple().isTvOS()) {
2796 // Transcribe "ios" to "tvos" (and add a new attribute) if the versioning
2797 // matches before the start of the tvOS platform.
2798 IdentifierInfo *NewII = nullptr;
2799 if (II->getName() == "ios")
2800 NewII = &S.Context.Idents.get(Name: "tvos");
2801 else if (II->getName() == "ios_app_extension")
2802 NewII = &S.Context.Idents.get(Name: "tvos_app_extension");
2803
2804 if (NewII) {
2805 const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking();
2806 const auto *IOSToTvOSMapping =
2807 SDKInfo ? SDKInfo->getVersionMapping(
2808 Kind: DarwinSDKInfo::OSEnvPair::iOStoTvOSPair())
2809 : nullptr;
2810
2811 auto AdjustTvOSVersion =
2812 [IOSToTvOSMapping](VersionTuple Version) -> VersionTuple {
2813 if (Version.empty())
2814 return Version;
2815
2816 if (IOSToTvOSMapping) {
2817 if (auto MappedVersion = IOSToTvOSMapping->map(
2818 Key: Version, MinimumValue: VersionTuple(0, 0), MaximumValue: std::nullopt)) {
2819 return *MappedVersion;
2820 }
2821 }
2822 return Version;
2823 };
2824
2825 auto NewIntroduced = AdjustTvOSVersion(Introduced.Version);
2826 auto NewDeprecated = AdjustTvOSVersion(Deprecated.Version);
2827 auto NewObsoleted = AdjustTvOSVersion(Obsoleted.Version);
2828
2829 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2830 D: ND, CI: AL, Platform: NewII, Implicit: true /*Implicit*/, Introduced: NewIntroduced, Deprecated: NewDeprecated,
2831 Obsoleted: NewObsoleted, IsUnavailable, Message: Str, IsStrict, Replacement,
2832 AMK: AvailabilityMergeKind::None,
2833 Priority: PriorityModifier + Sema::AP_InferredFromOtherPlatform, Environment: IIEnvironment);
2834 if (NewAttr)
2835 D->addAttr(A: NewAttr);
2836 }
2837 } else if (S.Context.getTargetInfo().getTriple().getOS() ==
2838 llvm::Triple::IOS &&
2839 S.Context.getTargetInfo().getTriple().isMacCatalystEnvironment()) {
2840 auto GetSDKInfo = [&]() {
2841 return S.getDarwinSDKInfoForAvailabilityChecking(Loc: AL.getRange().getBegin(),
2842 Platform: "macOS");
2843 };
2844
2845 // Transcribe "ios" to "maccatalyst" (and add a new attribute).
2846 IdentifierInfo *NewII = nullptr;
2847 if (II->getName() == "ios")
2848 NewII = &S.Context.Idents.get(Name: "maccatalyst");
2849 else if (II->getName() == "ios_app_extension")
2850 NewII = &S.Context.Idents.get(Name: "maccatalyst_app_extension");
2851 if (NewII) {
2852 auto MinMacCatalystVersion = [](const VersionTuple &V) {
2853 if (V.empty())
2854 return V;
2855 if (V.getMajor() < 13 ||
2856 (V.getMajor() == 13 && V.getMinor() && *V.getMinor() < 1))
2857 return VersionTuple(13, 1); // The min Mac Catalyst version is 13.1.
2858 return V;
2859 };
2860 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2861 D: ND, CI: AL, Platform: NewII, Implicit: true /*Implicit*/,
2862 Introduced: MinMacCatalystVersion(Introduced.Version),
2863 Deprecated: MinMacCatalystVersion(Deprecated.Version),
2864 Obsoleted: MinMacCatalystVersion(Obsoleted.Version), IsUnavailable, Message: Str,
2865 IsStrict, Replacement, AMK: AvailabilityMergeKind::None,
2866 Priority: PriorityModifier + Sema::AP_InferredFromOtherPlatform, Environment: IIEnvironment);
2867 if (NewAttr)
2868 D->addAttr(A: NewAttr);
2869 } else if (II->getName() == "macos" && GetSDKInfo() &&
2870 (!Introduced.Version.empty() || !Deprecated.Version.empty() ||
2871 !Obsoleted.Version.empty())) {
2872 if (const auto *MacOStoMacCatalystMapping =
2873 GetSDKInfo()->getVersionMapping(
2874 Kind: DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
2875 // Infer Mac Catalyst availability from the macOS availability attribute
2876 // if it has versioned availability. Don't infer 'unavailable'. This
2877 // inferred availability has lower priority than the other availability
2878 // attributes that are inferred from 'ios'.
2879 NewII = &S.Context.Idents.get(Name: "maccatalyst");
2880 auto RemapMacOSVersion =
2881 [&](const VersionTuple &V) -> std::optional<VersionTuple> {
2882 if (V.empty())
2883 return std::nullopt;
2884 // API_TO_BE_DEPRECATED is 100000.
2885 if (V.getMajor() == 100000)
2886 return VersionTuple(100000);
2887 // The minimum iosmac version is 13.1
2888 return MacOStoMacCatalystMapping->map(Key: V, MinimumValue: VersionTuple(13, 1),
2889 MaximumValue: std::nullopt);
2890 };
2891 std::optional<VersionTuple> NewIntroduced =
2892 RemapMacOSVersion(Introduced.Version),
2893 NewDeprecated =
2894 RemapMacOSVersion(Deprecated.Version),
2895 NewObsoleted =
2896 RemapMacOSVersion(Obsoleted.Version);
2897 if (NewIntroduced || NewDeprecated || NewObsoleted) {
2898 auto VersionOrEmptyVersion =
2899 [](const std::optional<VersionTuple> &V) -> VersionTuple {
2900 return V ? *V : VersionTuple();
2901 };
2902 AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
2903 D: ND, CI: AL, Platform: NewII, Implicit: true /*Implicit*/,
2904 Introduced: VersionOrEmptyVersion(NewIntroduced),
2905 Deprecated: VersionOrEmptyVersion(NewDeprecated),
2906 Obsoleted: VersionOrEmptyVersion(NewObsoleted), /*IsUnavailable=*/false, Message: Str,
2907 IsStrict, Replacement, AMK: AvailabilityMergeKind::None,
2908 Priority: PriorityModifier + Sema::AP_InferredFromOtherPlatform +
2909 Sema::AP_InferredFromOtherPlatform,
2910 Environment: IIEnvironment);
2911 if (NewAttr)
2912 D->addAttr(A: NewAttr);
2913 }
2914 }
2915 }
2916 }
2917}
2918
2919static void handleExternalSourceSymbolAttr(Sema &S, Decl *D,
2920 const ParsedAttr &AL) {
2921 if (!AL.checkAtLeastNumArgs(S, Num: 1) || !AL.checkAtMostNumArgs(S, Num: 4))
2922 return;
2923
2924 StringRef Language;
2925 if (const auto *SE = dyn_cast_if_present<StringLiteral>(Val: AL.getArgAsExpr(Arg: 0)))
2926 Language = SE->getString();
2927 StringRef DefinedIn;
2928 if (const auto *SE = dyn_cast_if_present<StringLiteral>(Val: AL.getArgAsExpr(Arg: 1)))
2929 DefinedIn = SE->getString();
2930 bool IsGeneratedDeclaration = AL.getArgAsIdent(Arg: 2) != nullptr;
2931 StringRef USR;
2932 if (const auto *SE = dyn_cast_if_present<StringLiteral>(Val: AL.getArgAsExpr(Arg: 3)))
2933 USR = SE->getString();
2934
2935 D->addAttr(A: ::new (S.Context) ExternalSourceSymbolAttr(
2936 S.Context, AL, Language, DefinedIn, IsGeneratedDeclaration, USR));
2937}
2938
2939void Sema::mergeVisibilityType(Decl *D, SourceLocation Loc,
2940 VisibilityAttr::VisibilityType Value) {
2941 if (VisibilityAttr *Attr = D->getAttr<VisibilityAttr>()) {
2942 if (Attr->getVisibility() != Value)
2943 Diag(Loc, DiagID: diag::err_mismatched_visibility);
2944 } else
2945 D->addAttr(A: VisibilityAttr::CreateImplicit(Ctx&: Context, Visibility: Value));
2946}
2947
2948template <class T>
2949static T *mergeVisibilityAttr(Sema &S, Decl *D, const AttributeCommonInfo &CI,
2950 typename T::VisibilityType value) {
2951 T *existingAttr = D->getAttr<T>();
2952 if (existingAttr) {
2953 typename T::VisibilityType existingValue = existingAttr->getVisibility();
2954 if (existingValue == value)
2955 return nullptr;
2956 S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
2957 S.Diag(Loc: CI.getLoc(), DiagID: diag::note_previous_attribute);
2958 D->dropAttr<T>();
2959 }
2960 return ::new (S.Context) T(S.Context, CI, value);
2961}
2962
2963VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D,
2964 const AttributeCommonInfo &CI,
2965 VisibilityAttr::VisibilityType Vis) {
2966 return ::mergeVisibilityAttr<VisibilityAttr>(S&: *this, D, CI, value: Vis);
2967}
2968
2969TypeVisibilityAttr *
2970Sema::mergeTypeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI,
2971 TypeVisibilityAttr::VisibilityType Vis) {
2972 return ::mergeVisibilityAttr<TypeVisibilityAttr>(S&: *this, D, CI, value: Vis);
2973}
2974
2975static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL,
2976 bool isTypeVisibility) {
2977 // Visibility attributes don't mean anything on a typedef.
2978 if (isa<TypedefNameDecl>(Val: D)) {
2979 S.Diag(Loc: AL.getRange().getBegin(), DiagID: diag::warn_attribute_ignored) << AL;
2980 return;
2981 }
2982
2983 // 'type_visibility' can only go on a type or namespace.
2984 if (isTypeVisibility && !(isa<TagDecl>(Val: D) || isa<ObjCInterfaceDecl>(Val: D) ||
2985 isa<NamespaceDecl>(Val: D))) {
2986 S.Diag(Loc: AL.getRange().getBegin(), DiagID: diag::err_attribute_wrong_decl_type)
2987 << AL << AL.isRegularKeywordAttribute() << ExpectedTypeOrNamespace;
2988 return;
2989 }
2990
2991 // Check that the argument is a string literal.
2992 StringRef TypeStr;
2993 SourceLocation LiteralLoc;
2994 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: TypeStr, ArgLocation: &LiteralLoc))
2995 return;
2996
2997 VisibilityAttr::VisibilityType type;
2998 if (!VisibilityAttr::ConvertStrToVisibilityType(Val: TypeStr, Out&: type)) {
2999 S.Diag(Loc: LiteralLoc, DiagID: diag::warn_attribute_type_not_supported) << AL
3000 << TypeStr;
3001 return;
3002 }
3003
3004 // Complain about attempts to use protected visibility on targets
3005 // (like Darwin) that don't support it.
3006 if (type == VisibilityAttr::Protected &&
3007 !S.Context.getTargetInfo().hasProtectedVisibility()) {
3008 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_protected_visibility);
3009 type = VisibilityAttr::Default;
3010 }
3011
3012 Attr *newAttr;
3013 if (isTypeVisibility) {
3014 newAttr = S.mergeTypeVisibilityAttr(
3015 D, CI: AL, Vis: (TypeVisibilityAttr::VisibilityType)type);
3016 } else {
3017 newAttr = S.mergeVisibilityAttr(D, CI: AL, Vis: type);
3018 }
3019 if (newAttr)
3020 D->addAttr(A: newAttr);
3021}
3022
3023static void handleSentinelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3024 unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel;
3025 if (AL.getNumArgs() > 0) {
3026 Expr *E = AL.getArgAsExpr(Arg: 0);
3027 std::optional<llvm::APSInt> Idx = llvm::APSInt(32);
3028 if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(Ctx: S.Context))) {
3029 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
3030 << AL << 1 << AANT_ArgumentIntegerConstant << E->getSourceRange();
3031 return;
3032 }
3033
3034 if (Idx->isSigned() && Idx->isNegative()) {
3035 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_sentinel_less_than_zero)
3036 << E->getSourceRange();
3037 return;
3038 }
3039
3040 sentinel = Idx->getZExtValue();
3041 }
3042
3043 unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos;
3044 if (AL.getNumArgs() > 1) {
3045 Expr *E = AL.getArgAsExpr(Arg: 1);
3046 std::optional<llvm::APSInt> Idx = llvm::APSInt(32);
3047 if (E->isTypeDependent() || !(Idx = E->getIntegerConstantExpr(Ctx: S.Context))) {
3048 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
3049 << AL << 2 << AANT_ArgumentIntegerConstant << E->getSourceRange();
3050 return;
3051 }
3052 nullPos = Idx->getZExtValue();
3053
3054 if ((Idx->isSigned() && Idx->isNegative()) || nullPos > 1) {
3055 // FIXME: This error message could be improved, it would be nice
3056 // to say what the bounds actually are.
3057 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_sentinel_not_zero_or_one)
3058 << E->getSourceRange();
3059 return;
3060 }
3061 }
3062
3063 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
3064 const FunctionType *FT = FD->getType()->castAs<FunctionType>();
3065 if (isa<FunctionNoProtoType>(Val: FT)) {
3066 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_sentinel_named_arguments);
3067 return;
3068 }
3069
3070 if (!cast<FunctionProtoType>(Val: FT)->isVariadic()) {
3071 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_sentinel_not_variadic) << 0;
3072 return;
3073 }
3074 } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(Val: D)) {
3075 if (!MD->isVariadic()) {
3076 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_sentinel_not_variadic) << 0;
3077 return;
3078 }
3079 } else if (const auto *BD = dyn_cast<BlockDecl>(Val: D)) {
3080 if (!BD->isVariadic()) {
3081 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_sentinel_not_variadic) << 1;
3082 return;
3083 }
3084 } else if (const auto *V = dyn_cast<VarDecl>(Val: D)) {
3085 QualType Ty = V->getType();
3086 if (Ty->isBlockPointerType() || Ty->isFunctionPointerType()) {
3087 const FunctionType *FT = Ty->isFunctionPointerType()
3088 ? D->getFunctionType()
3089 : Ty->castAs<BlockPointerType>()
3090 ->getPointeeType()
3091 ->castAs<FunctionType>();
3092 if (isa<FunctionNoProtoType>(Val: FT)) {
3093 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_sentinel_named_arguments);
3094 return;
3095 }
3096 if (!cast<FunctionProtoType>(Val: FT)->isVariadic()) {
3097 int m = Ty->isFunctionPointerType() ? 0 : 1;
3098 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_sentinel_not_variadic) << m;
3099 return;
3100 }
3101 } else {
3102 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_wrong_decl_type)
3103 << AL << AL.isRegularKeywordAttribute()
3104 << ExpectedFunctionMethodOrBlock;
3105 return;
3106 }
3107 } else {
3108 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_wrong_decl_type)
3109 << AL << AL.isRegularKeywordAttribute()
3110 << ExpectedFunctionMethodOrBlock;
3111 return;
3112 }
3113 D->addAttr(A: ::new (S.Context) SentinelAttr(S.Context, AL, sentinel, nullPos));
3114}
3115
3116static void handleWarnUnusedResult(Sema &S, Decl *D, const ParsedAttr &AL) {
3117 if (D->getFunctionType() &&
3118 D->getFunctionType()->getReturnType()->isVoidType() &&
3119 !isa<CXXConstructorDecl>(Val: D)) {
3120 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_void_function_method) << AL << 0;
3121 return;
3122 }
3123 if (const auto *MD = dyn_cast<ObjCMethodDecl>(Val: D))
3124 if (MD->getReturnType()->isVoidType()) {
3125 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_void_function_method) << AL << 1;
3126 return;
3127 }
3128
3129 StringRef Str;
3130 if (AL.isStandardAttributeSyntax()) {
3131 // If this is spelled [[clang::warn_unused_result]] we look for an optional
3132 // string literal. This is not gated behind any specific version of the
3133 // standard.
3134 if (AL.isClangScope()) {
3135 if (AL.getNumArgs() == 1 &&
3136 !S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: nullptr))
3137 return;
3138 } else if (!AL.getScopeName()) {
3139 // The standard attribute cannot be applied to variable declarations such
3140 // as a function pointer.
3141 if (isa<VarDecl>(Val: D))
3142 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_wrong_decl_type)
3143 << AL << AL.isRegularKeywordAttribute()
3144 << ExpectedFunctionOrClassOrEnum;
3145
3146 // If this is spelled as the standard C++17 attribute, but not in C++17,
3147 // warn about using it as an extension. If there are attribute arguments,
3148 // then claim it's a C++20 extension instead. C23 supports this attribute
3149 // with the message; no extension warning is needed there beyond the one
3150 // already issued for accepting attributes in older modes.
3151 const LangOptions &LO = S.getLangOpts();
3152 if (AL.getNumArgs() == 1) {
3153 if (LO.CPlusPlus && !LO.CPlusPlus20)
3154 S.Diag(Loc: AL.getLoc(), DiagID: diag::ext_cxx20_attr) << AL;
3155
3156 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: nullptr))
3157 return;
3158 } else if (LO.CPlusPlus && !LO.CPlusPlus17)
3159 S.Diag(Loc: AL.getLoc(), DiagID: diag::ext_cxx17_attr) << AL;
3160 }
3161 }
3162
3163 if ((!AL.isGNUAttribute() &&
3164 !(AL.isStandardAttributeSyntax() && AL.isClangScope())) &&
3165 isa<TypedefNameDecl>(Val: D)) {
3166 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_unused_result_typedef_unsupported_spelling)
3167 << AL.isGNUScope();
3168 return;
3169 }
3170
3171 D->addAttr(A: ::new (S.Context) WarnUnusedResultAttr(S.Context, AL, Str));
3172}
3173
3174static void handleWeakImportAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3175 // weak_import only applies to variable & function declarations.
3176 bool isDef = false;
3177 if (!D->canBeWeakImported(IsDefinition&: isDef)) {
3178 if (isDef)
3179 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_invalid_on_definition)
3180 << "weak_import";
3181 else if (isa<ObjCPropertyDecl>(Val: D) || isa<ObjCMethodDecl>(Val: D) ||
3182 (S.Context.getTargetInfo().getTriple().isOSDarwin() &&
3183 (isa<ObjCInterfaceDecl>(Val: D) || isa<EnumDecl>(Val: D)))) {
3184 // Nothing to warn about here.
3185 } else
3186 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_wrong_decl_type)
3187 << AL << AL.isRegularKeywordAttribute() << ExpectedVariableOrFunction;
3188
3189 return;
3190 }
3191
3192 D->addAttr(A: ::new (S.Context) WeakImportAttr(S.Context, AL));
3193}
3194
3195// Checks whether an argument of launch_bounds-like attribute is
3196// acceptable, performs implicit conversion to Rvalue, and returns
3197// non-nullptr Expr result on success. Otherwise, it returns nullptr
3198// and may output an error.
3199template <class Attribute>
3200static Expr *makeAttributeArgExpr(Sema &S, Expr *E, const Attribute &Attr,
3201 const unsigned Idx) {
3202 if (S.DiagnoseUnexpandedParameterPack(E))
3203 return nullptr;
3204
3205 // Accept template arguments for now as they depend on something else.
3206 // We'll get to check them when they eventually get instantiated.
3207 if (E->isValueDependent())
3208 return E;
3209
3210 std::optional<llvm::APSInt> I = llvm::APSInt(64);
3211 if (!(I = E->getIntegerConstantExpr(Ctx: S.Context))) {
3212 S.Diag(Loc: E->getExprLoc(), DiagID: diag::err_attribute_argument_n_type)
3213 << &Attr << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
3214 return nullptr;
3215 }
3216 // Make sure we can fit it in 32 bits.
3217 if (!I->isIntN(N: 32)) {
3218 S.Diag(Loc: E->getExprLoc(), DiagID: diag::err_ice_too_large)
3219 << toString(I: *I, Radix: 10, Signed: false) << 32 << /* Unsigned */ 1;
3220 return nullptr;
3221 }
3222 if (*I < 0)
3223 S.Diag(Loc: E->getExprLoc(), DiagID: diag::err_attribute_requires_positive_integer)
3224 << &Attr << /*non-negative*/ 1 << E->getSourceRange();
3225
3226 // We may need to perform implicit conversion of the argument.
3227 InitializedEntity Entity = InitializedEntity::InitializeParameter(
3228 Context&: S.Context, Type: S.Context.getConstType(T: S.Context.IntTy), /*consume*/ Consumed: false);
3229 ExprResult ValArg = S.PerformCopyInitialization(Entity, EqualLoc: SourceLocation(), Init: E);
3230 assert(!ValArg.isInvalid() &&
3231 "Unexpected PerformCopyInitialization() failure.");
3232
3233 return ValArg.getAs<Expr>();
3234}
3235
3236// Handles reqd_work_group_size and work_group_size_hint.
3237template <typename WorkGroupAttr>
3238static void handleWorkGroupSize(Sema &S, Decl *D, const ParsedAttr &AL) {
3239 Expr *WGSize[3];
3240 for (unsigned i = 0; i < 3; ++i) {
3241 if (Expr *E = makeAttributeArgExpr(S, E: AL.getArgAsExpr(Arg: i), Attr: AL, Idx: i))
3242 WGSize[i] = E;
3243 else
3244 return;
3245 }
3246
3247 auto IsZero = [&](Expr *E) {
3248 if (E->isValueDependent())
3249 return false;
3250 std::optional<llvm::APSInt> I = E->getIntegerConstantExpr(Ctx: S.Context);
3251 assert(I && "Non-integer constant expr");
3252 return I->isZero();
3253 };
3254
3255 if (!llvm::all_of(WGSize, IsZero)) {
3256 for (unsigned i = 0; i < 3; ++i) {
3257 const Expr *E = AL.getArgAsExpr(Arg: i);
3258 if (IsZero(WGSize[i])) {
3259 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_is_zero)
3260 << AL << E->getSourceRange();
3261 return;
3262 }
3263 }
3264 }
3265
3266 auto Equal = [&](Expr *LHS, Expr *RHS) {
3267 if (LHS->isValueDependent() || RHS->isValueDependent())
3268 return true;
3269 std::optional<llvm::APSInt> L = LHS->getIntegerConstantExpr(Ctx: S.Context);
3270 assert(L && "Non-integer constant expr");
3271 std::optional<llvm::APSInt> R = RHS->getIntegerConstantExpr(Ctx: S.Context);
3272 assert(L && "Non-integer constant expr");
3273 return L == R;
3274 };
3275
3276 WorkGroupAttr *Existing = D->getAttr<WorkGroupAttr>();
3277 if (Existing &&
3278 !llvm::equal(std::initializer_list<Expr *>{Existing->getXDim(),
3279 Existing->getYDim(),
3280 Existing->getZDim()},
3281 WGSize, Equal))
3282 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_duplicate_attribute) << AL;
3283
3284 D->addAttr(A: ::new (S.Context)
3285 WorkGroupAttr(S.Context, AL, WGSize[0], WGSize[1], WGSize[2]));
3286}
3287
3288static void handleVecTypeHint(Sema &S, Decl *D, const ParsedAttr &AL) {
3289 if (!AL.hasParsedType()) {
3290 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_wrong_number_arguments) << AL << 1;
3291 return;
3292 }
3293
3294 TypeSourceInfo *ParmTSI = nullptr;
3295 QualType ParmType = S.GetTypeFromParser(Ty: AL.getTypeArg(), TInfo: &ParmTSI);
3296 assert(ParmTSI && "no type source info for attribute argument");
3297
3298 if (!ParmType->isExtVectorType() && !ParmType->isFloatingType() &&
3299 (ParmType->isBooleanType() ||
3300 !ParmType->isIntegralType(Ctx: S.getASTContext()))) {
3301 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_invalid_argument) << 2 << AL;
3302 return;
3303 }
3304
3305 if (VecTypeHintAttr *A = D->getAttr<VecTypeHintAttr>()) {
3306 if (!S.Context.hasSameType(T1: A->getTypeHint(), T2: ParmType)) {
3307 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_duplicate_attribute) << AL;
3308 return;
3309 }
3310 }
3311
3312 D->addAttr(A: ::new (S.Context) VecTypeHintAttr(S.Context, AL, ParmTSI));
3313}
3314
3315SectionAttr *Sema::mergeSectionAttr(Decl *D, const AttributeCommonInfo &CI,
3316 StringRef Name) {
3317 // Explicit or partial specializations do not inherit
3318 // the section attribute from the primary template.
3319 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
3320 if (CI.getAttributeSpellingListIndex() == SectionAttr::Declspec_allocate &&
3321 FD->isFunctionTemplateSpecialization())
3322 return nullptr;
3323 }
3324 if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
3325 if (ExistingAttr->getName() == Name)
3326 return nullptr;
3327 Diag(Loc: ExistingAttr->getLocation(), DiagID: diag::warn_mismatched_section)
3328 << 1 /*section*/;
3329 Diag(Loc: CI.getLoc(), DiagID: diag::note_previous_attribute);
3330 return nullptr;
3331 }
3332 return ::new (Context) SectionAttr(Context, CI, Name);
3333}
3334
3335llvm::Error Sema::isValidSectionSpecifier(StringRef SecName) {
3336 if (!Context.getTargetInfo().getTriple().isOSDarwin())
3337 return llvm::Error::success();
3338
3339 // Let MCSectionMachO validate this.
3340 StringRef Segment, Section;
3341 unsigned TAA, StubSize;
3342 bool HasTAA;
3343 return llvm::MCSectionMachO::ParseSectionSpecifier(Spec: SecName, Segment, Section,
3344 TAA, TAAParsed&: HasTAA, StubSize);
3345}
3346
3347bool Sema::checkSectionName(SourceLocation LiteralLoc, StringRef SecName) {
3348 if (llvm::Error E = isValidSectionSpecifier(SecName)) {
3349 Diag(Loc: LiteralLoc, DiagID: diag::err_attribute_section_invalid_for_target)
3350 << toString(E: std::move(E)) << 1 /*'section'*/;
3351 return false;
3352 }
3353 return true;
3354}
3355
3356static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3357 // Make sure that there is a string literal as the sections's single
3358 // argument.
3359 StringRef Str;
3360 SourceLocation LiteralLoc;
3361 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &LiteralLoc))
3362 return;
3363
3364 if (!S.checkSectionName(LiteralLoc, SecName: Str))
3365 return;
3366
3367 SectionAttr *NewAttr = S.mergeSectionAttr(D, CI: AL, Name: Str);
3368 if (NewAttr) {
3369 D->addAttr(A: NewAttr);
3370 if (isa<FunctionDecl, FunctionTemplateDecl, ObjCMethodDecl,
3371 ObjCPropertyDecl>(Val: D))
3372 S.UnifySection(SectionName: NewAttr->getName(),
3373 SectionFlags: ASTContext::PSF_Execute | ASTContext::PSF_Read,
3374 TheDecl: cast<NamedDecl>(Val: D));
3375 }
3376}
3377
3378static bool isValidCodeModelAttr(llvm::Triple &Triple, StringRef Str) {
3379 if (Triple.isLoongArch()) {
3380 return Str == "normal" || Str == "medium" || Str == "extreme";
3381 } else {
3382 assert(Triple.getArch() == llvm::Triple::x86_64 &&
3383 "only loongarch/x86-64 supported");
3384 return Str == "small" || Str == "large";
3385 }
3386}
3387
3388static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3389 StringRef Str;
3390 SourceLocation LiteralLoc;
3391 auto IsTripleSupported = [](llvm::Triple &Triple) {
3392 return Triple.getArch() == llvm::Triple::ArchType::x86_64 ||
3393 Triple.isLoongArch();
3394 };
3395
3396 // Check that it is a string.
3397 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &LiteralLoc))
3398 return;
3399
3400 SmallVector<llvm::Triple, 2> Triples = {
3401 S.Context.getTargetInfo().getTriple()};
3402 if (auto *aux = S.Context.getAuxTargetInfo()) {
3403 Triples.push_back(Elt: aux->getTriple());
3404 } else if (S.Context.getTargetInfo().getTriple().isNVPTX() ||
3405 S.Context.getTargetInfo().getTriple().isAMDGPU() ||
3406 S.Context.getTargetInfo().getTriple().isSPIRV()) {
3407 // Ignore the attribute for pure GPU device compiles since it only applies
3408 // to host globals.
3409 return;
3410 }
3411
3412 auto SupportedTripleIt = llvm::find_if(Range&: Triples, P: IsTripleSupported);
3413 if (SupportedTripleIt == Triples.end()) {
3414 S.Diag(Loc: LiteralLoc, DiagID: diag::warn_unknown_attribute_ignored) << AL;
3415 return;
3416 }
3417
3418 llvm::CodeModel::Model CM;
3419 if (!CodeModelAttr::ConvertStrToModel(Val: Str, Out&: CM) ||
3420 !isValidCodeModelAttr(Triple&: *SupportedTripleIt, Str)) {
3421 S.Diag(Loc: LiteralLoc, DiagID: diag::err_attr_codemodel_arg) << Str;
3422 return;
3423 }
3424
3425 D->addAttr(A: ::new (S.Context) CodeModelAttr(S.Context, AL, CM));
3426}
3427
3428// This is used for `__declspec(code_seg("segname"))` on a decl.
3429// `#pragma code_seg("segname")` uses checkSectionName() instead.
3430static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc,
3431 StringRef CodeSegName) {
3432 if (llvm::Error E = S.isValidSectionSpecifier(SecName: CodeSegName)) {
3433 S.Diag(Loc: LiteralLoc, DiagID: diag::err_attribute_section_invalid_for_target)
3434 << toString(E: std::move(E)) << 0 /*'code-seg'*/;
3435 return false;
3436 }
3437
3438 return true;
3439}
3440
3441CodeSegAttr *Sema::mergeCodeSegAttr(Decl *D, const AttributeCommonInfo &CI,
3442 StringRef Name) {
3443 // Explicit or partial specializations do not inherit
3444 // the code_seg attribute from the primary template.
3445 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
3446 if (FD->isFunctionTemplateSpecialization())
3447 return nullptr;
3448 }
3449 if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3450 if (ExistingAttr->getName() == Name)
3451 return nullptr;
3452 Diag(Loc: ExistingAttr->getLocation(), DiagID: diag::warn_mismatched_section)
3453 << 0 /*codeseg*/;
3454 Diag(Loc: CI.getLoc(), DiagID: diag::note_previous_attribute);
3455 return nullptr;
3456 }
3457 return ::new (Context) CodeSegAttr(Context, CI, Name);
3458}
3459
3460static void handleCodeSegAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3461 StringRef Str;
3462 SourceLocation LiteralLoc;
3463 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &LiteralLoc))
3464 return;
3465 if (!checkCodeSegName(S, LiteralLoc, CodeSegName: Str))
3466 return;
3467 if (const auto *ExistingAttr = D->getAttr<CodeSegAttr>()) {
3468 if (!ExistingAttr->isImplicit()) {
3469 S.Diag(Loc: AL.getLoc(),
3470 DiagID: ExistingAttr->getName() == Str
3471 ? diag::warn_duplicate_codeseg_attribute
3472 : diag::err_conflicting_codeseg_attribute);
3473 return;
3474 }
3475 D->dropAttr<CodeSegAttr>();
3476 }
3477 if (CodeSegAttr *CSA = S.mergeCodeSegAttr(D, CI: AL, Name: Str))
3478 D->addAttr(A: CSA);
3479}
3480
3481bool Sema::checkTargetAttr(SourceLocation LiteralLoc, StringRef AttrStr) {
3482 using namespace DiagAttrParams;
3483
3484 if (AttrStr.contains(Other: "fpmath="))
3485 return Diag(Loc: LiteralLoc, DiagID: diag::warn_unsupported_target_attribute)
3486 << Unsupported << None << "fpmath=" << Target;
3487
3488 // Diagnose use of tune if target doesn't support it.
3489 if (!Context.getTargetInfo().supportsTargetAttributeTune() &&
3490 AttrStr.contains(Other: "tune="))
3491 return Diag(Loc: LiteralLoc, DiagID: diag::warn_unsupported_target_attribute)
3492 << Unsupported << None << "tune=" << Target;
3493
3494 ParsedTargetAttr ParsedAttrs =
3495 Context.getTargetInfo().parseTargetAttr(Str: AttrStr);
3496
3497 if (!ParsedAttrs.CPU.empty() &&
3498 !Context.getTargetInfo().isValidCPUName(Name: ParsedAttrs.CPU))
3499 return Diag(Loc: LiteralLoc, DiagID: diag::warn_unsupported_target_attribute)
3500 << Unknown << CPU << ParsedAttrs.CPU << Target;
3501
3502 if (!ParsedAttrs.Tune.empty() &&
3503 !Context.getTargetInfo().isValidCPUName(Name: ParsedAttrs.Tune))
3504 return Diag(Loc: LiteralLoc, DiagID: diag::warn_unsupported_target_attribute)
3505 << Unknown << Tune << ParsedAttrs.Tune << Target;
3506
3507 if (Context.getTargetInfo().getTriple().isRISCV()) {
3508 if (ParsedAttrs.Duplicate != "")
3509 return Diag(Loc: LiteralLoc, DiagID: diag::err_duplicate_target_attribute)
3510 << Duplicate << None << ParsedAttrs.Duplicate << Target;
3511 for (StringRef CurFeature : ParsedAttrs.Features) {
3512 if (!CurFeature.starts_with(Prefix: '+') && !CurFeature.starts_with(Prefix: '-'))
3513 return Diag(Loc: LiteralLoc, DiagID: diag::warn_unsupported_target_attribute)
3514 << Unsupported << None << AttrStr << Target;
3515 }
3516 }
3517
3518 if (Context.getTargetInfo().getTriple().isLoongArch()) {
3519 for (StringRef CurFeature : ParsedAttrs.Features) {
3520 if (CurFeature.starts_with(Prefix: "!arch=")) {
3521 StringRef ArchValue = CurFeature.split(Separator: "=").second.trim();
3522 return Diag(Loc: LiteralLoc, DiagID: diag::err_attribute_unsupported)
3523 << "target(arch=..)" << ArchValue;
3524 }
3525 }
3526 }
3527
3528 if (ParsedAttrs.Duplicate != "")
3529 return Diag(Loc: LiteralLoc, DiagID: diag::warn_unsupported_target_attribute)
3530 << Duplicate << None << ParsedAttrs.Duplicate << Target;
3531
3532 for (const auto &Feature : ParsedAttrs.Features) {
3533 auto CurFeature = StringRef(Feature).drop_front(); // remove + or -.
3534 if (!Context.getTargetInfo().isValidFeatureName(Feature: CurFeature))
3535 return Diag(Loc: LiteralLoc, DiagID: diag::warn_unsupported_target_attribute)
3536 << Unsupported << None << CurFeature << Target;
3537 }
3538
3539 TargetInfo::BranchProtectionInfo BPI{};
3540 StringRef DiagMsg;
3541 if (ParsedAttrs.BranchProtection.empty())
3542 return false;
3543 if (!Context.getTargetInfo().validateBranchProtection(
3544 Spec: ParsedAttrs.BranchProtection, Arch: ParsedAttrs.CPU, BPI,
3545 LO: Context.getLangOpts(), Err&: DiagMsg)) {
3546 if (DiagMsg.empty())
3547 return Diag(Loc: LiteralLoc, DiagID: diag::warn_unsupported_target_attribute)
3548 << Unsupported << None << "branch-protection" << Target;
3549 return Diag(Loc: LiteralLoc, DiagID: diag::err_invalid_branch_protection_spec)
3550 << DiagMsg;
3551 }
3552 if (!DiagMsg.empty())
3553 Diag(Loc: LiteralLoc, DiagID: diag::warn_unsupported_branch_protection_spec) << DiagMsg;
3554
3555 return false;
3556}
3557
3558static void handleTargetVersionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3559 StringRef Param;
3560 SourceLocation Loc;
3561 SmallString<64> NewParam;
3562 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: Param, ArgLocation: &Loc))
3563 return;
3564
3565 if (S.Context.getTargetInfo().getTriple().isAArch64()) {
3566 if (S.ARM().checkTargetVersionAttr(Param, Loc, NewParam))
3567 return;
3568 } else if (S.Context.getTargetInfo().getTriple().isRISCV()) {
3569 if (S.RISCV().checkTargetVersionAttr(Param, Loc, NewParam))
3570 return;
3571 }
3572
3573 TargetVersionAttr *NewAttr =
3574 ::new (S.Context) TargetVersionAttr(S.Context, AL, NewParam);
3575 D->addAttr(A: NewAttr);
3576}
3577
3578static void handleTargetAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3579 StringRef Str;
3580 SourceLocation LiteralLoc;
3581 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str, ArgLocation: &LiteralLoc) ||
3582 S.checkTargetAttr(LiteralLoc, AttrStr: Str))
3583 return;
3584
3585 TargetAttr *NewAttr = ::new (S.Context) TargetAttr(S.Context, AL, Str);
3586 D->addAttr(A: NewAttr);
3587}
3588
3589static void handleTargetClonesAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3590 // Ensure we don't combine these with themselves, since that causes some
3591 // confusing behavior.
3592 if (const auto *Other = D->getAttr<TargetClonesAttr>()) {
3593 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_disallowed_duplicate_attribute) << AL;
3594 S.Diag(Loc: Other->getLocation(), DiagID: diag::note_conflicting_attribute);
3595 return;
3596 }
3597 if (checkAttrMutualExclusion<TargetClonesAttr>(S, D, AL))
3598 return;
3599
3600 // FIXME: We could probably figure out how to get this to work for lambdas
3601 // someday.
3602 if (const auto *MD = dyn_cast<CXXMethodDecl>(Val: D)) {
3603 if (MD->getParent()->isLambda()) {
3604 S.Diag(Loc: D->getLocation(), DiagID: diag::err_multiversion_doesnt_support)
3605 << static_cast<unsigned>(MultiVersionKind::TargetClones)
3606 << /*Lambda*/ 9;
3607 return;
3608 }
3609 }
3610
3611 SmallVector<StringRef, 2> Params;
3612 SmallVector<SourceLocation, 2> Locations;
3613 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
3614 StringRef Param;
3615 SourceLocation Loc;
3616 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: Param, ArgLocation: &Loc))
3617 return;
3618 Params.push_back(Elt: Param);
3619 Locations.push_back(Elt: Loc);
3620 }
3621
3622 SmallVector<SmallString<64>, 2> NewParams;
3623 if (S.Context.getTargetInfo().getTriple().isAArch64()) {
3624 if (S.ARM().checkTargetClonesAttr(Params, Locs&: Locations, NewParams))
3625 return;
3626 } else if (S.Context.getTargetInfo().getTriple().isRISCV()) {
3627 if (S.RISCV().checkTargetClonesAttr(Params, Locs: Locations, NewParams,
3628 AttrLoc: AL.getLoc()))
3629 return;
3630 } else if (S.Context.getTargetInfo().getTriple().isX86()) {
3631 if (S.X86().checkTargetClonesAttr(Params, Locs: Locations, NewParams,
3632 AttrLoc: AL.getLoc()))
3633 return;
3634 }
3635 Params.clear();
3636 for (auto &SmallStr : NewParams)
3637 Params.push_back(Elt: SmallStr.str());
3638
3639 TargetClonesAttr *NewAttr = ::new (S.Context)
3640 TargetClonesAttr(S.Context, AL, Params.data(), Params.size());
3641 D->addAttr(A: NewAttr);
3642}
3643
3644static void handleMinVectorWidthAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3645 Expr *E = AL.getArgAsExpr(Arg: 0);
3646 uint32_t VecWidth;
3647 if (!S.checkUInt32Argument(AI: AL, Expr: E, Val&: VecWidth)) {
3648 AL.setInvalid();
3649 return;
3650 }
3651
3652 MinVectorWidthAttr *Existing = D->getAttr<MinVectorWidthAttr>();
3653 if (Existing && Existing->getVectorWidth() != VecWidth) {
3654 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_duplicate_attribute) << AL;
3655 return;
3656 }
3657
3658 D->addAttr(A: ::new (S.Context) MinVectorWidthAttr(S.Context, AL, VecWidth));
3659}
3660
3661static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3662 Expr *E = AL.getArgAsExpr(Arg: 0);
3663 SourceLocation Loc = E->getExprLoc();
3664 FunctionDecl *FD = nullptr;
3665 DeclarationNameInfo NI;
3666
3667 // gcc only allows for simple identifiers. Since we support more than gcc, we
3668 // will warn the user.
3669 if (auto *DRE = dyn_cast<DeclRefExpr>(Val: E)) {
3670 if (DRE->hasQualifier())
3671 S.Diag(Loc, DiagID: diag::warn_cleanup_ext);
3672 FD = dyn_cast<FunctionDecl>(Val: DRE->getDecl());
3673 NI = DRE->getNameInfo();
3674 if (!FD) {
3675 S.Diag(Loc, DiagID: diag::err_attribute_cleanup_arg_not_function) << 1
3676 << NI.getName();
3677 return;
3678 }
3679 } else if (auto *ULE = dyn_cast<UnresolvedLookupExpr>(Val: E)) {
3680 if (ULE->hasExplicitTemplateArgs())
3681 S.Diag(Loc, DiagID: diag::warn_cleanup_ext);
3682 FD = S.ResolveSingleFunctionTemplateSpecialization(ovl: ULE, Complain: true);
3683 NI = ULE->getNameInfo();
3684 if (!FD) {
3685 S.Diag(Loc, DiagID: diag::err_attribute_cleanup_arg_not_function) << 2
3686 << NI.getName();
3687 if (ULE->getType() == S.Context.OverloadTy)
3688 S.NoteAllOverloadCandidates(E: ULE);
3689 return;
3690 }
3691 } else {
3692 S.Diag(Loc, DiagID: diag::err_attribute_cleanup_arg_not_function) << 0;
3693 return;
3694 }
3695
3696 if (FD->getNumParams() != 1) {
3697 S.Diag(Loc, DiagID: diag::err_attribute_cleanup_func_must_take_one_arg)
3698 << NI.getName();
3699 return;
3700 }
3701
3702 VarDecl *VD = cast<VarDecl>(Val: D);
3703 // Create a reference to the variable declaration. This is a fake/dummy
3704 // reference.
3705 DeclRefExpr *VariableReference = DeclRefExpr::Create(
3706 Context: S.Context, QualifierLoc: NestedNameSpecifierLoc{}, TemplateKWLoc: FD->getLocation(), D: VD, RefersToEnclosingVariableOrCapture: false,
3707 NameInfo: DeclarationNameInfo{VD->getDeclName(), VD->getLocation()}, T: VD->getType(),
3708 VK: VK_LValue);
3709
3710 // Create a unary operator expression that represents taking the address of
3711 // the variable. This is a fake/dummy expression.
3712 Expr *AddressOfVariable = UnaryOperator::Create(
3713 C: S.Context, input: VariableReference, opc: UnaryOperatorKind::UO_AddrOf,
3714 type: S.Context.getPointerType(T: VD->getType()), VK: VK_PRValue, OK: OK_Ordinary, l: Loc,
3715 CanOverflow: +false, FPFeatures: FPOptionsOverride{});
3716
3717 // Create a function call expression. This is a fake/dummy call expression.
3718 CallExpr *FunctionCallExpression =
3719 CallExpr::Create(Ctx: S.Context, Fn: E, Args: ArrayRef{AddressOfVariable},
3720 Ty: S.Context.VoidTy, VK: VK_PRValue, RParenLoc: Loc, FPFeatures: FPOptionsOverride{});
3721
3722 if (S.CheckFunctionCall(FDecl: FD, TheCall: FunctionCallExpression,
3723 Proto: FD->getType()->getAs<FunctionProtoType>())) {
3724 return;
3725 }
3726
3727 auto *attr = ::new (S.Context) CleanupAttr(S.Context, AL, FD);
3728 attr->setArgLoc(E->getExprLoc());
3729 D->addAttr(A: attr);
3730}
3731
3732static void handleEnumExtensibilityAttr(Sema &S, Decl *D,
3733 const ParsedAttr &AL) {
3734 if (!AL.isArgIdent(Arg: 0)) {
3735 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
3736 << AL << 0 << AANT_ArgumentIdentifier;
3737 return;
3738 }
3739
3740 EnumExtensibilityAttr::Kind ExtensibilityKind;
3741 IdentifierInfo *II = AL.getArgAsIdent(Arg: 0)->getIdentifierInfo();
3742 if (!EnumExtensibilityAttr::ConvertStrToKind(Val: II->getName(),
3743 Out&: ExtensibilityKind)) {
3744 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_type_not_supported) << AL << II;
3745 return;
3746 }
3747
3748 D->addAttr(A: ::new (S.Context)
3749 EnumExtensibilityAttr(S.Context, AL, ExtensibilityKind));
3750}
3751
3752/// Handle __attribute__((format_arg((idx)))) attribute based on
3753/// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
3754static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3755 const Expr *IdxExpr = AL.getArgAsExpr(Arg: 0);
3756 ParamIdx Idx;
3757 if (!S.checkFunctionOrMethodParameterIndex(D, AI: AL, AttrArgNum: 1, IdxExpr, Idx))
3758 return;
3759
3760 // Make sure the format string is really a string.
3761 QualType Ty = getFunctionOrMethodParamType(D, Idx: Idx.getASTIndex());
3762
3763 bool NotNSStringTy = !S.ObjC().isNSStringType(T: Ty);
3764 if (NotNSStringTy && !S.ObjC().isCFStringType(T: Ty) &&
3765 (!Ty->isPointerType() ||
3766 !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
3767 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_format_attribute_not)
3768 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, Idx: 0);
3769 return;
3770 }
3771 Ty = getFunctionOrMethodResultType(D);
3772 // replace instancetype with the class type
3773 auto *Instancetype = cast<TypedefType>(Val: S.Context.getTypedefType(
3774 Keyword: ElaboratedTypeKeyword::None, /*Qualifier=*/std::nullopt,
3775 Decl: S.Context.getObjCInstanceTypeDecl()));
3776 if (Ty->getAs<TypedefType>() == Instancetype)
3777 if (auto *OMD = dyn_cast<ObjCMethodDecl>(Val: D))
3778 if (auto *Interface = OMD->getClassInterface())
3779 Ty = S.Context.getObjCObjectPointerType(
3780 OIT: QualType(Interface->getTypeForDecl(), 0));
3781 if (!S.ObjC().isNSStringType(T: Ty, /*AllowNSAttributedString=*/true) &&
3782 !S.ObjC().isCFStringType(T: Ty) &&
3783 (!Ty->isPointerType() ||
3784 !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
3785 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_format_attribute_result_not)
3786 << (NotNSStringTy ? "string type" : "NSString")
3787 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, Idx: 0);
3788 return;
3789 }
3790
3791 D->addAttr(A: ::new (S.Context) FormatArgAttr(S.Context, AL, Idx));
3792}
3793
3794enum FormatAttrKind {
3795 CFStringFormat,
3796 NSStringFormat,
3797 StrftimeFormat,
3798 SupportedFormat,
3799 IgnoredFormat,
3800 InvalidFormat
3801};
3802
3803/// getFormatAttrKind - Map from format attribute names to supported format
3804/// types.
3805static FormatAttrKind getFormatAttrKind(StringRef Format) {
3806 return llvm::StringSwitch<FormatAttrKind>(Format)
3807 // Check for formats that get handled specially.
3808 .Case(S: "NSString", Value: NSStringFormat)
3809 .Case(S: "CFString", Value: CFStringFormat)
3810 .Cases(CaseStrings: {"gnu_strftime", "strftime"}, Value: StrftimeFormat)
3811
3812 // Otherwise, check for supported formats.
3813 .Cases(CaseStrings: {"gnu_scanf", "scanf", "gnu_printf", "printf", "printf0",
3814 "gnu_strfmon", "strfmon"},
3815 Value: SupportedFormat)
3816 .Cases(CaseStrings: {"cmn_err", "vcmn_err", "zcmn_err"}, Value: SupportedFormat)
3817 .Cases(CaseStrings: {"kprintf", "syslog"}, Value: SupportedFormat) // OpenBSD.
3818 .Case(S: "freebsd_kprintf", Value: SupportedFormat) // FreeBSD.
3819 .Case(S: "os_trace", Value: SupportedFormat)
3820 .Case(S: "os_log", Value: SupportedFormat)
3821
3822 .Cases(CaseStrings: {"gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag"},
3823 Value: IgnoredFormat)
3824 .Default(Value: InvalidFormat);
3825}
3826
3827/// Handle __attribute__((init_priority(priority))) attributes based on
3828/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
3829static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3830 if (!S.getLangOpts().CPlusPlus) {
3831 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_ignored) << AL;
3832 return;
3833 }
3834
3835 if (S.getLangOpts().HLSL) {
3836 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_hlsl_init_priority_unsupported);
3837 return;
3838 }
3839
3840 if (S.getCurFunctionOrMethodDecl()) {
3841 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_init_priority_object_attr);
3842 AL.setInvalid();
3843 return;
3844 }
3845
3846 Expr *E = AL.getArgAsExpr(Arg: 0);
3847 uint32_t prioritynum;
3848 if (!S.checkUInt32Argument(AI: AL, Expr: E, Val&: prioritynum)) {
3849 AL.setInvalid();
3850 return;
3851 }
3852
3853 if (prioritynum > 65535) {
3854 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_out_of_range)
3855 << E->getSourceRange() << AL << 0 << 65535;
3856 AL.setInvalid();
3857 return;
3858 }
3859
3860 // Values <= 100 are reserved for the implementation, and libc++
3861 // benefits from being able to specify values in that range.
3862 if (prioritynum < 101)
3863 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_init_priority_reserved)
3864 << E->getSourceRange() << prioritynum;
3865 D->addAttr(A: ::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
3866}
3867
3868ErrorAttr *Sema::mergeErrorAttr(Decl *D, const AttributeCommonInfo &CI,
3869 StringRef NewUserDiagnostic) {
3870 if (const auto *EA = D->getAttr<ErrorAttr>()) {
3871 std::string NewAttr = CI.getNormalizedFullName();
3872 assert((NewAttr == "error" || NewAttr == "warning") &&
3873 "unexpected normalized full name");
3874 bool Match = (EA->isError() && NewAttr == "error") ||
3875 (EA->isWarning() && NewAttr == "warning");
3876 if (!Match) {
3877 Diag(Loc: EA->getLocation(), DiagID: diag::err_attributes_are_not_compatible)
3878 << CI << EA
3879 << (CI.isRegularKeywordAttribute() ||
3880 EA->isRegularKeywordAttribute());
3881 Diag(Loc: CI.getLoc(), DiagID: diag::note_conflicting_attribute);
3882 return nullptr;
3883 }
3884 if (EA->getUserDiagnostic() != NewUserDiagnostic) {
3885 Diag(Loc: CI.getLoc(), DiagID: diag::warn_duplicate_attribute) << EA;
3886 Diag(Loc: EA->getLoc(), DiagID: diag::note_previous_attribute);
3887 }
3888 D->dropAttr<ErrorAttr>();
3889 }
3890 return ::new (Context) ErrorAttr(Context, CI, NewUserDiagnostic);
3891}
3892
3893FormatAttr *Sema::mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI,
3894 const IdentifierInfo *Format, int FormatIdx,
3895 int FirstArg) {
3896 // Check whether we already have an equivalent format attribute.
3897 for (auto *F : D->specific_attrs<FormatAttr>()) {
3898 if (F->getType() == Format &&
3899 F->getFormatIdx() == FormatIdx &&
3900 F->getFirstArg() == FirstArg) {
3901 // If we don't have a valid location for this attribute, adopt the
3902 // location.
3903 if (F->getLocation().isInvalid())
3904 F->setRange(CI.getRange());
3905 return nullptr;
3906 }
3907 }
3908
3909 return ::new (Context) FormatAttr(Context, CI, Format, FormatIdx, FirstArg);
3910}
3911
3912FormatMatchesAttr *Sema::mergeFormatMatchesAttr(Decl *D,
3913 const AttributeCommonInfo &CI,
3914 const IdentifierInfo *Format,
3915 int FormatIdx,
3916 StringLiteral *FormatStr) {
3917 // Check whether we already have an equivalent FormatMatches attribute.
3918 for (auto *F : D->specific_attrs<FormatMatchesAttr>()) {
3919 if (F->getType() == Format && F->getFormatIdx() == FormatIdx) {
3920 if (!CheckFormatStringsCompatible(FST: GetFormatStringType(FormatFlavor: Format->getName()),
3921 AuthoritativeFormatString: F->getFormatString(), TestedFormatString: FormatStr))
3922 return nullptr;
3923
3924 // If we don't have a valid location for this attribute, adopt the
3925 // location.
3926 if (F->getLocation().isInvalid())
3927 F->setRange(CI.getRange());
3928 return nullptr;
3929 }
3930 }
3931
3932 return ::new (Context)
3933 FormatMatchesAttr(Context, CI, Format, FormatIdx, FormatStr);
3934}
3935
3936struct FormatAttrCommon {
3937 FormatAttrKind Kind;
3938 IdentifierInfo *Identifier;
3939 unsigned NumArgs;
3940 unsigned FormatStringIdx;
3941};
3942
3943/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
3944/// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
3945static bool handleFormatAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
3946 FormatAttrCommon *Info) {
3947 // Checks the first two arguments of the attribute; this is shared between
3948 // Format and FormatMatches attributes.
3949
3950 if (!AL.isArgIdent(Arg: 0)) {
3951 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
3952 << AL << 1 << AANT_ArgumentIdentifier;
3953 return false;
3954 }
3955
3956 // In C++ the implicit 'this' function parameter also counts, and they are
3957 // counted from one.
3958 bool HasImplicitThisParam = hasImplicitObjectParameter(D);
3959 Info->NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam;
3960
3961 Info->Identifier = AL.getArgAsIdent(Arg: 0)->getIdentifierInfo();
3962 StringRef Format = Info->Identifier->getName();
3963
3964 if (normalizeName(AttrName&: Format)) {
3965 // If we've modified the string name, we need a new identifier for it.
3966 Info->Identifier = &S.Context.Idents.get(Name: Format);
3967 }
3968
3969 // Check for supported formats.
3970 Info->Kind = getFormatAttrKind(Format);
3971
3972 if (Info->Kind == IgnoredFormat)
3973 return false;
3974
3975 if (Info->Kind == InvalidFormat) {
3976 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_type_not_supported)
3977 << AL << Info->Identifier->getName();
3978 return false;
3979 }
3980
3981 // checks for the 2nd argument
3982 Expr *IdxExpr = AL.getArgAsExpr(Arg: 1);
3983 if (!S.checkUInt32Argument(AI: AL, Expr: IdxExpr, Val&: Info->FormatStringIdx, Idx: 2))
3984 return false;
3985
3986 if (Info->FormatStringIdx < 1 || Info->FormatStringIdx > Info->NumArgs) {
3987 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_out_of_bounds)
3988 << AL << 2 << IdxExpr->getSourceRange();
3989 return false;
3990 }
3991
3992 // FIXME: Do we need to bounds check?
3993 unsigned ArgIdx = Info->FormatStringIdx - 1;
3994
3995 if (HasImplicitThisParam) {
3996 if (ArgIdx == 0) {
3997 S.Diag(Loc: AL.getLoc(),
3998 DiagID: diag::err_format_attribute_implicit_this_format_string)
3999 << IdxExpr->getSourceRange();
4000 return false;
4001 }
4002 ArgIdx--;
4003 }
4004
4005 // make sure the format string is really a string
4006 QualType Ty = getFunctionOrMethodParamType(D, Idx: ArgIdx);
4007
4008 if (!S.ObjC().isNSStringType(T: Ty, AllowNSAttributedString: true) && !S.ObjC().isCFStringType(T: Ty) &&
4009 (!Ty->isPointerType() ||
4010 !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
4011 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_format_attribute_not)
4012 << IdxExpr->getSourceRange()
4013 << getFunctionOrMethodParamRange(D, Idx: ArgIdx);
4014 return false;
4015 }
4016
4017 return true;
4018}
4019
4020static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4021 FormatAttrCommon Info;
4022 if (!handleFormatAttrCommon(S, D, AL, Info: &Info))
4023 return;
4024
4025 // check the 3rd argument
4026 Expr *FirstArgExpr = AL.getArgAsExpr(Arg: 2);
4027 uint32_t FirstArg;
4028 if (!S.checkUInt32Argument(AI: AL, Expr: FirstArgExpr, Val&: FirstArg, Idx: 3))
4029 return;
4030
4031 // FirstArg == 0 is is always valid.
4032 if (FirstArg != 0) {
4033 if (Info.Kind == StrftimeFormat) {
4034 // If the kind is strftime, FirstArg must be 0 because strftime does not
4035 // use any variadic arguments.
4036 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_format_strftime_third_parameter)
4037 << FirstArgExpr->getSourceRange()
4038 << FixItHint::CreateReplacement(RemoveRange: FirstArgExpr->getSourceRange(), Code: "0");
4039 return;
4040 } else if (isFunctionOrMethodVariadic(D)) {
4041 // Else, if the function is variadic, then FirstArg must be 0 or the
4042 // "position" of the ... parameter. It's unusual to use 0 with variadic
4043 // functions, so the fixit proposes the latter.
4044 if (FirstArg != Info.NumArgs + 1) {
4045 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_out_of_bounds)
4046 << AL << 3 << FirstArgExpr->getSourceRange()
4047 << FixItHint::CreateReplacement(RemoveRange: FirstArgExpr->getSourceRange(),
4048 Code: std::to_string(val: Info.NumArgs + 1));
4049 return;
4050 }
4051 } else {
4052 // Inescapable GCC compatibility diagnostic.
4053 S.Diag(Loc: D->getLocation(), DiagID: diag::warn_gcc_requires_variadic_function) << AL;
4054 if (FirstArg <= Info.FormatStringIdx) {
4055 // Else, the function is not variadic, and FirstArg must be 0 or any
4056 // parameter after the format parameter. We don't offer a fixit because
4057 // there are too many possible good values.
4058 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_out_of_bounds)
4059 << AL << 3 << FirstArgExpr->getSourceRange();
4060 return;
4061 }
4062 }
4063 }
4064
4065 FormatAttr *NewAttr =
4066 S.mergeFormatAttr(D, CI: AL, Format: Info.Identifier, FormatIdx: Info.FormatStringIdx, FirstArg);
4067 if (NewAttr)
4068 D->addAttr(A: NewAttr);
4069}
4070
4071static void handleFormatMatchesAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4072 FormatAttrCommon Info;
4073 if (!handleFormatAttrCommon(S, D, AL, Info: &Info))
4074 return;
4075
4076 Expr *FormatStrExpr = AL.getArgAsExpr(Arg: 2)->IgnoreParenImpCasts();
4077 if (auto *SL = dyn_cast<StringLiteral>(Val: FormatStrExpr)) {
4078 FormatStringType FST = S.GetFormatStringType(FormatFlavor: Info.Identifier->getName());
4079 if (S.ValidateFormatString(FST, Str: SL))
4080 if (auto *NewAttr = S.mergeFormatMatchesAttr(D, CI: AL, Format: Info.Identifier,
4081 FormatIdx: Info.FormatStringIdx, FormatStr: SL))
4082 D->addAttr(A: NewAttr);
4083 return;
4084 }
4085
4086 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_format_nonliteral)
4087 << FormatStrExpr->getSourceRange();
4088}
4089
4090/// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
4091static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4092 // The index that identifies the callback callee is mandatory.
4093 if (AL.getNumArgs() == 0) {
4094 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_attribute_no_callee)
4095 << AL.getRange();
4096 return;
4097 }
4098
4099 bool HasImplicitThisParam = hasImplicitObjectParameter(D);
4100 int32_t NumArgs = getFunctionOrMethodNumParams(D);
4101
4102 FunctionDecl *FD = D->getAsFunction();
4103 assert(FD && "Expected a function declaration!");
4104
4105 llvm::StringMap<int> NameIdxMapping;
4106 NameIdxMapping["__"] = -1;
4107
4108 NameIdxMapping["this"] = 0;
4109
4110 int Idx = 1;
4111 for (const ParmVarDecl *PVD : FD->parameters())
4112 NameIdxMapping[PVD->getName()] = Idx++;
4113
4114 auto UnknownName = NameIdxMapping.end();
4115
4116 SmallVector<int, 8> EncodingIndices;
4117 for (unsigned I = 0, E = AL.getNumArgs(); I < E; ++I) {
4118 SourceRange SR;
4119 int32_t ArgIdx;
4120
4121 if (AL.isArgIdent(Arg: I)) {
4122 IdentifierLoc *IdLoc = AL.getArgAsIdent(Arg: I);
4123 auto It = NameIdxMapping.find(Key: IdLoc->getIdentifierInfo()->getName());
4124 if (It == UnknownName) {
4125 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_attribute_argument_unknown)
4126 << IdLoc->getIdentifierInfo() << IdLoc->getLoc();
4127 return;
4128 }
4129
4130 SR = SourceRange(IdLoc->getLoc());
4131 ArgIdx = It->second;
4132 } else if (AL.isArgExpr(Arg: I)) {
4133 Expr *IdxExpr = AL.getArgAsExpr(Arg: I);
4134
4135 // If the expression is not parseable as an int32_t we have a problem.
4136 if (!S.checkUInt32Argument(AI: AL, Expr: IdxExpr, Val&: (uint32_t &)ArgIdx, Idx: I + 1,
4137 StrictlyUnsigned: false)) {
4138 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_out_of_bounds)
4139 << AL << (I + 1) << IdxExpr->getSourceRange();
4140 return;
4141 }
4142
4143 // Check oob, excluding the special values, 0 and -1.
4144 if (ArgIdx < -1 || ArgIdx > NumArgs) {
4145 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_out_of_bounds)
4146 << AL << (I + 1) << IdxExpr->getSourceRange();
4147 return;
4148 }
4149
4150 SR = IdxExpr->getSourceRange();
4151 } else {
4152 llvm_unreachable("Unexpected ParsedAttr argument type!");
4153 }
4154
4155 if (ArgIdx == 0 && !HasImplicitThisParam) {
4156 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_implicit_this_not_available)
4157 << (I + 1) << SR;
4158 return;
4159 }
4160
4161 // Adjust for the case we do not have an implicit "this" parameter. In this
4162 // case we decrease all positive values by 1 to get LLVM argument indices.
4163 if (!HasImplicitThisParam && ArgIdx > 0)
4164 ArgIdx -= 1;
4165
4166 EncodingIndices.push_back(Elt: ArgIdx);
4167 }
4168
4169 int CalleeIdx = EncodingIndices.front();
4170 // Check if the callee index is proper, thus not "this" and not "unknown".
4171 // This means the "CalleeIdx" has to be non-negative if "HasImplicitThisParam"
4172 // is false and positive if "HasImplicitThisParam" is true.
4173 if (CalleeIdx < (int)HasImplicitThisParam) {
4174 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_attribute_invalid_callee)
4175 << AL.getRange();
4176 return;
4177 }
4178
4179 // Get the callee type, note the index adjustment as the AST doesn't contain
4180 // the this type (which the callee cannot reference anyway!).
4181 const Type *CalleeType =
4182 getFunctionOrMethodParamType(D, Idx: CalleeIdx - HasImplicitThisParam)
4183 .getTypePtr();
4184 if (!CalleeType || !CalleeType->isFunctionPointerType()) {
4185 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_callee_no_function_type)
4186 << AL.getRange();
4187 return;
4188 }
4189
4190 const Type *CalleeFnType =
4191 CalleeType->getPointeeType()->getUnqualifiedDesugaredType();
4192
4193 // TODO: Check the type of the callee arguments.
4194
4195 const auto *CalleeFnProtoType = dyn_cast<FunctionProtoType>(Val: CalleeFnType);
4196 if (!CalleeFnProtoType) {
4197 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_callee_no_function_type)
4198 << AL.getRange();
4199 return;
4200 }
4201
4202 if (CalleeFnProtoType->getNumParams() != EncodingIndices.size() - 1) {
4203 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_wrong_arg_count_for_func)
4204 << AL << QualType{CalleeFnProtoType, 0}
4205 << CalleeFnProtoType->getNumParams()
4206 << (unsigned)(EncodingIndices.size() - 1);
4207 return;
4208 }
4209
4210 if (CalleeFnProtoType->isVariadic()) {
4211 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_callee_is_variadic) << AL.getRange();
4212 return;
4213 }
4214
4215 // Do not allow multiple callback attributes.
4216 if (D->hasAttr<CallbackAttr>()) {
4217 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_attribute_multiple) << AL.getRange();
4218 return;
4219 }
4220
4221 D->addAttr(A: ::new (S.Context) CallbackAttr(
4222 S.Context, AL, EncodingIndices.data(), EncodingIndices.size()));
4223}
4224
4225LifetimeCaptureByAttr *Sema::ParseLifetimeCaptureByAttr(const ParsedAttr &AL,
4226 StringRef ParamName) {
4227 // Atleast one capture by is required.
4228 if (AL.getNumArgs() == 0) {
4229 Diag(Loc: AL.getLoc(), DiagID: diag::err_capture_by_attribute_no_entity)
4230 << AL.getRange();
4231 return nullptr;
4232 }
4233 unsigned N = AL.getNumArgs();
4234 auto ParamIdents =
4235 MutableArrayRef<IdentifierInfo *>(new (Context) IdentifierInfo *[N], N);
4236 auto ParamLocs =
4237 MutableArrayRef<SourceLocation>(new (Context) SourceLocation[N], N);
4238 bool IsValid = true;
4239 for (unsigned I = 0; I < N; ++I) {
4240 if (AL.isArgExpr(Arg: I)) {
4241 Expr *E = AL.getArgAsExpr(Arg: I);
4242 Diag(Loc: E->getExprLoc(), DiagID: diag::err_capture_by_attribute_argument_unknown)
4243 << E << E->getExprLoc();
4244 IsValid = false;
4245 continue;
4246 }
4247 assert(AL.isArgIdent(I));
4248 IdentifierLoc *IdLoc = AL.getArgAsIdent(Arg: I);
4249 if (IdLoc->getIdentifierInfo()->getName() == ParamName) {
4250 Diag(Loc: IdLoc->getLoc(), DiagID: diag::err_capture_by_references_itself)
4251 << IdLoc->getLoc();
4252 IsValid = false;
4253 continue;
4254 }
4255 ParamIdents[I] = IdLoc->getIdentifierInfo();
4256 ParamLocs[I] = IdLoc->getLoc();
4257 }
4258 if (!IsValid)
4259 return nullptr;
4260 SmallVector<int> FakeParamIndices(N, LifetimeCaptureByAttr::Invalid);
4261 auto *CapturedBy =
4262 LifetimeCaptureByAttr::Create(Ctx&: Context, Params: FakeParamIndices.data(), ParamsSize: N, CommonInfo: AL);
4263 CapturedBy->setArgs(Idents: ParamIdents, Locs: ParamLocs);
4264 return CapturedBy;
4265}
4266
4267static void handleLifetimeCaptureByAttr(Sema &S, Decl *D,
4268 const ParsedAttr &AL) {
4269 // Do not allow multiple attributes.
4270 if (D->hasAttr<LifetimeCaptureByAttr>()) {
4271 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_capture_by_attribute_multiple)
4272 << AL.getRange();
4273 return;
4274 }
4275 auto *PVD = dyn_cast<ParmVarDecl>(Val: D);
4276 assert(PVD);
4277 auto *CaptureByAttr = S.ParseLifetimeCaptureByAttr(AL, ParamName: PVD->getName());
4278 if (CaptureByAttr)
4279 D->addAttr(A: CaptureByAttr);
4280}
4281
4282void Sema::LazyProcessLifetimeCaptureByParams(FunctionDecl *FD) {
4283 bool HasImplicitThisParam = hasImplicitObjectParameter(D: FD);
4284 SmallVector<LifetimeCaptureByAttr *, 1> Attrs;
4285 for (ParmVarDecl *PVD : FD->parameters())
4286 if (auto *A = PVD->getAttr<LifetimeCaptureByAttr>())
4287 Attrs.push_back(Elt: A);
4288 if (HasImplicitThisParam) {
4289 TypeSourceInfo *TSI = FD->getTypeSourceInfo();
4290 if (!TSI)
4291 return;
4292 AttributedTypeLoc ATL;
4293 for (TypeLoc TL = TSI->getTypeLoc();
4294 (ATL = TL.getAsAdjusted<AttributedTypeLoc>());
4295 TL = ATL.getModifiedLoc()) {
4296 if (auto *A = ATL.getAttrAs<LifetimeCaptureByAttr>())
4297 Attrs.push_back(Elt: const_cast<LifetimeCaptureByAttr *>(A));
4298 }
4299 }
4300 if (Attrs.empty())
4301 return;
4302 llvm::StringMap<int> NameIdxMapping = {
4303 {"global", LifetimeCaptureByAttr::Global},
4304 {"unknown", LifetimeCaptureByAttr::Unknown}};
4305 int Idx = 0;
4306 if (HasImplicitThisParam) {
4307 NameIdxMapping["this"] = 0;
4308 Idx++;
4309 }
4310 for (const ParmVarDecl *PVD : FD->parameters())
4311 NameIdxMapping[PVD->getName()] = Idx++;
4312 auto DisallowReservedParams = [&](StringRef Reserved) {
4313 for (const ParmVarDecl *PVD : FD->parameters())
4314 if (PVD->getName() == Reserved)
4315 Diag(Loc: PVD->getLocation(), DiagID: diag::err_capture_by_param_uses_reserved_name)
4316 << (PVD->getName() == "unknown");
4317 };
4318 for (auto *CapturedBy : Attrs) {
4319 const auto &Entities = CapturedBy->getArgIdents();
4320 for (size_t I = 0; I < Entities.size(); ++I) {
4321 StringRef Name = Entities[I]->getName();
4322 auto It = NameIdxMapping.find(Key: Name);
4323 if (It == NameIdxMapping.end()) {
4324 auto Loc = CapturedBy->getArgLocs()[I];
4325 if (!HasImplicitThisParam && Name == "this")
4326 Diag(Loc, DiagID: diag::err_capture_by_implicit_this_not_available) << Loc;
4327 else
4328 Diag(Loc, DiagID: diag::err_capture_by_attribute_argument_unknown)
4329 << Entities[I] << Loc;
4330 continue;
4331 }
4332 if (Name == "unknown" || Name == "global")
4333 DisallowReservedParams(Name);
4334 CapturedBy->setParamIdx(Idx: I, Val: It->second);
4335 }
4336 }
4337}
4338
4339static bool isFunctionLike(const Type &T) {
4340 // Check for explicit function types.
4341 // 'called_once' is only supported in Objective-C and it has
4342 // function pointers and block pointers.
4343 return T.isFunctionPointerType() || T.isBlockPointerType();
4344}
4345
4346/// Handle 'called_once' attribute.
4347static void handleCalledOnceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4348 // 'called_once' only applies to parameters representing functions.
4349 QualType T = cast<ParmVarDecl>(Val: D)->getType();
4350
4351 if (!isFunctionLike(T: *T)) {
4352 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_called_once_attribute_wrong_type);
4353 return;
4354 }
4355
4356 D->addAttr(A: ::new (S.Context) CalledOnceAttr(S.Context, AL));
4357}
4358
4359static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4360 // Try to find the underlying union declaration.
4361 RecordDecl *RD = nullptr;
4362 const auto *TD = dyn_cast<TypedefNameDecl>(Val: D);
4363 if (TD && TD->getUnderlyingType()->isUnionType())
4364 RD = TD->getUnderlyingType()->getAsRecordDecl();
4365 else
4366 RD = dyn_cast<RecordDecl>(Val: D);
4367
4368 if (!RD || !RD->isUnion()) {
4369 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_wrong_decl_type)
4370 << AL << AL.isRegularKeywordAttribute() << ExpectedUnion;
4371 return;
4372 }
4373
4374 if (!RD->isCompleteDefinition()) {
4375 if (!RD->isBeingDefined())
4376 S.Diag(Loc: AL.getLoc(),
4377 DiagID: diag::warn_transparent_union_attribute_not_definition);
4378 return;
4379 }
4380
4381 RecordDecl::field_iterator Field = RD->field_begin(),
4382 FieldEnd = RD->field_end();
4383 if (Field == FieldEnd) {
4384 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_transparent_union_attribute_zero_fields);
4385 return;
4386 }
4387
4388 FieldDecl *FirstField = *Field;
4389 QualType FirstType = FirstField->getType();
4390 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
4391 S.Diag(Loc: FirstField->getLocation(),
4392 DiagID: diag::warn_transparent_union_attribute_floating)
4393 << FirstType->isVectorType() << FirstType;
4394 return;
4395 }
4396
4397 if (FirstType->isIncompleteType())
4398 return;
4399 uint64_t FirstSize = S.Context.getTypeSize(T: FirstType);
4400 uint64_t FirstAlign = S.Context.getTypeAlign(T: FirstType);
4401 for (; Field != FieldEnd; ++Field) {
4402 QualType FieldType = Field->getType();
4403 if (FieldType->isIncompleteType())
4404 return;
4405 // FIXME: this isn't fully correct; we also need to test whether the
4406 // members of the union would all have the same calling convention as the
4407 // first member of the union. Checking just the size and alignment isn't
4408 // sufficient (consider structs passed on the stack instead of in registers
4409 // as an example).
4410 if (S.Context.getTypeSize(T: FieldType) != FirstSize ||
4411 S.Context.getTypeAlign(T: FieldType) > FirstAlign) {
4412 // Warn if we drop the attribute.
4413 bool isSize = S.Context.getTypeSize(T: FieldType) != FirstSize;
4414 unsigned FieldBits = isSize ? S.Context.getTypeSize(T: FieldType)
4415 : S.Context.getTypeAlign(T: FieldType);
4416 S.Diag(Loc: Field->getLocation(),
4417 DiagID: diag::warn_transparent_union_attribute_field_size_align)
4418 << isSize << *Field << FieldBits;
4419 unsigned FirstBits = isSize ? FirstSize : FirstAlign;
4420 S.Diag(Loc: FirstField->getLocation(),
4421 DiagID: diag::note_transparent_union_first_field_size_align)
4422 << isSize << FirstBits;
4423 return;
4424 }
4425 }
4426
4427 RD->addAttr(A: ::new (S.Context) TransparentUnionAttr(S.Context, AL));
4428}
4429
4430static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4431 auto *Attr = S.CreateAnnotationAttr(AL);
4432 if (Attr) {
4433 D->addAttr(A: Attr);
4434 }
4435}
4436
4437static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4438 S.AddAlignValueAttr(D, CI: AL, E: AL.getArgAsExpr(Arg: 0));
4439}
4440
4441void Sema::AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E) {
4442 SourceLocation AttrLoc = CI.getLoc();
4443
4444 QualType T;
4445 if (const auto *TD = dyn_cast<TypedefNameDecl>(Val: D))
4446 T = TD->getUnderlyingType();
4447 else if (const auto *VD = dyn_cast<ValueDecl>(Val: D))
4448 T = VD->getType();
4449 else
4450 llvm_unreachable("Unknown decl type for align_value");
4451
4452 if (!T->isDependentType() && !T->isAnyPointerType() &&
4453 !T->isReferenceType() && !T->isMemberPointerType()) {
4454 Diag(Loc: AttrLoc, DiagID: diag::warn_attribute_pointer_or_reference_only)
4455 << CI << T << D->getSourceRange();
4456 return;
4457 }
4458
4459 if (!E->isValueDependent()) {
4460 llvm::APSInt Alignment;
4461 ExprResult ICE = VerifyIntegerConstantExpression(
4462 E, Result: &Alignment, DiagID: diag::err_align_value_attribute_argument_not_int);
4463 if (ICE.isInvalid())
4464 return;
4465
4466 if (!Alignment.isPowerOf2()) {
4467 Diag(Loc: AttrLoc, DiagID: diag::err_alignment_not_power_of_two)
4468 << E->getSourceRange();
4469 return;
4470 }
4471
4472 D->addAttr(A: ::new (Context) AlignValueAttr(Context, CI, ICE.get()));
4473 return;
4474 }
4475
4476 // Save dependent expressions in the AST to be instantiated.
4477 D->addAttr(A: ::new (Context) AlignValueAttr(Context, CI, E));
4478}
4479
4480static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4481 if (AL.hasParsedType()) {
4482 const ParsedType &TypeArg = AL.getTypeArg();
4483 TypeSourceInfo *TInfo;
4484 (void)S.GetTypeFromParser(
4485 Ty: ParsedType::getFromOpaquePtr(P: TypeArg.getAsOpaquePtr()), TInfo: &TInfo);
4486 if (AL.isPackExpansion() &&
4487 !TInfo->getType()->containsUnexpandedParameterPack()) {
4488 S.Diag(Loc: AL.getEllipsisLoc(),
4489 DiagID: diag::err_pack_expansion_without_parameter_packs);
4490 return;
4491 }
4492
4493 if (!AL.isPackExpansion() &&
4494 S.DiagnoseUnexpandedParameterPack(Loc: TInfo->getTypeLoc().getBeginLoc(),
4495 T: TInfo, UPPC: Sema::UPPC_Expression))
4496 return;
4497
4498 S.AddAlignedAttr(D, CI: AL, T: TInfo, IsPackExpansion: AL.isPackExpansion());
4499 return;
4500 }
4501
4502 // check the attribute arguments.
4503 if (AL.getNumArgs() > 1) {
4504 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_wrong_number_arguments) << AL << 1;
4505 return;
4506 }
4507
4508 if (AL.getNumArgs() == 0) {
4509 D->addAttr(A: ::new (S.Context) AlignedAttr(S.Context, AL, true, nullptr));
4510 return;
4511 }
4512
4513 Expr *E = AL.getArgAsExpr(Arg: 0);
4514 if (AL.isPackExpansion() && !E->containsUnexpandedParameterPack()) {
4515 S.Diag(Loc: AL.getEllipsisLoc(),
4516 DiagID: diag::err_pack_expansion_without_parameter_packs);
4517 return;
4518 }
4519
4520 if (!AL.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E))
4521 return;
4522
4523 S.AddAlignedAttr(D, CI: AL, E, IsPackExpansion: AL.isPackExpansion());
4524}
4525
4526/// Perform checking of type validity
4527///
4528/// C++11 [dcl.align]p1:
4529/// An alignment-specifier may be applied to a variable or to a class
4530/// data member, but it shall not be applied to a bit-field, a function
4531/// parameter, the formal parameter of a catch clause, or a variable
4532/// declared with the register storage class specifier. An
4533/// alignment-specifier may also be applied to the declaration of a class
4534/// or enumeration type.
4535/// CWG 2354:
4536/// CWG agreed to remove permission for alignas to be applied to
4537/// enumerations.
4538/// C11 6.7.5/2:
4539/// An alignment attribute shall not be specified in a declaration of
4540/// a typedef, or a bit-field, or a function, or a parameter, or an
4541/// object declared with the register storage-class specifier.
4542static bool validateAlignasAppliedType(Sema &S, Decl *D,
4543 const AlignedAttr &Attr,
4544 SourceLocation AttrLoc) {
4545 int DiagKind = -1;
4546 if (isa<ParmVarDecl>(Val: D)) {
4547 DiagKind = 0;
4548 } else if (const auto *VD = dyn_cast<VarDecl>(Val: D)) {
4549 if (VD->getStorageClass() == SC_Register)
4550 DiagKind = 1;
4551 if (VD->isExceptionVariable())
4552 DiagKind = 2;
4553 } else if (const auto *FD = dyn_cast<FieldDecl>(Val: D)) {
4554 if (FD->isBitField())
4555 DiagKind = 3;
4556 } else if (const auto *ED = dyn_cast<EnumDecl>(Val: D)) {
4557 if (ED->getLangOpts().CPlusPlus)
4558 DiagKind = 4;
4559 } else if (!isa<TagDecl>(Val: D)) {
4560 return S.Diag(Loc: AttrLoc, DiagID: diag::err_attribute_wrong_decl_type)
4561 << &Attr << Attr.isRegularKeywordAttribute()
4562 << (Attr.isC11() ? ExpectedVariableOrField
4563 : ExpectedVariableFieldOrTag);
4564 }
4565 if (DiagKind != -1) {
4566 return S.Diag(Loc: AttrLoc, DiagID: diag::err_alignas_attribute_wrong_decl_type)
4567 << &Attr << DiagKind;
4568 }
4569 return false;
4570}
4571
4572void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
4573 bool IsPackExpansion) {
4574 AlignedAttr TmpAttr(Context, CI, true, E);
4575 SourceLocation AttrLoc = CI.getLoc();
4576
4577 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
4578 if (TmpAttr.isAlignas() &&
4579 validateAlignasAppliedType(S&: *this, D, Attr: TmpAttr, AttrLoc))
4580 return;
4581
4582 if (E->isValueDependent()) {
4583 // We can't support a dependent alignment on a non-dependent type,
4584 // because we have no way to model that a type is "alignment-dependent"
4585 // but not dependent in any other way.
4586 if (const auto *TND = dyn_cast<TypedefNameDecl>(Val: D)) {
4587 if (!TND->getUnderlyingType()->isDependentType()) {
4588 Diag(Loc: AttrLoc, DiagID: diag::err_alignment_dependent_typedef_name)
4589 << E->getSourceRange();
4590 return;
4591 }
4592 }
4593
4594 // Save dependent expressions in the AST to be instantiated.
4595 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, E);
4596 AA->setPackExpansion(IsPackExpansion);
4597 D->addAttr(A: AA);
4598 return;
4599 }
4600
4601 // FIXME: Cache the number on the AL object?
4602 llvm::APSInt Alignment;
4603 ExprResult ICE = VerifyIntegerConstantExpression(
4604 E, Result: &Alignment, DiagID: diag::err_aligned_attribute_argument_not_int);
4605 if (ICE.isInvalid())
4606 return;
4607
4608 uint64_t MaximumAlignment = Sema::MaximumAlignment;
4609 if (Context.getTargetInfo().getTriple().isOSBinFormatCOFF())
4610 MaximumAlignment = std::min(a: MaximumAlignment, b: uint64_t(8192));
4611 if (Alignment > MaximumAlignment) {
4612 Diag(Loc: AttrLoc, DiagID: diag::err_attribute_aligned_too_great)
4613 << MaximumAlignment << E->getSourceRange();
4614 return;
4615 }
4616
4617 uint64_t AlignVal = Alignment.getZExtValue();
4618 // C++11 [dcl.align]p2:
4619 // -- if the constant expression evaluates to zero, the alignment
4620 // specifier shall have no effect
4621 // C11 6.7.5p6:
4622 // An alignment specification of zero has no effect.
4623 if (!(TmpAttr.isAlignas() && !Alignment)) {
4624 if (!llvm::isPowerOf2_64(Value: AlignVal)) {
4625 Diag(Loc: AttrLoc, DiagID: diag::err_alignment_not_power_of_two)
4626 << E->getSourceRange();
4627 return;
4628 }
4629 }
4630
4631 const auto *VD = dyn_cast<VarDecl>(Val: D);
4632 if (VD) {
4633 unsigned MaxTLSAlign =
4634 Context.toCharUnitsFromBits(BitSize: Context.getTargetInfo().getMaxTLSAlign())
4635 .getQuantity();
4636 if (MaxTLSAlign && AlignVal > MaxTLSAlign &&
4637 VD->getTLSKind() != VarDecl::TLS_None) {
4638 Diag(Loc: VD->getLocation(), DiagID: diag::err_tls_var_aligned_over_maximum)
4639 << (unsigned)AlignVal << VD << MaxTLSAlign;
4640 return;
4641 }
4642 }
4643
4644 // On AIX, an aligned attribute can not decrease the alignment when applied
4645 // to a variable declaration with vector type.
4646 if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {
4647 const Type *Ty = VD->getType().getTypePtr();
4648 if (Ty->isVectorType() && AlignVal < 16) {
4649 Diag(Loc: VD->getLocation(), DiagID: diag::warn_aligned_attr_underaligned)
4650 << VD->getType() << 16;
4651 return;
4652 }
4653 }
4654
4655 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, ICE.get());
4656 AA->setPackExpansion(IsPackExpansion);
4657 AA->setCachedAlignmentValue(
4658 static_cast<unsigned>(AlignVal * Context.getCharWidth()));
4659 D->addAttr(A: AA);
4660}
4661
4662void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI,
4663 TypeSourceInfo *TS, bool IsPackExpansion) {
4664 AlignedAttr TmpAttr(Context, CI, false, TS);
4665 SourceLocation AttrLoc = CI.getLoc();
4666
4667 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
4668 if (TmpAttr.isAlignas() &&
4669 validateAlignasAppliedType(S&: *this, D, Attr: TmpAttr, AttrLoc))
4670 return;
4671
4672 if (TS->getType()->isDependentType()) {
4673 // We can't support a dependent alignment on a non-dependent type,
4674 // because we have no way to model that a type is "type-dependent"
4675 // but not dependent in any other way.
4676 if (const auto *TND = dyn_cast<TypedefNameDecl>(Val: D)) {
4677 if (!TND->getUnderlyingType()->isDependentType()) {
4678 Diag(Loc: AttrLoc, DiagID: diag::err_alignment_dependent_typedef_name)
4679 << TS->getTypeLoc().getSourceRange();
4680 return;
4681 }
4682 }
4683
4684 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
4685 AA->setPackExpansion(IsPackExpansion);
4686 D->addAttr(A: AA);
4687 return;
4688 }
4689
4690 const auto *VD = dyn_cast<VarDecl>(Val: D);
4691 unsigned AlignVal = TmpAttr.getAlignment(Ctx&: Context);
4692 // On AIX, an aligned attribute can not decrease the alignment when applied
4693 // to a variable declaration with vector type.
4694 if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {
4695 const Type *Ty = VD->getType().getTypePtr();
4696 if (Ty->isVectorType() &&
4697 Context.toCharUnitsFromBits(BitSize: AlignVal).getQuantity() < 16) {
4698 Diag(Loc: VD->getLocation(), DiagID: diag::warn_aligned_attr_underaligned)
4699 << VD->getType() << 16;
4700 return;
4701 }
4702 }
4703
4704 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
4705 AA->setPackExpansion(IsPackExpansion);
4706 AA->setCachedAlignmentValue(AlignVal);
4707 D->addAttr(A: AA);
4708}
4709
4710void Sema::CheckAlignasUnderalignment(Decl *D) {
4711 assert(D->hasAttrs() && "no attributes on decl");
4712
4713 QualType UnderlyingTy, DiagTy;
4714 if (const auto *VD = dyn_cast<ValueDecl>(Val: D)) {
4715 UnderlyingTy = DiagTy = VD->getType();
4716 } else {
4717 UnderlyingTy = DiagTy = Context.getCanonicalTagType(TD: cast<TagDecl>(Val: D));
4718 if (const auto *ED = dyn_cast<EnumDecl>(Val: D))
4719 UnderlyingTy = ED->getIntegerType();
4720 }
4721 if (DiagTy->isDependentType() || DiagTy->isIncompleteType())
4722 return;
4723
4724 // C++11 [dcl.align]p5, C11 6.7.5/4:
4725 // The combined effect of all alignment attributes in a declaration shall
4726 // not specify an alignment that is less strict than the alignment that
4727 // would otherwise be required for the entity being declared.
4728 AlignedAttr *AlignasAttr = nullptr;
4729 AlignedAttr *LastAlignedAttr = nullptr;
4730 unsigned Align = 0;
4731 for (auto *I : D->specific_attrs<AlignedAttr>()) {
4732 if (I->isAlignmentDependent())
4733 return;
4734 if (I->isAlignas())
4735 AlignasAttr = I;
4736 Align = std::max(a: Align, b: I->getAlignment(Ctx&: Context));
4737 LastAlignedAttr = I;
4738 }
4739
4740 if (Align && DiagTy->isSizelessType()) {
4741 Diag(Loc: LastAlignedAttr->getLocation(), DiagID: diag::err_attribute_sizeless_type)
4742 << LastAlignedAttr << DiagTy;
4743 } else if (AlignasAttr && Align) {
4744 CharUnits RequestedAlign = Context.toCharUnitsFromBits(BitSize: Align);
4745 CharUnits NaturalAlign = Context.getTypeAlignInChars(T: UnderlyingTy);
4746 if (NaturalAlign > RequestedAlign)
4747 Diag(Loc: AlignasAttr->getLocation(), DiagID: diag::err_alignas_underaligned)
4748 << DiagTy << (unsigned)NaturalAlign.getQuantity();
4749 }
4750}
4751
4752bool Sema::checkMSInheritanceAttrOnDefinition(
4753 CXXRecordDecl *RD, SourceRange Range, bool BestCase,
4754 MSInheritanceModel ExplicitModel) {
4755 assert(RD->hasDefinition() && "RD has no definition!");
4756
4757 // We may not have seen base specifiers or any virtual methods yet. We will
4758 // have to wait until the record is defined to catch any mismatches.
4759 if (!RD->getDefinition()->isCompleteDefinition())
4760 return false;
4761
4762 // The unspecified model never matches what a definition could need.
4763 if (ExplicitModel == MSInheritanceModel::Unspecified)
4764 return false;
4765
4766 if (BestCase) {
4767 if (RD->calculateInheritanceModel() == ExplicitModel)
4768 return false;
4769 } else {
4770 if (RD->calculateInheritanceModel() <= ExplicitModel)
4771 return false;
4772 }
4773
4774 Diag(Loc: Range.getBegin(), DiagID: diag::err_mismatched_ms_inheritance)
4775 << 0 /*definition*/;
4776 Diag(Loc: RD->getDefinition()->getLocation(), DiagID: diag::note_defined_here) << RD;
4777 return true;
4778}
4779
4780/// parseModeAttrArg - Parses attribute mode string and returns parsed type
4781/// attribute.
4782static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth,
4783 bool &IntegerMode, bool &ComplexMode,
4784 FloatModeKind &ExplicitType) {
4785 IntegerMode = true;
4786 ComplexMode = false;
4787 ExplicitType = FloatModeKind::NoFloat;
4788 switch (Str.size()) {
4789 case 2:
4790 switch (Str[0]) {
4791 case 'Q':
4792 DestWidth = 8;
4793 break;
4794 case 'H':
4795 DestWidth = 16;
4796 break;
4797 case 'S':
4798 DestWidth = 32;
4799 break;
4800 case 'D':
4801 DestWidth = 64;
4802 break;
4803 case 'X':
4804 DestWidth = 96;
4805 break;
4806 case 'K': // KFmode - IEEE quad precision (__float128)
4807 ExplicitType = FloatModeKind::Float128;
4808 DestWidth = Str[1] == 'I' ? 0 : 128;
4809 break;
4810 case 'T':
4811 ExplicitType = FloatModeKind::LongDouble;
4812 DestWidth = 128;
4813 break;
4814 case 'I':
4815 ExplicitType = FloatModeKind::Ibm128;
4816 DestWidth = Str[1] == 'I' ? 0 : 128;
4817 break;
4818 }
4819 if (Str[1] == 'F') {
4820 IntegerMode = false;
4821 } else if (Str[1] == 'C') {
4822 IntegerMode = false;
4823 ComplexMode = true;
4824 } else if (Str[1] != 'I') {
4825 DestWidth = 0;
4826 }
4827 break;
4828 case 4:
4829 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
4830 // pointer on PIC16 and other embedded platforms.
4831 if (Str == "word")
4832 DestWidth = S.Context.getTargetInfo().getRegisterWidth();
4833 else if (Str == "byte")
4834 DestWidth = S.Context.getTargetInfo().getCharWidth();
4835 break;
4836 case 7:
4837 if (Str == "pointer")
4838 DestWidth = S.Context.getTargetInfo().getPointerWidth(AddrSpace: LangAS::Default);
4839 break;
4840 case 11:
4841 if (Str == "unwind_word")
4842 DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
4843 break;
4844 }
4845}
4846
4847/// handleModeAttr - This attribute modifies the width of a decl with primitive
4848/// type.
4849///
4850/// Despite what would be logical, the mode attribute is a decl attribute, not a
4851/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
4852/// HImode, not an intermediate pointer.
4853static void handleModeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4854 // This attribute isn't documented, but glibc uses it. It changes
4855 // the width of an int or unsigned int to the specified size.
4856 if (!AL.isArgIdent(Arg: 0)) {
4857 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
4858 << AL << AANT_ArgumentIdentifier;
4859 return;
4860 }
4861
4862 IdentifierInfo *Name = AL.getArgAsIdent(Arg: 0)->getIdentifierInfo();
4863
4864 S.AddModeAttr(D, CI: AL, Name);
4865}
4866
4867void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI,
4868 const IdentifierInfo *Name, bool InInstantiation) {
4869 StringRef Str = Name->getName();
4870 normalizeName(AttrName&: Str);
4871 SourceLocation AttrLoc = CI.getLoc();
4872
4873 unsigned DestWidth = 0;
4874 bool IntegerMode = true;
4875 bool ComplexMode = false;
4876 FloatModeKind ExplicitType = FloatModeKind::NoFloat;
4877 llvm::APInt VectorSize(64, 0);
4878 if (Str.size() >= 4 && Str[0] == 'V') {
4879 // Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2).
4880 size_t StrSize = Str.size();
4881 size_t VectorStringLength = 0;
4882 while ((VectorStringLength + 1) < StrSize &&
4883 isdigit(Str[VectorStringLength + 1]))
4884 ++VectorStringLength;
4885 if (VectorStringLength &&
4886 !Str.substr(Start: 1, N: VectorStringLength).getAsInteger(Radix: 10, Result&: VectorSize) &&
4887 VectorSize.isPowerOf2()) {
4888 parseModeAttrArg(S&: *this, Str: Str.substr(Start: VectorStringLength + 1), DestWidth,
4889 IntegerMode, ComplexMode, ExplicitType);
4890 // Avoid duplicate warning from template instantiation.
4891 if (!InInstantiation)
4892 Diag(Loc: AttrLoc, DiagID: diag::warn_vector_mode_deprecated);
4893 } else {
4894 VectorSize = 0;
4895 }
4896 }
4897
4898 if (!VectorSize)
4899 parseModeAttrArg(S&: *this, Str, DestWidth, IntegerMode, ComplexMode,
4900 ExplicitType);
4901
4902 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
4903 // and friends, at least with glibc.
4904 // FIXME: Make sure floating-point mappings are accurate
4905 // FIXME: Support XF and TF types
4906 if (!DestWidth) {
4907 Diag(Loc: AttrLoc, DiagID: diag::err_machine_mode) << 0 /*Unknown*/ << Name;
4908 return;
4909 }
4910
4911 QualType OldTy;
4912 if (const auto *TD = dyn_cast<TypedefNameDecl>(Val: D))
4913 OldTy = TD->getUnderlyingType();
4914 else if (const auto *ED = dyn_cast<EnumDecl>(Val: D)) {
4915 // Something like 'typedef enum { X } __attribute__((mode(XX))) T;'.
4916 // Try to get type from enum declaration, default to int.
4917 OldTy = ED->getIntegerType();
4918 if (OldTy.isNull())
4919 OldTy = Context.IntTy;
4920 } else
4921 OldTy = cast<ValueDecl>(Val: D)->getType();
4922
4923 if (OldTy->isDependentType()) {
4924 D->addAttr(A: ::new (Context) ModeAttr(Context, CI, Name));
4925 return;
4926 }
4927
4928 // Base type can also be a vector type (see PR17453).
4929 // Distinguish between base type and base element type.
4930 QualType OldElemTy = OldTy;
4931 if (const auto *VT = OldTy->getAs<VectorType>())
4932 OldElemTy = VT->getElementType();
4933
4934 // GCC allows 'mode' attribute on enumeration types (even incomplete), except
4935 // for vector modes. So, 'enum X __attribute__((mode(QI)));' forms a complete
4936 // type, 'enum { A } __attribute__((mode(V4SI)))' is rejected.
4937 if ((isa<EnumDecl>(Val: D) || OldElemTy->isEnumeralType()) &&
4938 VectorSize.getBoolValue()) {
4939 Diag(Loc: AttrLoc, DiagID: diag::err_enum_mode_vector_type) << Name << CI.getRange();
4940 return;
4941 }
4942 bool IntegralOrAnyEnumType = (OldElemTy->isIntegralOrEnumerationType() &&
4943 !OldElemTy->isBitIntType()) ||
4944 OldElemTy->isEnumeralType();
4945
4946 if (!OldElemTy->getAs<BuiltinType>() && !OldElemTy->isComplexType() &&
4947 !IntegralOrAnyEnumType)
4948 Diag(Loc: AttrLoc, DiagID: diag::err_mode_not_primitive);
4949 else if (IntegerMode) {
4950 if (!IntegralOrAnyEnumType)
4951 Diag(Loc: AttrLoc, DiagID: diag::err_mode_wrong_type);
4952 } else if (ComplexMode) {
4953 if (!OldElemTy->isComplexType())
4954 Diag(Loc: AttrLoc, DiagID: diag::err_mode_wrong_type);
4955 } else {
4956 if (!OldElemTy->isFloatingType())
4957 Diag(Loc: AttrLoc, DiagID: diag::err_mode_wrong_type);
4958 }
4959
4960 QualType NewElemTy;
4961
4962 if (IntegerMode)
4963 NewElemTy = Context.getIntTypeForBitwidth(DestWidth,
4964 Signed: OldElemTy->isSignedIntegerType());
4965 else
4966 NewElemTy = Context.getRealTypeForBitwidth(DestWidth, ExplicitType);
4967
4968 if (NewElemTy.isNull()) {
4969 // Only emit diagnostic on host for 128-bit mode attribute
4970 if (!(DestWidth == 128 &&
4971 (getLangOpts().CUDAIsDevice || getLangOpts().SYCLIsDevice)))
4972 Diag(Loc: AttrLoc, DiagID: diag::err_machine_mode) << 1 /*Unsupported*/ << Name;
4973 return;
4974 }
4975
4976 if (ComplexMode) {
4977 NewElemTy = Context.getComplexType(T: NewElemTy);
4978 }
4979
4980 QualType NewTy = NewElemTy;
4981 if (VectorSize.getBoolValue()) {
4982 NewTy = Context.getVectorType(VectorType: NewTy, NumElts: VectorSize.getZExtValue(),
4983 VecKind: VectorKind::Generic);
4984 } else if (const auto *OldVT = OldTy->getAs<VectorType>()) {
4985 // Complex machine mode does not support base vector types.
4986 if (ComplexMode) {
4987 Diag(Loc: AttrLoc, DiagID: diag::err_complex_mode_vector_type);
4988 return;
4989 }
4990 unsigned NumElements = Context.getTypeSize(T: OldElemTy) *
4991 OldVT->getNumElements() /
4992 Context.getTypeSize(T: NewElemTy);
4993 NewTy =
4994 Context.getVectorType(VectorType: NewElemTy, NumElts: NumElements, VecKind: OldVT->getVectorKind());
4995 }
4996
4997 if (NewTy.isNull()) {
4998 Diag(Loc: AttrLoc, DiagID: diag::err_mode_wrong_type);
4999 return;
5000 }
5001
5002 // Install the new type.
5003 if (auto *TD = dyn_cast<TypedefNameDecl>(Val: D))
5004 TD->setModedTypeSourceInfo(unmodedTSI: TD->getTypeSourceInfo(), modedTy: NewTy);
5005 else if (auto *ED = dyn_cast<EnumDecl>(Val: D))
5006 ED->setIntegerType(NewTy);
5007 else
5008 cast<ValueDecl>(Val: D)->setType(NewTy);
5009
5010 D->addAttr(A: ::new (Context) ModeAttr(Context, CI, Name));
5011}
5012
5013static void handleNonStringAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5014 // This only applies to fields and variable declarations which have an array
5015 // type or pointer type, with character elements.
5016 QualType QT = cast<ValueDecl>(Val: D)->getType();
5017 if ((!QT->isArrayType() && !QT->isPointerType()) ||
5018 !QT->getPointeeOrArrayElementType()->isAnyCharacterType()) {
5019 S.Diag(Loc: D->getBeginLoc(), DiagID: diag::warn_attribute_non_character_array)
5020 << AL << AL.isRegularKeywordAttribute() << QT << AL.getRange();
5021 return;
5022 }
5023
5024 D->addAttr(A: ::new (S.Context) NonStringAttr(S.Context, AL));
5025}
5026
5027static void handleNoDebugAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5028 D->addAttr(A: ::new (S.Context) NoDebugAttr(S.Context, AL));
5029}
5030
5031AlwaysInlineAttr *Sema::mergeAlwaysInlineAttr(Decl *D,
5032 const AttributeCommonInfo &CI,
5033 const IdentifierInfo *Ident) {
5034 if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
5035 Diag(Loc: CI.getLoc(), DiagID: diag::warn_attribute_ignored) << Ident;
5036 Diag(Loc: Optnone->getLocation(), DiagID: diag::note_conflicting_attribute);
5037 return nullptr;
5038 }
5039
5040 if (D->hasAttr<AlwaysInlineAttr>())
5041 return nullptr;
5042
5043 return ::new (Context) AlwaysInlineAttr(Context, CI);
5044}
5045
5046InternalLinkageAttr *Sema::mergeInternalLinkageAttr(Decl *D,
5047 const ParsedAttr &AL) {
5048 if (const auto *VD = dyn_cast<VarDecl>(Val: D)) {
5049 // Attribute applies to Var but not any subclass of it (like ParmVar,
5050 // ImplicitParm or VarTemplateSpecialization).
5051 if (VD->getKind() != Decl::Var) {
5052 Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_wrong_decl_type)
5053 << AL << AL.isRegularKeywordAttribute()
5054 << (getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass
5055 : ExpectedVariableOrFunction);
5056 return nullptr;
5057 }
5058 // Attribute does not apply to non-static local variables.
5059 if (VD->hasLocalStorage()) {
5060 Diag(Loc: VD->getLocation(), DiagID: diag::warn_internal_linkage_local_storage);
5061 return nullptr;
5062 }
5063 }
5064
5065 return ::new (Context) InternalLinkageAttr(Context, AL);
5066}
5067InternalLinkageAttr *
5068Sema::mergeInternalLinkageAttr(Decl *D, const InternalLinkageAttr &AL) {
5069 if (const auto *VD = dyn_cast<VarDecl>(Val: D)) {
5070 // Attribute applies to Var but not any subclass of it (like ParmVar,
5071 // ImplicitParm or VarTemplateSpecialization).
5072 if (VD->getKind() != Decl::Var) {
5073 Diag(Loc: AL.getLocation(), DiagID: diag::warn_attribute_wrong_decl_type)
5074 << &AL << AL.isRegularKeywordAttribute()
5075 << (getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass
5076 : ExpectedVariableOrFunction);
5077 return nullptr;
5078 }
5079 // Attribute does not apply to non-static local variables.
5080 if (VD->hasLocalStorage()) {
5081 Diag(Loc: VD->getLocation(), DiagID: diag::warn_internal_linkage_local_storage);
5082 return nullptr;
5083 }
5084 }
5085
5086 return ::new (Context) InternalLinkageAttr(Context, AL);
5087}
5088
5089MinSizeAttr *Sema::mergeMinSizeAttr(Decl *D, const AttributeCommonInfo &CI) {
5090 if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
5091 Diag(Loc: CI.getLoc(), DiagID: diag::warn_attribute_ignored) << "'minsize'";
5092 Diag(Loc: Optnone->getLocation(), DiagID: diag::note_conflicting_attribute);
5093 return nullptr;
5094 }
5095
5096 if (D->hasAttr<MinSizeAttr>())
5097 return nullptr;
5098
5099 return ::new (Context) MinSizeAttr(Context, CI);
5100}
5101
5102OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D,
5103 const AttributeCommonInfo &CI) {
5104 if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) {
5105 Diag(Loc: Inline->getLocation(), DiagID: diag::warn_attribute_ignored) << Inline;
5106 Diag(Loc: CI.getLoc(), DiagID: diag::note_conflicting_attribute);
5107 D->dropAttr<AlwaysInlineAttr>();
5108 }
5109 if (MinSizeAttr *MinSize = D->getAttr<MinSizeAttr>()) {
5110 Diag(Loc: MinSize->getLocation(), DiagID: diag::warn_attribute_ignored) << MinSize;
5111 Diag(Loc: CI.getLoc(), DiagID: diag::note_conflicting_attribute);
5112 D->dropAttr<MinSizeAttr>();
5113 }
5114
5115 if (D->hasAttr<OptimizeNoneAttr>())
5116 return nullptr;
5117
5118 return ::new (Context) OptimizeNoneAttr(Context, CI);
5119}
5120
5121static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5122 if (AlwaysInlineAttr *Inline =
5123 S.mergeAlwaysInlineAttr(D, CI: AL, Ident: AL.getAttrName()))
5124 D->addAttr(A: Inline);
5125}
5126
5127static void handleMinSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5128 if (MinSizeAttr *MinSize = S.mergeMinSizeAttr(D, CI: AL))
5129 D->addAttr(A: MinSize);
5130}
5131
5132static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5133 if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr(D, CI: AL))
5134 D->addAttr(A: Optnone);
5135}
5136
5137static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5138 const auto *VD = cast<VarDecl>(Val: D);
5139 if (VD->hasLocalStorage()) {
5140 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_cuda_nonstatic_constdev);
5141 return;
5142 }
5143 if (!S.CheckVarDeclSizeAddressSpace(VD, AS: LangAS::cuda_constant))
5144 return;
5145 // constexpr variable may already get an implicit constant attr, which should
5146 // be replaced by the explicit constant attr.
5147 if (auto *A = D->getAttr<CUDAConstantAttr>()) {
5148 if (!A->isImplicit())
5149 return;
5150 D->dropAttr<CUDAConstantAttr>();
5151 }
5152 D->addAttr(A: ::new (S.Context) CUDAConstantAttr(S.Context, AL));
5153}
5154
5155static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5156 const auto *VD = cast<VarDecl>(Val: D);
5157 // extern __shared__ is only allowed on arrays with no length (e.g.
5158 // "int x[]").
5159 if (!S.getLangOpts().GPURelocatableDeviceCode && VD->hasExternalStorage() &&
5160 !isa<IncompleteArrayType>(Val: VD->getType())) {
5161 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_cuda_extern_shared) << VD;
5162 return;
5163 }
5164 if (!S.CheckVarDeclSizeAddressSpace(VD, AS: LangAS::cuda_shared))
5165 return;
5166 if (S.getLangOpts().CUDA && VD->hasLocalStorage() &&
5167 S.CUDA().DiagIfHostCode(Loc: AL.getLoc(), DiagID: diag::err_cuda_host_shared)
5168 << S.CUDA().CurrentTarget())
5169 return;
5170 D->addAttr(A: ::new (S.Context) CUDASharedAttr(S.Context, AL));
5171}
5172
5173static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5174 const auto *FD = cast<FunctionDecl>(Val: D);
5175 if (!FD->getReturnType()->isVoidType() &&
5176 !FD->getReturnType()->getAs<AutoType>() &&
5177 !FD->getReturnType()->isInstantiationDependentType()) {
5178 SourceRange RTRange = FD->getReturnTypeSourceRange();
5179 S.Diag(Loc: FD->getTypeSpecStartLoc(), DiagID: diag::err_kern_type_not_void_return)
5180 << FD->getType()
5181 << (RTRange.isValid() ? FixItHint::CreateReplacement(RemoveRange: RTRange, Code: "void")
5182 : FixItHint());
5183 return;
5184 }
5185 if (const auto *Method = dyn_cast<CXXMethodDecl>(Val: FD)) {
5186 if (Method->isInstance()) {
5187 S.Diag(Loc: Method->getBeginLoc(), DiagID: diag::err_kern_is_nonstatic_method)
5188 << Method;
5189 return;
5190 }
5191 S.Diag(Loc: Method->getBeginLoc(), DiagID: diag::warn_kern_is_method) << Method;
5192 }
5193 // Only warn for "inline" when compiling for host, to cut down on noise.
5194 if (FD->isInlineSpecified() && !S.getLangOpts().CUDAIsDevice)
5195 S.Diag(Loc: FD->getBeginLoc(), DiagID: diag::warn_kern_is_inline) << FD;
5196
5197 if (AL.getKind() == ParsedAttr::AT_DeviceKernel)
5198 D->addAttr(A: ::new (S.Context) DeviceKernelAttr(S.Context, AL));
5199 else
5200 D->addAttr(A: ::new (S.Context) CUDAGlobalAttr(S.Context, AL));
5201 // In host compilation the kernel is emitted as a stub function, which is
5202 // a helper function for launching the kernel. The instructions in the helper
5203 // function has nothing to do with the source code of the kernel. Do not emit
5204 // debug info for the stub function to avoid confusing the debugger.
5205 if (S.LangOpts.HIP && !S.LangOpts.CUDAIsDevice)
5206 D->addAttr(A: NoDebugAttr::CreateImplicit(Ctx&: S.Context));
5207}
5208
5209static void handleDeviceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5210 if (const auto *VD = dyn_cast<VarDecl>(Val: D)) {
5211 if (VD->hasLocalStorage()) {
5212 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_cuda_nonstatic_constdev);
5213 return;
5214 }
5215 if (!S.CheckVarDeclSizeAddressSpace(VD, AS: LangAS::cuda_device))
5216 return;
5217 }
5218
5219 if (auto *A = D->getAttr<CUDADeviceAttr>()) {
5220 if (!A->isImplicit())
5221 return;
5222 D->dropAttr<CUDADeviceAttr>();
5223 }
5224 D->addAttr(A: ::new (S.Context) CUDADeviceAttr(S.Context, AL));
5225}
5226
5227static void handleManagedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5228 if (const auto *VD = dyn_cast<VarDecl>(Val: D)) {
5229 if (VD->hasLocalStorage()) {
5230 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_cuda_nonstatic_constdev);
5231 return;
5232 }
5233 if (!S.CheckVarDeclSizeAddressSpace(VD, AS: LangAS::cuda_device))
5234 return;
5235 }
5236 if (!D->hasAttr<HIPManagedAttr>())
5237 D->addAttr(A: ::new (S.Context) HIPManagedAttr(S.Context, AL));
5238 if (!D->hasAttr<CUDADeviceAttr>())
5239 D->addAttr(A: CUDADeviceAttr::CreateImplicit(Ctx&: S.Context));
5240}
5241
5242static void handleGridConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5243 if (D->isInvalidDecl())
5244 return;
5245 // Whether __grid_constant__ is allowed to be used will be checked in
5246 // Sema::CheckFunctionDeclaration as we need complete function decl to make
5247 // the call.
5248 D->addAttr(A: ::new (S.Context) CUDAGridConstantAttr(S.Context, AL));
5249}
5250
5251static void handleGNUInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5252 const auto *Fn = cast<FunctionDecl>(Val: D);
5253 if (!Fn->isInlineSpecified()) {
5254 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_gnu_inline_attribute_requires_inline);
5255 return;
5256 }
5257
5258 if (S.LangOpts.CPlusPlus && Fn->getStorageClass() != SC_Extern)
5259 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_gnu_inline_cplusplus_without_extern);
5260
5261 D->addAttr(A: ::new (S.Context) GNUInlineAttr(S.Context, AL));
5262}
5263
5264static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5265 if (hasDeclarator(D)) return;
5266
5267 // Diagnostic is emitted elsewhere: here we store the (valid) AL
5268 // in the Decl node for syntactic reasoning, e.g., pretty-printing.
5269 CallingConv CC;
5270 if (S.CheckCallingConvAttr(
5271 attr: AL, CC, /*FD*/ nullptr,
5272 CFT: S.CUDA().IdentifyTarget(D: dyn_cast<FunctionDecl>(Val: D))))
5273 return;
5274
5275 if (!isa<ObjCMethodDecl>(Val: D)) {
5276 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_wrong_decl_type)
5277 << AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod;
5278 return;
5279 }
5280
5281 switch (AL.getKind()) {
5282 case ParsedAttr::AT_FastCall:
5283 D->addAttr(A: ::new (S.Context) FastCallAttr(S.Context, AL));
5284 return;
5285 case ParsedAttr::AT_StdCall:
5286 D->addAttr(A: ::new (S.Context) StdCallAttr(S.Context, AL));
5287 return;
5288 case ParsedAttr::AT_ThisCall:
5289 D->addAttr(A: ::new (S.Context) ThisCallAttr(S.Context, AL));
5290 return;
5291 case ParsedAttr::AT_CDecl:
5292 D->addAttr(A: ::new (S.Context) CDeclAttr(S.Context, AL));
5293 return;
5294 case ParsedAttr::AT_Pascal:
5295 D->addAttr(A: ::new (S.Context) PascalAttr(S.Context, AL));
5296 return;
5297 case ParsedAttr::AT_SwiftCall:
5298 D->addAttr(A: ::new (S.Context) SwiftCallAttr(S.Context, AL));
5299 return;
5300 case ParsedAttr::AT_SwiftAsyncCall:
5301 D->addAttr(A: ::new (S.Context) SwiftAsyncCallAttr(S.Context, AL));
5302 return;
5303 case ParsedAttr::AT_VectorCall:
5304 D->addAttr(A: ::new (S.Context) VectorCallAttr(S.Context, AL));
5305 return;
5306 case ParsedAttr::AT_MSABI:
5307 D->addAttr(A: ::new (S.Context) MSABIAttr(S.Context, AL));
5308 return;
5309 case ParsedAttr::AT_SysVABI:
5310 D->addAttr(A: ::new (S.Context) SysVABIAttr(S.Context, AL));
5311 return;
5312 case ParsedAttr::AT_RegCall:
5313 D->addAttr(A: ::new (S.Context) RegCallAttr(S.Context, AL));
5314 return;
5315 case ParsedAttr::AT_Pcs: {
5316 PcsAttr::PCSType PCS;
5317 switch (CC) {
5318 case CC_AAPCS:
5319 PCS = PcsAttr::AAPCS;
5320 break;
5321 case CC_AAPCS_VFP:
5322 PCS = PcsAttr::AAPCS_VFP;
5323 break;
5324 default:
5325 llvm_unreachable("unexpected calling convention in pcs attribute");
5326 }
5327
5328 D->addAttr(A: ::new (S.Context) PcsAttr(S.Context, AL, PCS));
5329 return;
5330 }
5331 case ParsedAttr::AT_AArch64VectorPcs:
5332 D->addAttr(A: ::new (S.Context) AArch64VectorPcsAttr(S.Context, AL));
5333 return;
5334 case ParsedAttr::AT_AArch64SVEPcs:
5335 D->addAttr(A: ::new (S.Context) AArch64SVEPcsAttr(S.Context, AL));
5336 return;
5337 case ParsedAttr::AT_DeviceKernel: {
5338 // The attribute should already be applied.
5339 assert(D->hasAttr<DeviceKernelAttr>() && "Expected attribute");
5340 return;
5341 }
5342 case ParsedAttr::AT_IntelOclBicc:
5343 D->addAttr(A: ::new (S.Context) IntelOclBiccAttr(S.Context, AL));
5344 return;
5345 case ParsedAttr::AT_PreserveMost:
5346 D->addAttr(A: ::new (S.Context) PreserveMostAttr(S.Context, AL));
5347 return;
5348 case ParsedAttr::AT_PreserveAll:
5349 D->addAttr(A: ::new (S.Context) PreserveAllAttr(S.Context, AL));
5350 return;
5351 case ParsedAttr::AT_M68kRTD:
5352 D->addAttr(A: ::new (S.Context) M68kRTDAttr(S.Context, AL));
5353 return;
5354 case ParsedAttr::AT_PreserveNone:
5355 D->addAttr(A: ::new (S.Context) PreserveNoneAttr(S.Context, AL));
5356 return;
5357 case ParsedAttr::AT_RISCVVectorCC:
5358 D->addAttr(A: ::new (S.Context) RISCVVectorCCAttr(S.Context, AL));
5359 return;
5360 case ParsedAttr::AT_RISCVVLSCC: {
5361 // If the riscv_abi_vlen doesn't have any argument, default ABI_VLEN is 128.
5362 unsigned VectorLength = 128;
5363 if (AL.getNumArgs() &&
5364 !S.checkUInt32Argument(AI: AL, Expr: AL.getArgAsExpr(Arg: 0), Val&: VectorLength))
5365 return;
5366 if (VectorLength < 32 || VectorLength > 65536) {
5367 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_argument_invalid_range)
5368 << VectorLength << 32 << 65536;
5369 return;
5370 }
5371 if (!llvm::isPowerOf2_64(Value: VectorLength)) {
5372 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_argument_not_power_of_2);
5373 return;
5374 }
5375
5376 D->addAttr(A: ::new (S.Context) RISCVVLSCCAttr(S.Context, AL, VectorLength));
5377 return;
5378 }
5379 default:
5380 llvm_unreachable("unexpected attribute kind");
5381 }
5382}
5383
5384static void handleDeviceKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5385 const auto *FD = dyn_cast_or_null<FunctionDecl>(Val: D);
5386 bool IsFunctionTemplate = FD && FD->getDescribedFunctionTemplate();
5387 llvm::Triple Triple = S.getASTContext().getTargetInfo().getTriple();
5388 const LangOptions &LangOpts = S.getLangOpts();
5389 // OpenCL has its own error messages.
5390 if (!LangOpts.OpenCL && FD && !FD->isExternallyVisible()) {
5391 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_hidden_device_kernel) << FD;
5392 AL.setInvalid();
5393 return;
5394 }
5395 if (Triple.isNVPTX()) {
5396 handleGlobalAttr(S, D, AL);
5397 } else {
5398 // OpenCL C++ will throw a more specific error.
5399 if (!LangOpts.OpenCLCPlusPlus && (!FD || IsFunctionTemplate)) {
5400 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_wrong_decl_type_str)
5401 << AL << AL.isRegularKeywordAttribute() << "functions";
5402 AL.setInvalid();
5403 return;
5404 }
5405 handleSimpleAttribute<DeviceKernelAttr>(S, D, CI: AL);
5406 }
5407 // TODO: isGPU() should probably return true for SPIR.
5408 bool TargetDeviceEnvironment = Triple.isGPU() || Triple.isSPIR() ||
5409 LangOpts.isTargetDevice() || LangOpts.OpenCL;
5410 if (!TargetDeviceEnvironment) {
5411 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_cconv_unsupported)
5412 << AL << (int)Sema::CallingConventionIgnoredReason::ForThisTarget;
5413 AL.setInvalid();
5414 return;
5415 }
5416
5417 // Make sure we validate the CC with the target
5418 // and warn/error if necessary.
5419 handleCallConvAttr(S, D, AL);
5420}
5421
5422static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5423 if (AL.getAttributeSpellingListIndex() == SuppressAttr::CXX11_gsl_suppress) {
5424 // Suppression attribute with GSL spelling requires at least 1 argument.
5425 if (!AL.checkAtLeastNumArgs(S, Num: 1))
5426 return;
5427 }
5428
5429 std::vector<StringRef> DiagnosticIdentifiers;
5430 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
5431 StringRef RuleName;
5432
5433 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: RuleName, ArgLocation: nullptr))
5434 return;
5435
5436 DiagnosticIdentifiers.push_back(x: RuleName);
5437 }
5438 D->addAttr(A: ::new (S.Context)
5439 SuppressAttr(S.Context, AL, DiagnosticIdentifiers.data(),
5440 DiagnosticIdentifiers.size()));
5441}
5442
5443static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5444 TypeSourceInfo *DerefTypeLoc = nullptr;
5445 QualType ParmType;
5446 if (AL.hasParsedType()) {
5447 ParmType = S.GetTypeFromParser(Ty: AL.getTypeArg(), TInfo: &DerefTypeLoc);
5448
5449 unsigned SelectIdx = ~0U;
5450 if (ParmType->isReferenceType())
5451 SelectIdx = 0;
5452 else if (ParmType->isArrayType())
5453 SelectIdx = 1;
5454
5455 if (SelectIdx != ~0U) {
5456 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_invalid_argument)
5457 << SelectIdx << AL;
5458 return;
5459 }
5460 }
5461
5462 // To check if earlier decl attributes do not conflict the newly parsed ones
5463 // we always add (and check) the attribute to the canonical decl. We need
5464 // to repeat the check for attribute mutual exclusion because we're attaching
5465 // all of the attributes to the canonical declaration rather than the current
5466 // declaration.
5467 D = D->getCanonicalDecl();
5468 if (AL.getKind() == ParsedAttr::AT_Owner) {
5469 if (checkAttrMutualExclusion<PointerAttr>(S, D, AL))
5470 return;
5471 if (const auto *OAttr = D->getAttr<OwnerAttr>()) {
5472 const Type *ExistingDerefType = OAttr->getDerefTypeLoc()
5473 ? OAttr->getDerefType().getTypePtr()
5474 : nullptr;
5475 if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
5476 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attributes_are_not_compatible)
5477 << AL << OAttr
5478 << (AL.isRegularKeywordAttribute() ||
5479 OAttr->isRegularKeywordAttribute());
5480 S.Diag(Loc: OAttr->getLocation(), DiagID: diag::note_conflicting_attribute);
5481 }
5482 return;
5483 }
5484 for (Decl *Redecl : D->redecls()) {
5485 Redecl->addAttr(A: ::new (S.Context) OwnerAttr(S.Context, AL, DerefTypeLoc));
5486 }
5487 } else {
5488 if (checkAttrMutualExclusion<OwnerAttr>(S, D, AL))
5489 return;
5490 if (const auto *PAttr = D->getAttr<PointerAttr>()) {
5491 const Type *ExistingDerefType = PAttr->getDerefTypeLoc()
5492 ? PAttr->getDerefType().getTypePtr()
5493 : nullptr;
5494 if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
5495 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attributes_are_not_compatible)
5496 << AL << PAttr
5497 << (AL.isRegularKeywordAttribute() ||
5498 PAttr->isRegularKeywordAttribute());
5499 S.Diag(Loc: PAttr->getLocation(), DiagID: diag::note_conflicting_attribute);
5500 }
5501 return;
5502 }
5503 for (Decl *Redecl : D->redecls()) {
5504 Redecl->addAttr(A: ::new (S.Context)
5505 PointerAttr(S.Context, AL, DerefTypeLoc));
5506 }
5507 }
5508}
5509
5510static void handleRandomizeLayoutAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5511 if (checkAttrMutualExclusion<NoRandomizeLayoutAttr>(S, D, AL))
5512 return;
5513 if (!D->hasAttr<RandomizeLayoutAttr>())
5514 D->addAttr(A: ::new (S.Context) RandomizeLayoutAttr(S.Context, AL));
5515}
5516
5517static void handleNoRandomizeLayoutAttr(Sema &S, Decl *D,
5518 const ParsedAttr &AL) {
5519 if (checkAttrMutualExclusion<RandomizeLayoutAttr>(S, D, AL))
5520 return;
5521 if (!D->hasAttr<NoRandomizeLayoutAttr>())
5522 D->addAttr(A: ::new (S.Context) NoRandomizeLayoutAttr(S.Context, AL));
5523}
5524
5525bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
5526 const FunctionDecl *FD,
5527 CUDAFunctionTarget CFT) {
5528 if (Attrs.isInvalid())
5529 return true;
5530
5531 if (Attrs.hasProcessingCache()) {
5532 CC = (CallingConv) Attrs.getProcessingCache();
5533 return false;
5534 }
5535
5536 if (Attrs.getKind() == ParsedAttr::AT_RISCVVLSCC) {
5537 // riscv_vls_cc only accepts 0 or 1 argument.
5538 if (!Attrs.checkAtLeastNumArgs(S&: *this, Num: 0) ||
5539 !Attrs.checkAtMostNumArgs(S&: *this, Num: 1)) {
5540 Attrs.setInvalid();
5541 return true;
5542 }
5543 } else {
5544 unsigned ReqArgs = Attrs.getKind() == ParsedAttr::AT_Pcs ? 1 : 0;
5545 if (!Attrs.checkExactlyNumArgs(S&: *this, Num: ReqArgs)) {
5546 Attrs.setInvalid();
5547 return true;
5548 }
5549 }
5550
5551 bool IsTargetDefaultMSABI =
5552 Context.getTargetInfo().getTriple().isOSWindows() ||
5553 Context.getTargetInfo().getTriple().isUEFI();
5554 // TODO: diagnose uses of these conventions on the wrong target.
5555 switch (Attrs.getKind()) {
5556 case ParsedAttr::AT_CDecl:
5557 CC = CC_C;
5558 break;
5559 case ParsedAttr::AT_FastCall:
5560 CC = CC_X86FastCall;
5561 break;
5562 case ParsedAttr::AT_StdCall:
5563 CC = CC_X86StdCall;
5564 break;
5565 case ParsedAttr::AT_ThisCall:
5566 CC = CC_X86ThisCall;
5567 break;
5568 case ParsedAttr::AT_Pascal:
5569 CC = CC_X86Pascal;
5570 break;
5571 case ParsedAttr::AT_SwiftCall:
5572 CC = CC_Swift;
5573 break;
5574 case ParsedAttr::AT_SwiftAsyncCall:
5575 CC = CC_SwiftAsync;
5576 break;
5577 case ParsedAttr::AT_VectorCall:
5578 CC = CC_X86VectorCall;
5579 break;
5580 case ParsedAttr::AT_AArch64VectorPcs:
5581 CC = CC_AArch64VectorCall;
5582 break;
5583 case ParsedAttr::AT_AArch64SVEPcs:
5584 CC = CC_AArch64SVEPCS;
5585 break;
5586 case ParsedAttr::AT_RegCall:
5587 CC = CC_X86RegCall;
5588 break;
5589 case ParsedAttr::AT_MSABI:
5590 CC = IsTargetDefaultMSABI ? CC_C : CC_Win64;
5591 break;
5592 case ParsedAttr::AT_SysVABI:
5593 CC = IsTargetDefaultMSABI ? CC_X86_64SysV : CC_C;
5594 break;
5595 case ParsedAttr::AT_Pcs: {
5596 StringRef StrRef;
5597 if (!checkStringLiteralArgumentAttr(AL: Attrs, ArgNum: 0, Str&: StrRef)) {
5598 Attrs.setInvalid();
5599 return true;
5600 }
5601 if (StrRef == "aapcs") {
5602 CC = CC_AAPCS;
5603 break;
5604 } else if (StrRef == "aapcs-vfp") {
5605 CC = CC_AAPCS_VFP;
5606 break;
5607 }
5608
5609 Attrs.setInvalid();
5610 Diag(Loc: Attrs.getLoc(), DiagID: diag::err_invalid_pcs);
5611 return true;
5612 }
5613 case ParsedAttr::AT_IntelOclBicc:
5614 CC = CC_IntelOclBicc;
5615 break;
5616 case ParsedAttr::AT_PreserveMost:
5617 CC = CC_PreserveMost;
5618 break;
5619 case ParsedAttr::AT_PreserveAll:
5620 CC = CC_PreserveAll;
5621 break;
5622 case ParsedAttr::AT_M68kRTD:
5623 CC = CC_M68kRTD;
5624 break;
5625 case ParsedAttr::AT_PreserveNone:
5626 CC = CC_PreserveNone;
5627 break;
5628 case ParsedAttr::AT_RISCVVectorCC:
5629 CC = CC_RISCVVectorCall;
5630 break;
5631 case ParsedAttr::AT_RISCVVLSCC: {
5632 // If the riscv_abi_vlen doesn't have any argument, we set set it to default
5633 // value 128.
5634 unsigned ABIVLen = 128;
5635 if (Attrs.getNumArgs() &&
5636 !checkUInt32Argument(AI: Attrs, Expr: Attrs.getArgAsExpr(Arg: 0), Val&: ABIVLen)) {
5637 Attrs.setInvalid();
5638 return true;
5639 }
5640 if (Attrs.getNumArgs() && (ABIVLen < 32 || ABIVLen > 65536)) {
5641 Attrs.setInvalid();
5642 Diag(Loc: Attrs.getLoc(), DiagID: diag::err_argument_invalid_range)
5643 << ABIVLen << 32 << 65536;
5644 return true;
5645 }
5646 if (!llvm::isPowerOf2_64(Value: ABIVLen)) {
5647 Attrs.setInvalid();
5648 Diag(Loc: Attrs.getLoc(), DiagID: diag::err_argument_not_power_of_2);
5649 return true;
5650 }
5651 CC = static_cast<CallingConv>(CallingConv::CC_RISCVVLSCall_32 +
5652 llvm::Log2_64(Value: ABIVLen) - 5);
5653 break;
5654 }
5655 case ParsedAttr::AT_DeviceKernel: {
5656 // Validation was handled in handleDeviceKernelAttr.
5657 CC = CC_DeviceKernel;
5658 break;
5659 }
5660 default: llvm_unreachable("unexpected attribute kind");
5661 }
5662
5663 TargetInfo::CallingConvCheckResult A = TargetInfo::CCCR_OK;
5664 const TargetInfo &TI = Context.getTargetInfo();
5665 auto *Aux = Context.getAuxTargetInfo();
5666 // CUDA functions may have host and/or device attributes which indicate
5667 // their targeted execution environment, therefore the calling convention
5668 // of functions in CUDA should be checked against the target deduced based
5669 // on their host/device attributes.
5670 if (LangOpts.CUDA) {
5671 assert(FD || CFT != CUDAFunctionTarget::InvalidTarget);
5672 auto CudaTarget = FD ? CUDA().IdentifyTarget(D: FD) : CFT;
5673 bool CheckHost = false, CheckDevice = false;
5674 switch (CudaTarget) {
5675 case CUDAFunctionTarget::HostDevice:
5676 CheckHost = true;
5677 CheckDevice = true;
5678 break;
5679 case CUDAFunctionTarget::Host:
5680 CheckHost = true;
5681 break;
5682 case CUDAFunctionTarget::Device:
5683 case CUDAFunctionTarget::Global:
5684 CheckDevice = true;
5685 break;
5686 case CUDAFunctionTarget::InvalidTarget:
5687 llvm_unreachable("unexpected cuda target");
5688 }
5689 auto *HostTI = LangOpts.CUDAIsDevice ? Aux : &TI;
5690 auto *DeviceTI = LangOpts.CUDAIsDevice ? &TI : Aux;
5691 if (CheckHost && HostTI)
5692 A = HostTI->checkCallingConvention(CC);
5693 if (A == TargetInfo::CCCR_OK && CheckDevice && DeviceTI)
5694 A = DeviceTI->checkCallingConvention(CC);
5695 } else if (LangOpts.SYCLIsDevice && TI.getTriple().isAMDGPU() &&
5696 CC == CC_X86VectorCall) {
5697 // Assuming SYCL Device AMDGPU CC_X86VectorCall functions are always to be
5698 // emitted on the host. The MSVC STL has CC-based specializations so we
5699 // cannot change the CC to be the default as that will cause a clash with
5700 // another specialization.
5701 A = TI.checkCallingConvention(CC);
5702 if (Aux && A != TargetInfo::CCCR_OK)
5703 A = Aux->checkCallingConvention(CC);
5704 } else {
5705 A = TI.checkCallingConvention(CC);
5706 }
5707
5708 switch (A) {
5709 case TargetInfo::CCCR_OK:
5710 break;
5711
5712 case TargetInfo::CCCR_Ignore:
5713 // Treat an ignored convention as if it was an explicit C calling convention
5714 // attribute. For example, __stdcall on Win x64 functions as __cdecl, so
5715 // that command line flags that change the default convention to
5716 // __vectorcall don't affect declarations marked __stdcall.
5717 CC = CC_C;
5718 break;
5719
5720 case TargetInfo::CCCR_Error:
5721 Diag(Loc: Attrs.getLoc(), DiagID: diag::error_cconv_unsupported)
5722 << Attrs << (int)CallingConventionIgnoredReason::ForThisTarget;
5723 break;
5724
5725 case TargetInfo::CCCR_Warning: {
5726 Diag(Loc: Attrs.getLoc(), DiagID: diag::warn_cconv_unsupported)
5727 << Attrs << (int)CallingConventionIgnoredReason::ForThisTarget;
5728
5729 // This convention is not valid for the target. Use the default function or
5730 // method calling convention.
5731 bool IsCXXMethod = false, IsVariadic = false;
5732 if (FD) {
5733 IsCXXMethod = FD->isCXXInstanceMember();
5734 IsVariadic = FD->isVariadic();
5735 }
5736 CC = Context.getDefaultCallingConvention(IsVariadic, IsCXXMethod);
5737 break;
5738 }
5739 }
5740
5741 Attrs.setProcessingCache((unsigned) CC);
5742 return false;
5743}
5744
5745bool Sema::CheckRegparmAttr(const ParsedAttr &AL, unsigned &numParams) {
5746 if (AL.isInvalid())
5747 return true;
5748
5749 if (!AL.checkExactlyNumArgs(S&: *this, Num: 1)) {
5750 AL.setInvalid();
5751 return true;
5752 }
5753
5754 uint32_t NP;
5755 Expr *NumParamsExpr = AL.getArgAsExpr(Arg: 0);
5756 if (!checkUInt32Argument(AI: AL, Expr: NumParamsExpr, Val&: NP)) {
5757 AL.setInvalid();
5758 return true;
5759 }
5760
5761 if (Context.getTargetInfo().getRegParmMax() == 0) {
5762 Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_regparm_wrong_platform)
5763 << NumParamsExpr->getSourceRange();
5764 AL.setInvalid();
5765 return true;
5766 }
5767
5768 numParams = NP;
5769 if (numParams > Context.getTargetInfo().getRegParmMax()) {
5770 Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_regparm_invalid_number)
5771 << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
5772 AL.setInvalid();
5773 return true;
5774 }
5775
5776 return false;
5777}
5778
5779// Helper to get OffloadArch.
5780static OffloadArch getOffloadArch(const TargetInfo &TI) {
5781 if (!TI.getTriple().isNVPTX())
5782 llvm_unreachable("getOffloadArch is only valid for NVPTX triple");
5783 auto &TO = TI.getTargetOpts();
5784 return StringToOffloadArch(S: TO.CPU);
5785}
5786
5787// Checks whether an argument of launch_bounds attribute is
5788// acceptable, performs implicit conversion to Rvalue, and returns
5789// non-nullptr Expr result on success. Otherwise, it returns nullptr
5790// and may output an error.
5791static Expr *makeLaunchBoundsArgExpr(Sema &S, Expr *E,
5792 const CUDALaunchBoundsAttr &AL,
5793 const unsigned Idx) {
5794 if (S.DiagnoseUnexpandedParameterPack(E))
5795 return nullptr;
5796
5797 // Accept template arguments for now as they depend on something else.
5798 // We'll get to check them when they eventually get instantiated.
5799 if (E->isValueDependent())
5800 return E;
5801
5802 std::optional<llvm::APSInt> I = llvm::APSInt(64);
5803 if (!(I = E->getIntegerConstantExpr(Ctx: S.Context))) {
5804 S.Diag(Loc: E->getExprLoc(), DiagID: diag::err_attribute_argument_n_type)
5805 << &AL << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
5806 return nullptr;
5807 }
5808 // Make sure we can fit it in 32 bits.
5809 if (!I->isIntN(N: 32)) {
5810 S.Diag(Loc: E->getExprLoc(), DiagID: diag::err_ice_too_large)
5811 << toString(I: *I, Radix: 10, Signed: false) << 32 << /* Unsigned */ 1;
5812 return nullptr;
5813 }
5814 if (*I < 0)
5815 S.Diag(Loc: E->getExprLoc(), DiagID: diag::warn_attribute_argument_n_negative)
5816 << &AL << Idx << E->getSourceRange();
5817
5818 // We may need to perform implicit conversion of the argument.
5819 InitializedEntity Entity = InitializedEntity::InitializeParameter(
5820 Context&: S.Context, Type: S.Context.getConstType(T: S.Context.IntTy), /*consume*/ Consumed: false);
5821 ExprResult ValArg = S.PerformCopyInitialization(Entity, EqualLoc: SourceLocation(), Init: E);
5822 assert(!ValArg.isInvalid() &&
5823 "Unexpected PerformCopyInitialization() failure.");
5824
5825 return ValArg.getAs<Expr>();
5826}
5827
5828CUDALaunchBoundsAttr *
5829Sema::CreateLaunchBoundsAttr(const AttributeCommonInfo &CI, Expr *MaxThreads,
5830 Expr *MinBlocks, Expr *MaxBlocks) {
5831 CUDALaunchBoundsAttr TmpAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);
5832 MaxThreads = makeLaunchBoundsArgExpr(S&: *this, E: MaxThreads, AL: TmpAttr, Idx: 0);
5833 if (!MaxThreads)
5834 return nullptr;
5835
5836 if (MinBlocks) {
5837 MinBlocks = makeLaunchBoundsArgExpr(S&: *this, E: MinBlocks, AL: TmpAttr, Idx: 1);
5838 if (!MinBlocks)
5839 return nullptr;
5840 }
5841
5842 if (MaxBlocks) {
5843 // '.maxclusterrank' ptx directive requires .target sm_90 or higher.
5844 auto SM = getOffloadArch(TI: Context.getTargetInfo());
5845 if (SM == OffloadArch::UNKNOWN || SM < OffloadArch::SM_90) {
5846 Diag(Loc: MaxBlocks->getBeginLoc(), DiagID: diag::warn_cuda_maxclusterrank_sm_90)
5847 << OffloadArchToString(A: SM) << CI << MaxBlocks->getSourceRange();
5848 // Ignore it by setting MaxBlocks to null;
5849 MaxBlocks = nullptr;
5850 } else {
5851 MaxBlocks = makeLaunchBoundsArgExpr(S&: *this, E: MaxBlocks, AL: TmpAttr, Idx: 2);
5852 if (!MaxBlocks)
5853 return nullptr;
5854 }
5855 }
5856
5857 return ::new (Context)
5858 CUDALaunchBoundsAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);
5859}
5860
5861void Sema::AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI,
5862 Expr *MaxThreads, Expr *MinBlocks,
5863 Expr *MaxBlocks) {
5864 if (auto *Attr = CreateLaunchBoundsAttr(CI, MaxThreads, MinBlocks, MaxBlocks))
5865 D->addAttr(A: Attr);
5866}
5867
5868static void handleLaunchBoundsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5869 if (!AL.checkAtLeastNumArgs(S, Num: 1) || !AL.checkAtMostNumArgs(S, Num: 3))
5870 return;
5871
5872 S.AddLaunchBoundsAttr(D, CI: AL, MaxThreads: AL.getArgAsExpr(Arg: 0),
5873 MinBlocks: AL.getNumArgs() > 1 ? AL.getArgAsExpr(Arg: 1) : nullptr,
5874 MaxBlocks: AL.getNumArgs() > 2 ? AL.getArgAsExpr(Arg: 2) : nullptr);
5875}
5876
5877static std::pair<Expr *, int>
5878makeClusterDimsArgExpr(Sema &S, Expr *E, const CUDAClusterDimsAttr &AL,
5879 const unsigned Idx) {
5880 if (!E || S.DiagnoseUnexpandedParameterPack(E))
5881 return {};
5882
5883 // Accept template arguments for now as they depend on something else.
5884 // We'll get to check them when they eventually get instantiated.
5885 if (E->isInstantiationDependent())
5886 return {E, 1};
5887
5888 std::optional<llvm::APSInt> I = E->getIntegerConstantExpr(Ctx: S.Context);
5889 if (!I) {
5890 S.Diag(Loc: E->getExprLoc(), DiagID: diag::err_attribute_argument_n_type)
5891 << &AL << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
5892 return {};
5893 }
5894 // Make sure we can fit it in 4 bits.
5895 if (!I->isIntN(N: 4)) {
5896 S.Diag(Loc: E->getExprLoc(), DiagID: diag::err_ice_too_large)
5897 << toString(I: *I, Radix: 10, Signed: false) << 4 << /*Unsigned=*/1;
5898 return {};
5899 }
5900 if (*I < 0) {
5901 S.Diag(Loc: E->getExprLoc(), DiagID: diag::warn_attribute_argument_n_negative)
5902 << &AL << Idx << E->getSourceRange();
5903 }
5904
5905 return {ConstantExpr::Create(Context: S.getASTContext(), E, Result: APValue(*I)),
5906 I->getZExtValue()};
5907}
5908
5909CUDAClusterDimsAttr *Sema::createClusterDimsAttr(const AttributeCommonInfo &CI,
5910 Expr *X, Expr *Y, Expr *Z) {
5911 CUDAClusterDimsAttr TmpAttr(Context, CI, X, Y, Z);
5912
5913 auto [NewX, ValX] = makeClusterDimsArgExpr(S&: *this, E: X, AL: TmpAttr, /*Idx=*/0);
5914 auto [NewY, ValY] = makeClusterDimsArgExpr(S&: *this, E: Y, AL: TmpAttr, /*Idx=*/1);
5915 auto [NewZ, ValZ] = makeClusterDimsArgExpr(S&: *this, E: Z, AL: TmpAttr, /*Idx=*/2);
5916
5917 if (!NewX || (Y && !NewY) || (Z && !NewZ))
5918 return nullptr;
5919
5920 int FlatDim = ValX * ValY * ValZ;
5921 const llvm::Triple TT =
5922 (!Context.getLangOpts().CUDAIsDevice && Context.getAuxTargetInfo())
5923 ? Context.getAuxTargetInfo()->getTriple()
5924 : Context.getTargetInfo().getTriple();
5925 int MaxDim = 1;
5926 if (TT.isNVPTX())
5927 MaxDim = 8;
5928 else if (TT.isAMDGPU())
5929 MaxDim = 16;
5930 else
5931 return nullptr;
5932
5933 // A maximum of 8 thread blocks in a cluster is supported as a portable
5934 // cluster size in CUDA. The number is 16 for AMDGPU.
5935 if (FlatDim > MaxDim) {
5936 Diag(Loc: CI.getLoc(), DiagID: diag::err_cluster_dims_too_large) << MaxDim << FlatDim;
5937 return nullptr;
5938 }
5939
5940 return CUDAClusterDimsAttr::Create(Ctx&: Context, X: NewX, Y: NewY, Z: NewZ, CommonInfo: CI);
5941}
5942
5943void Sema::addClusterDimsAttr(Decl *D, const AttributeCommonInfo &CI, Expr *X,
5944 Expr *Y, Expr *Z) {
5945 if (auto *Attr = createClusterDimsAttr(CI, X, Y, Z))
5946 D->addAttr(A: Attr);
5947}
5948
5949void Sema::addNoClusterAttr(Decl *D, const AttributeCommonInfo &CI) {
5950 D->addAttr(A: CUDANoClusterAttr::Create(Ctx&: Context, CommonInfo: CI));
5951}
5952
5953static void handleClusterDimsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5954 const TargetInfo &TTI = S.Context.getTargetInfo();
5955 OffloadArch Arch = StringToOffloadArch(S: TTI.getTargetOpts().CPU);
5956 if ((TTI.getTriple().isNVPTX() && Arch < clang::OffloadArch::SM_90) ||
5957 (TTI.getTriple().isAMDGPU() &&
5958 !TTI.hasFeatureEnabled(Features: TTI.getTargetOpts().FeatureMap, Name: "clusters"))) {
5959 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_cluster_attr_not_supported) << AL;
5960 return;
5961 }
5962
5963 if (!AL.checkAtLeastNumArgs(S, /*Num=*/1) ||
5964 !AL.checkAtMostNumArgs(S, /*Num=*/3))
5965 return;
5966
5967 S.addClusterDimsAttr(D, CI: AL, X: AL.getArgAsExpr(Arg: 0),
5968 Y: AL.getNumArgs() > 1 ? AL.getArgAsExpr(Arg: 1) : nullptr,
5969 Z: AL.getNumArgs() > 2 ? AL.getArgAsExpr(Arg: 2) : nullptr);
5970}
5971
5972static void handleNoClusterAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5973 const TargetInfo &TTI = S.Context.getTargetInfo();
5974 OffloadArch Arch = StringToOffloadArch(S: TTI.getTargetOpts().CPU);
5975 if ((TTI.getTriple().isNVPTX() && Arch < clang::OffloadArch::SM_90) ||
5976 (TTI.getTriple().isAMDGPU() &&
5977 !TTI.hasFeatureEnabled(Features: TTI.getTargetOpts().FeatureMap, Name: "clusters"))) {
5978 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_cluster_attr_not_supported) << AL;
5979 return;
5980 }
5981
5982 S.addNoClusterAttr(D, CI: AL);
5983}
5984
5985static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
5986 const ParsedAttr &AL) {
5987 if (!AL.isArgIdent(Arg: 0)) {
5988 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
5989 << AL << /* arg num = */ 1 << AANT_ArgumentIdentifier;
5990 return;
5991 }
5992
5993 ParamIdx ArgumentIdx;
5994 if (!S.checkFunctionOrMethodParameterIndex(
5995 D, AI: AL, AttrArgNum: 2, IdxExpr: AL.getArgAsExpr(Arg: 1), Idx&: ArgumentIdx,
5996 /*CanIndexImplicitThis=*/false,
5997 /*CanIndexVariadicArguments=*/true))
5998 return;
5999
6000 ParamIdx TypeTagIdx;
6001 if (!S.checkFunctionOrMethodParameterIndex(
6002 D, AI: AL, AttrArgNum: 3, IdxExpr: AL.getArgAsExpr(Arg: 2), Idx&: TypeTagIdx,
6003 /*CanIndexImplicitThis=*/false,
6004 /*CanIndexVariadicArguments=*/true))
6005 return;
6006
6007 bool IsPointer = AL.getAttrName()->getName() == "pointer_with_type_tag";
6008 if (IsPointer) {
6009 // Ensure that buffer has a pointer type.
6010 unsigned ArgumentIdxAST = ArgumentIdx.getASTIndex();
6011 if (ArgumentIdxAST >= getFunctionOrMethodNumParams(D) ||
6012 !getFunctionOrMethodParamType(D, Idx: ArgumentIdxAST)->isPointerType())
6013 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_pointers_only) << AL << 0;
6014 }
6015
6016 D->addAttr(A: ::new (S.Context) ArgumentWithTypeTagAttr(
6017 S.Context, AL, AL.getArgAsIdent(Arg: 0)->getIdentifierInfo(), ArgumentIdx,
6018 TypeTagIdx, IsPointer));
6019}
6020
6021static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
6022 const ParsedAttr &AL) {
6023 if (!AL.isArgIdent(Arg: 0)) {
6024 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
6025 << AL << 1 << AANT_ArgumentIdentifier;
6026 return;
6027 }
6028
6029 if (!AL.checkExactlyNumArgs(S, Num: 1))
6030 return;
6031
6032 if (!isa<VarDecl>(Val: D)) {
6033 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_wrong_decl_type)
6034 << AL << AL.isRegularKeywordAttribute() << ExpectedVariable;
6035 return;
6036 }
6037
6038 IdentifierInfo *PointerKind = AL.getArgAsIdent(Arg: 0)->getIdentifierInfo();
6039 TypeSourceInfo *MatchingCTypeLoc = nullptr;
6040 S.GetTypeFromParser(Ty: AL.getMatchingCType(), TInfo: &MatchingCTypeLoc);
6041 assert(MatchingCTypeLoc && "no type source info for attribute argument");
6042
6043 D->addAttr(A: ::new (S.Context) TypeTagForDatatypeAttr(
6044 S.Context, AL, PointerKind, MatchingCTypeLoc, AL.getLayoutCompatible(),
6045 AL.getMustBeNull()));
6046}
6047
6048static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6049 ParamIdx ArgCount;
6050
6051 if (!S.checkFunctionOrMethodParameterIndex(D, AI: AL, AttrArgNum: 1, IdxExpr: AL.getArgAsExpr(Arg: 0),
6052 Idx&: ArgCount,
6053 CanIndexImplicitThis: true /* CanIndexImplicitThis */))
6054 return;
6055
6056 // ArgCount isn't a parameter index [0;n), it's a count [1;n]
6057 D->addAttr(A: ::new (S.Context)
6058 XRayLogArgsAttr(S.Context, AL, ArgCount.getSourceIndex()));
6059}
6060
6061static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D,
6062 const ParsedAttr &AL) {
6063 if (S.Context.getTargetInfo().getTriple().isOSAIX()) {
6064 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_aix_attr_unsupported) << AL;
6065 return;
6066 }
6067 uint32_t Count = 0, Offset = 0;
6068 StringRef Section;
6069 if (!S.checkUInt32Argument(AI: AL, Expr: AL.getArgAsExpr(Arg: 0), Val&: Count, Idx: 0, StrictlyUnsigned: true))
6070 return;
6071 if (AL.getNumArgs() >= 2) {
6072 Expr *Arg = AL.getArgAsExpr(Arg: 1);
6073 if (!S.checkUInt32Argument(AI: AL, Expr: Arg, Val&: Offset, Idx: 1, StrictlyUnsigned: true))
6074 return;
6075 if (Count < Offset) {
6076 S.Diag(Loc: S.getAttrLoc(CI: AL), DiagID: diag::err_attribute_argument_out_of_range)
6077 << &AL << 0 << Count << Arg->getBeginLoc();
6078 return;
6079 }
6080 }
6081 if (AL.getNumArgs() == 3) {
6082 SourceLocation LiteralLoc;
6083 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 2, Str&: Section, ArgLocation: &LiteralLoc))
6084 return;
6085 if (llvm::Error E = S.isValidSectionSpecifier(SecName: Section)) {
6086 S.Diag(Loc: LiteralLoc,
6087 DiagID: diag::err_attribute_patchable_function_entry_invalid_section)
6088 << toString(E: std::move(E));
6089 return;
6090 }
6091 if (Section.empty()) {
6092 S.Diag(Loc: LiteralLoc,
6093 DiagID: diag::err_attribute_patchable_function_entry_invalid_section)
6094 << "section must not be empty";
6095 return;
6096 }
6097 }
6098 D->addAttr(A: ::new (S.Context) PatchableFunctionEntryAttr(S.Context, AL, Count,
6099 Offset, Section));
6100}
6101
6102static void handleBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6103 if (!AL.isArgIdent(Arg: 0)) {
6104 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
6105 << AL << 1 << AANT_ArgumentIdentifier;
6106 return;
6107 }
6108
6109 IdentifierInfo *Ident = AL.getArgAsIdent(Arg: 0)->getIdentifierInfo();
6110 unsigned BuiltinID = Ident->getBuiltinID();
6111 StringRef AliasName = cast<FunctionDecl>(Val: D)->getIdentifier()->getName();
6112
6113 bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
6114 bool IsARM = S.Context.getTargetInfo().getTriple().isARM();
6115 bool IsRISCV = S.Context.getTargetInfo().getTriple().isRISCV();
6116 bool IsSPIRV = S.Context.getTargetInfo().getTriple().isSPIRV();
6117 bool IsHLSL = S.Context.getLangOpts().HLSL;
6118 if ((IsAArch64 && !S.ARM().SveAliasValid(BuiltinID, AliasName)) ||
6119 (IsARM && !S.ARM().MveAliasValid(BuiltinID, AliasName) &&
6120 !S.ARM().CdeAliasValid(BuiltinID, AliasName)) ||
6121 (IsRISCV && !S.RISCV().isAliasValid(BuiltinID, AliasName)) ||
6122 (!IsAArch64 && !IsARM && !IsRISCV && !IsHLSL && !IsSPIRV)) {
6123 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_builtin_alias) << AL;
6124 return;
6125 }
6126
6127 D->addAttr(A: ::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident));
6128}
6129
6130static void handleNullableTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6131 if (AL.isUsedAsTypeAttr())
6132 return;
6133
6134 if (auto *CRD = dyn_cast<CXXRecordDecl>(Val: D);
6135 !CRD || !(CRD->isClass() || CRD->isStruct())) {
6136 S.Diag(Loc: AL.getRange().getBegin(), DiagID: diag::err_attribute_wrong_decl_type)
6137 << AL << AL.isRegularKeywordAttribute() << ExpectedClass;
6138 return;
6139 }
6140
6141 handleSimpleAttribute<TypeNullableAttr>(S, D, CI: AL);
6142}
6143
6144static void handlePreferredTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6145 if (!AL.hasParsedType()) {
6146 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_wrong_number_arguments) << AL << 1;
6147 return;
6148 }
6149
6150 TypeSourceInfo *ParmTSI = nullptr;
6151 QualType QT = S.GetTypeFromParser(Ty: AL.getTypeArg(), TInfo: &ParmTSI);
6152 assert(ParmTSI && "no type source info for attribute argument");
6153 S.RequireCompleteType(Loc: ParmTSI->getTypeLoc().getBeginLoc(), T: QT,
6154 DiagID: diag::err_incomplete_type);
6155
6156 D->addAttr(A: ::new (S.Context) PreferredTypeAttr(S.Context, AL, ParmTSI));
6157}
6158
6159//===----------------------------------------------------------------------===//
6160// Microsoft specific attribute handlers.
6161//===----------------------------------------------------------------------===//
6162
6163UuidAttr *Sema::mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI,
6164 StringRef UuidAsWritten, MSGuidDecl *GuidDecl) {
6165 if (const auto *UA = D->getAttr<UuidAttr>()) {
6166 if (declaresSameEntity(D1: UA->getGuidDecl(), D2: GuidDecl))
6167 return nullptr;
6168 if (!UA->getGuid().empty()) {
6169 Diag(Loc: UA->getLocation(), DiagID: diag::err_mismatched_uuid);
6170 Diag(Loc: CI.getLoc(), DiagID: diag::note_previous_uuid);
6171 D->dropAttr<UuidAttr>();
6172 }
6173 }
6174
6175 return ::new (Context) UuidAttr(Context, CI, UuidAsWritten, GuidDecl);
6176}
6177
6178static void handleUuidAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6179 if (!S.LangOpts.CPlusPlus) {
6180 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_not_supported_in_lang)
6181 << AL << AttributeLangSupport::C;
6182 return;
6183 }
6184
6185 StringRef OrigStrRef;
6186 SourceLocation LiteralLoc;
6187 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: OrigStrRef, ArgLocation: &LiteralLoc))
6188 return;
6189
6190 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
6191 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former.
6192 StringRef StrRef = OrigStrRef;
6193 if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}')
6194 StrRef = StrRef.drop_front().drop_back();
6195
6196 // Validate GUID length.
6197 if (StrRef.size() != 36) {
6198 S.Diag(Loc: LiteralLoc, DiagID: diag::err_attribute_uuid_malformed_guid);
6199 return;
6200 }
6201
6202 for (unsigned i = 0; i < 36; ++i) {
6203 if (i == 8 || i == 13 || i == 18 || i == 23) {
6204 if (StrRef[i] != '-') {
6205 S.Diag(Loc: LiteralLoc, DiagID: diag::err_attribute_uuid_malformed_guid);
6206 return;
6207 }
6208 } else if (!isHexDigit(c: StrRef[i])) {
6209 S.Diag(Loc: LiteralLoc, DiagID: diag::err_attribute_uuid_malformed_guid);
6210 return;
6211 }
6212 }
6213
6214 // Convert to our parsed format and canonicalize.
6215 MSGuidDecl::Parts Parsed;
6216 StrRef.substr(Start: 0, N: 8).getAsInteger(Radix: 16, Result&: Parsed.Part1);
6217 StrRef.substr(Start: 9, N: 4).getAsInteger(Radix: 16, Result&: Parsed.Part2);
6218 StrRef.substr(Start: 14, N: 4).getAsInteger(Radix: 16, Result&: Parsed.Part3);
6219 for (unsigned i = 0; i != 8; ++i)
6220 StrRef.substr(Start: 19 + 2 * i + (i >= 2 ? 1 : 0), N: 2)
6221 .getAsInteger(Radix: 16, Result&: Parsed.Part4And5[i]);
6222 MSGuidDecl *Guid = S.Context.getMSGuidDecl(Parts: Parsed);
6223
6224 // FIXME: It'd be nice to also emit a fixit removing uuid(...) (and, if it's
6225 // the only thing in the [] list, the [] too), and add an insertion of
6226 // __declspec(uuid(...)). But sadly, neither the SourceLocs of the commas
6227 // separating attributes nor of the [ and the ] are in the AST.
6228 // Cf "SourceLocations of attribute list delimiters - [[ ... , ... ]] etc"
6229 // on cfe-dev.
6230 if (AL.isMicrosoftAttribute()) // Check for [uuid(...)] spelling.
6231 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_atl_uuid_deprecated);
6232
6233 UuidAttr *UA = S.mergeUuidAttr(D, CI: AL, UuidAsWritten: OrigStrRef, GuidDecl: Guid);
6234 if (UA)
6235 D->addAttr(A: UA);
6236}
6237
6238static void handleMSInheritanceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6239 if (!S.LangOpts.CPlusPlus) {
6240 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_not_supported_in_lang)
6241 << AL << AttributeLangSupport::C;
6242 return;
6243 }
6244 MSInheritanceAttr *IA = S.mergeMSInheritanceAttr(
6245 D, CI: AL, /*BestCase=*/true, Model: (MSInheritanceModel)AL.getSemanticSpelling());
6246 if (IA) {
6247 D->addAttr(A: IA);
6248 S.Consumer.AssignInheritanceModel(RD: cast<CXXRecordDecl>(Val: D));
6249 }
6250}
6251
6252static void handleDeclspecThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6253 const auto *VD = cast<VarDecl>(Val: D);
6254 if (!S.Context.getTargetInfo().isTLSSupported()) {
6255 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_thread_unsupported);
6256 return;
6257 }
6258 if (VD->getTSCSpec() != TSCS_unspecified) {
6259 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_declspec_thread_on_thread_variable);
6260 return;
6261 }
6262 if (VD->hasLocalStorage()) {
6263 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_thread_non_global) << "__declspec(thread)";
6264 return;
6265 }
6266 D->addAttr(A: ::new (S.Context) ThreadAttr(S.Context, AL));
6267}
6268
6269static void handleMSConstexprAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6270 if (!S.getLangOpts().isCompatibleWithMSVC(MajorVersion: LangOptions::MSVC2022_3)) {
6271 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_unknown_attribute_ignored)
6272 << AL << AL.getRange();
6273 return;
6274 }
6275 auto *FD = cast<FunctionDecl>(Val: D);
6276 if (FD->isConstexprSpecified() || FD->isConsteval()) {
6277 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_ms_constexpr_cannot_be_applied)
6278 << FD->isConsteval() << FD;
6279 return;
6280 }
6281 if (auto *MD = dyn_cast<CXXMethodDecl>(Val: FD)) {
6282 if (!S.getLangOpts().CPlusPlus20 && MD->isVirtual()) {
6283 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_ms_constexpr_cannot_be_applied)
6284 << /*virtual*/ 2 << MD;
6285 return;
6286 }
6287 }
6288 D->addAttr(A: ::new (S.Context) MSConstexprAttr(S.Context, AL));
6289}
6290
6291static void handleMSStructAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6292 if (const auto *First = D->getAttr<GCCStructAttr>()) {
6293 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attributes_are_not_compatible)
6294 << AL << First << 0;
6295 S.Diag(Loc: First->getLocation(), DiagID: diag::note_conflicting_attribute);
6296 return;
6297 }
6298 if (const auto *Preexisting = D->getAttr<MSStructAttr>()) {
6299 if (Preexisting->isImplicit())
6300 D->dropAttr<MSStructAttr>();
6301 }
6302
6303 D->addAttr(A: ::new (S.Context) MSStructAttr(S.Context, AL));
6304}
6305
6306static void handleGCCStructAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6307 if (const auto *First = D->getAttr<MSStructAttr>()) {
6308 if (First->isImplicit()) {
6309 D->dropAttr<MSStructAttr>();
6310 } else {
6311 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attributes_are_not_compatible)
6312 << AL << First << 0;
6313 S.Diag(Loc: First->getLocation(), DiagID: diag::note_conflicting_attribute);
6314 return;
6315 }
6316 }
6317
6318 D->addAttr(A: ::new (S.Context) GCCStructAttr(S.Context, AL));
6319}
6320
6321static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6322 SmallVector<StringRef, 4> Tags;
6323 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
6324 StringRef Tag;
6325 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: Tag))
6326 return;
6327 Tags.push_back(Elt: Tag);
6328 }
6329
6330 if (const auto *NS = dyn_cast<NamespaceDecl>(Val: D)) {
6331 if (!NS->isInline()) {
6332 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attr_abi_tag_namespace) << 0;
6333 return;
6334 }
6335 if (NS->isAnonymousNamespace()) {
6336 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attr_abi_tag_namespace) << 1;
6337 return;
6338 }
6339 if (AL.getNumArgs() == 0)
6340 Tags.push_back(Elt: NS->getName());
6341 } else if (!AL.checkAtLeastNumArgs(S, Num: 1))
6342 return;
6343
6344 // Store tags sorted and without duplicates.
6345 llvm::sort(C&: Tags);
6346 Tags.erase(CS: llvm::unique(R&: Tags), CE: Tags.end());
6347
6348 D->addAttr(A: ::new (S.Context)
6349 AbiTagAttr(S.Context, AL, Tags.data(), Tags.size()));
6350}
6351
6352static bool hasBTFDeclTagAttr(Decl *D, StringRef Tag) {
6353 for (const auto *I : D->specific_attrs<BTFDeclTagAttr>()) {
6354 if (I->getBTFDeclTag() == Tag)
6355 return true;
6356 }
6357 return false;
6358}
6359
6360static void handleBTFDeclTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6361 StringRef Str;
6362 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str))
6363 return;
6364 if (hasBTFDeclTagAttr(D, Tag: Str))
6365 return;
6366
6367 D->addAttr(A: ::new (S.Context) BTFDeclTagAttr(S.Context, AL, Str));
6368}
6369
6370BTFDeclTagAttr *Sema::mergeBTFDeclTagAttr(Decl *D, const BTFDeclTagAttr &AL) {
6371 if (hasBTFDeclTagAttr(D, Tag: AL.getBTFDeclTag()))
6372 return nullptr;
6373 return ::new (Context) BTFDeclTagAttr(Context, AL, AL.getBTFDeclTag());
6374}
6375
6376static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6377 // Dispatch the interrupt attribute based on the current target.
6378 switch (S.Context.getTargetInfo().getTriple().getArch()) {
6379 case llvm::Triple::msp430:
6380 S.MSP430().handleInterruptAttr(D, AL);
6381 break;
6382 case llvm::Triple::mipsel:
6383 case llvm::Triple::mips:
6384 S.MIPS().handleInterruptAttr(D, AL);
6385 break;
6386 case llvm::Triple::m68k:
6387 S.M68k().handleInterruptAttr(D, AL);
6388 break;
6389 case llvm::Triple::x86:
6390 case llvm::Triple::x86_64:
6391 S.X86().handleAnyInterruptAttr(D, AL);
6392 break;
6393 case llvm::Triple::avr:
6394 S.AVR().handleInterruptAttr(D, AL);
6395 break;
6396 case llvm::Triple::riscv32:
6397 case llvm::Triple::riscv64:
6398 case llvm::Triple::riscv32be:
6399 case llvm::Triple::riscv64be:
6400 S.RISCV().handleInterruptAttr(D, AL);
6401 break;
6402 default:
6403 S.ARM().handleInterruptAttr(D, AL);
6404 break;
6405 }
6406}
6407
6408static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL) {
6409 uint32_t Version;
6410 Expr *VersionExpr = AL.getArgAsExpr(Arg: 0);
6411 if (!S.checkUInt32Argument(AI: AL, Expr: AL.getArgAsExpr(Arg: 0), Val&: Version))
6412 return;
6413
6414 // TODO: Investigate what happens with the next major version of MSVC.
6415 if (Version != LangOptions::MSVC2015 / 100) {
6416 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_out_of_bounds)
6417 << AL << Version << VersionExpr->getSourceRange();
6418 return;
6419 }
6420
6421 // The attribute expects a "major" version number like 19, but new versions of
6422 // MSVC have moved to updating the "minor", or less significant numbers, so we
6423 // have to multiply by 100 now.
6424 Version *= 100;
6425
6426 D->addAttr(A: ::new (S.Context) LayoutVersionAttr(S.Context, AL, Version));
6427}
6428
6429DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D,
6430 const AttributeCommonInfo &CI) {
6431 if (D->hasAttr<DLLExportAttr>()) {
6432 Diag(Loc: CI.getLoc(), DiagID: diag::warn_attribute_ignored) << "'dllimport'";
6433 return nullptr;
6434 }
6435
6436 if (D->hasAttr<DLLImportAttr>())
6437 return nullptr;
6438
6439 return ::new (Context) DLLImportAttr(Context, CI);
6440}
6441
6442DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D,
6443 const AttributeCommonInfo &CI) {
6444 if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
6445 Diag(Loc: Import->getLocation(), DiagID: diag::warn_attribute_ignored) << Import;
6446 D->dropAttr<DLLImportAttr>();
6447 }
6448
6449 if (D->hasAttr<DLLExportAttr>())
6450 return nullptr;
6451
6452 return ::new (Context) DLLExportAttr(Context, CI);
6453}
6454
6455static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) {
6456 if (isa<ClassTemplatePartialSpecializationDecl>(Val: D) &&
6457 (S.Context.getTargetInfo().shouldDLLImportComdatSymbols())) {
6458 S.Diag(Loc: A.getRange().getBegin(), DiagID: diag::warn_attribute_ignored) << A;
6459 return;
6460 }
6461
6462 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
6463 if (FD->isInlined() && A.getKind() == ParsedAttr::AT_DLLImport &&
6464 !(S.Context.getTargetInfo().shouldDLLImportComdatSymbols())) {
6465 // MinGW doesn't allow dllimport on inline functions.
6466 S.Diag(Loc: A.getRange().getBegin(), DiagID: diag::warn_attribute_ignored_on_inline)
6467 << A;
6468 return;
6469 }
6470 }
6471
6472 if (const auto *MD = dyn_cast<CXXMethodDecl>(Val: D)) {
6473 if ((S.Context.getTargetInfo().shouldDLLImportComdatSymbols()) &&
6474 MD->getParent()->isLambda()) {
6475 S.Diag(Loc: A.getRange().getBegin(), DiagID: diag::err_attribute_dll_lambda) << A;
6476 return;
6477 }
6478 }
6479
6480 if (auto *EA = D->getAttr<ExcludeFromExplicitInstantiationAttr>()) {
6481 S.Diag(Loc: A.getRange().getBegin(),
6482 DiagID: diag::warn_dllattr_ignored_exclusion_takes_precedence)
6483 << A << EA;
6484 return;
6485 }
6486
6487 Attr *NewAttr = A.getKind() == ParsedAttr::AT_DLLExport
6488 ? (Attr *)S.mergeDLLExportAttr(D, CI: A)
6489 : (Attr *)S.mergeDLLImportAttr(D, CI: A);
6490 if (NewAttr)
6491 D->addAttr(A: NewAttr);
6492}
6493
6494MSInheritanceAttr *
6495Sema::mergeMSInheritanceAttr(Decl *D, const AttributeCommonInfo &CI,
6496 bool BestCase,
6497 MSInheritanceModel Model) {
6498 if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) {
6499 if (IA->getInheritanceModel() == Model)
6500 return nullptr;
6501 Diag(Loc: IA->getLocation(), DiagID: diag::err_mismatched_ms_inheritance)
6502 << 1 /*previous declaration*/;
6503 Diag(Loc: CI.getLoc(), DiagID: diag::note_previous_ms_inheritance);
6504 D->dropAttr<MSInheritanceAttr>();
6505 }
6506
6507 auto *RD = cast<CXXRecordDecl>(Val: D);
6508 if (RD->hasDefinition()) {
6509 if (checkMSInheritanceAttrOnDefinition(RD, Range: CI.getRange(), BestCase,
6510 ExplicitModel: Model)) {
6511 return nullptr;
6512 }
6513 } else {
6514 if (isa<ClassTemplatePartialSpecializationDecl>(Val: RD)) {
6515 Diag(Loc: CI.getLoc(), DiagID: diag::warn_ignored_ms_inheritance)
6516 << 1 /*partial specialization*/;
6517 return nullptr;
6518 }
6519 if (RD->getDescribedClassTemplate()) {
6520 Diag(Loc: CI.getLoc(), DiagID: diag::warn_ignored_ms_inheritance)
6521 << 0 /*primary template*/;
6522 return nullptr;
6523 }
6524 }
6525
6526 return ::new (Context) MSInheritanceAttr(Context, CI, BestCase);
6527}
6528
6529static void handleCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6530 // The capability attributes take a single string parameter for the name of
6531 // the capability they represent. The lockable attribute does not take any
6532 // parameters. However, semantically, both attributes represent the same
6533 // concept, and so they use the same semantic attribute. Eventually, the
6534 // lockable attribute will be removed.
6535 //
6536 // For backward compatibility, any capability which has no specified string
6537 // literal will be considered a "mutex."
6538 StringRef N("mutex");
6539 SourceLocation LiteralLoc;
6540 if (AL.getKind() == ParsedAttr::AT_Capability &&
6541 !S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: N, ArgLocation: &LiteralLoc))
6542 return;
6543
6544 D->addAttr(A: ::new (S.Context) CapabilityAttr(S.Context, AL, N));
6545}
6546
6547static void handleReentrantCapabilityAttr(Sema &S, Decl *D,
6548 const ParsedAttr &AL) {
6549 // Do not permit 'reentrant_capability' without 'capability(..)'. Note that
6550 // the check here requires 'capability' to be before 'reentrant_capability'.
6551 // This helps enforce a canonical style. Also avoids placing an additional
6552 // branch into ProcessDeclAttributeList().
6553 if (!D->hasAttr<CapabilityAttr>()) {
6554 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_thread_attribute_requires_preceded)
6555 << AL << cast<NamedDecl>(Val: D) << "'capability'";
6556 return;
6557 }
6558
6559 D->addAttr(A: ::new (S.Context) ReentrantCapabilityAttr(S.Context, AL));
6560}
6561
6562static void handleAssertCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6563 SmallVector<Expr*, 1> Args;
6564 if (!checkLockFunAttrCommon(S, D, AL, Args))
6565 return;
6566
6567 D->addAttr(A: ::new (S.Context)
6568 AssertCapabilityAttr(S.Context, AL, Args.data(), Args.size()));
6569}
6570
6571static void handleAcquireCapabilityAttr(Sema &S, Decl *D,
6572 const ParsedAttr &AL) {
6573 if (const auto *ParmDecl = dyn_cast<ParmVarDecl>(Val: D);
6574 ParmDecl && !checkFunParamsAreScopedLockable(S, ParamDecl: ParmDecl, AL))
6575 return;
6576
6577 SmallVector<Expr*, 1> Args;
6578 if (!checkLockFunAttrCommon(S, D, AL, Args))
6579 return;
6580
6581 D->addAttr(A: ::new (S.Context) AcquireCapabilityAttr(S.Context, AL, Args.data(),
6582 Args.size()));
6583}
6584
6585static void handleTryAcquireCapabilityAttr(Sema &S, Decl *D,
6586 const ParsedAttr &AL) {
6587 SmallVector<Expr*, 2> Args;
6588 if (!checkTryLockFunAttrCommon(S, D, AL, Args))
6589 return;
6590
6591 D->addAttr(A: ::new (S.Context) TryAcquireCapabilityAttr(
6592 S.Context, AL, AL.getArgAsExpr(Arg: 0), Args.data(), Args.size()));
6593}
6594
6595static void handleReleaseCapabilityAttr(Sema &S, Decl *D,
6596 const ParsedAttr &AL) {
6597 if (const auto *ParmDecl = dyn_cast<ParmVarDecl>(Val: D);
6598 ParmDecl && !checkFunParamsAreScopedLockable(S, ParamDecl: ParmDecl, AL))
6599 return;
6600 // Check that all arguments are lockable objects.
6601 SmallVector<Expr *, 1> Args;
6602 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, Sidx: 0, ParamIdxOk: true);
6603
6604 D->addAttr(A: ::new (S.Context) ReleaseCapabilityAttr(S.Context, AL, Args.data(),
6605 Args.size()));
6606}
6607
6608static void handleRequiresCapabilityAttr(Sema &S, Decl *D,
6609 const ParsedAttr &AL) {
6610 if (const auto *ParmDecl = dyn_cast<ParmVarDecl>(Val: D);
6611 ParmDecl && !checkFunParamsAreScopedLockable(S, ParamDecl: ParmDecl, AL))
6612 return;
6613
6614 if (!AL.checkAtLeastNumArgs(S, Num: 1))
6615 return;
6616
6617 // check that all arguments are lockable objects
6618 SmallVector<Expr*, 1> Args;
6619 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
6620 if (Args.empty())
6621 return;
6622
6623 RequiresCapabilityAttr *RCA = ::new (S.Context)
6624 RequiresCapabilityAttr(S.Context, AL, Args.data(), Args.size());
6625
6626 D->addAttr(A: RCA);
6627}
6628
6629static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6630 if (const auto *NSD = dyn_cast<NamespaceDecl>(Val: D)) {
6631 if (NSD->isAnonymousNamespace()) {
6632 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_deprecated_anonymous_namespace);
6633 // Do not want to attach the attribute to the namespace because that will
6634 // cause confusing diagnostic reports for uses of declarations within the
6635 // namespace.
6636 return;
6637 }
6638 } else if (isa<UsingDecl, UnresolvedUsingTypenameDecl,
6639 UnresolvedUsingValueDecl>(Val: D)) {
6640 S.Diag(Loc: AL.getRange().getBegin(), DiagID: diag::warn_deprecated_ignored_on_using)
6641 << AL;
6642 return;
6643 }
6644
6645 // Handle the cases where the attribute has a text message.
6646 StringRef Str, Replacement;
6647 if (AL.isArgExpr(Arg: 0) && AL.getArgAsExpr(Arg: 0) &&
6648 !S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str))
6649 return;
6650
6651 // Support a single optional message only for Declspec and [[]] spellings.
6652 if (AL.isDeclspecAttribute() || AL.isStandardAttributeSyntax())
6653 AL.checkAtMostNumArgs(S, Num: 1);
6654 else if (AL.isArgExpr(Arg: 1) && AL.getArgAsExpr(Arg: 1) &&
6655 !S.checkStringLiteralArgumentAttr(AL, ArgNum: 1, Str&: Replacement))
6656 return;
6657
6658 if (!S.getLangOpts().CPlusPlus14 && AL.isCXX11Attribute() && !AL.isGNUScope())
6659 S.Diag(Loc: AL.getLoc(), DiagID: diag::ext_cxx14_attr) << AL;
6660
6661 D->addAttr(A: ::new (S.Context) DeprecatedAttr(S.Context, AL, Str, Replacement));
6662}
6663
6664static bool isGlobalVar(const Decl *D) {
6665 if (const auto *S = dyn_cast<VarDecl>(Val: D))
6666 return S->hasGlobalStorage();
6667 return false;
6668}
6669
6670static bool isSanitizerAttributeAllowedOnGlobals(StringRef Sanitizer) {
6671 return Sanitizer == "address" || Sanitizer == "hwaddress" ||
6672 Sanitizer == "memtag";
6673}
6674
6675static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6676 if (!AL.checkAtLeastNumArgs(S, Num: 1))
6677 return;
6678
6679 std::vector<StringRef> Sanitizers;
6680
6681 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
6682 StringRef SanitizerName;
6683 SourceLocation LiteralLoc;
6684
6685 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: SanitizerName, ArgLocation: &LiteralLoc))
6686 return;
6687
6688 if (parseSanitizerValue(Value: SanitizerName, /*AllowGroups=*/true) ==
6689 SanitizerMask() &&
6690 SanitizerName != "coverage")
6691 S.Diag(Loc: LiteralLoc, DiagID: diag::warn_unknown_sanitizer_ignored) << SanitizerName;
6692 else if (isGlobalVar(D) && !isSanitizerAttributeAllowedOnGlobals(Sanitizer: SanitizerName))
6693 S.Diag(Loc: D->getLocation(), DiagID: diag::warn_attribute_type_not_supported_global)
6694 << AL << SanitizerName;
6695 Sanitizers.push_back(x: SanitizerName);
6696 }
6697
6698 D->addAttr(A: ::new (S.Context) NoSanitizeAttr(S.Context, AL, Sanitizers.data(),
6699 Sanitizers.size()));
6700}
6701
6702static AttributeCommonInfo
6703getNoSanitizeAttrInfo(const ParsedAttr &NoSanitizeSpecificAttr) {
6704 // FIXME: Rather than create a NoSanitizeSpecificAttr, this creates a
6705 // NoSanitizeAttr object; but we need to calculate the correct spelling list
6706 // index rather than incorrectly assume the index for NoSanitizeSpecificAttr
6707 // has the same spellings as the index for NoSanitizeAttr. We don't have a
6708 // general way to "translate" between the two, so this hack attempts to work
6709 // around the issue with hard-coded indices. This is critical for calling
6710 // getSpelling() or prettyPrint() on the resulting semantic attribute object
6711 // without failing assertions.
6712 unsigned TranslatedSpellingIndex = 0;
6713 if (NoSanitizeSpecificAttr.isStandardAttributeSyntax())
6714 TranslatedSpellingIndex = 1;
6715
6716 AttributeCommonInfo Info = NoSanitizeSpecificAttr;
6717 Info.setAttributeSpellingListIndex(TranslatedSpellingIndex);
6718 return Info;
6719}
6720
6721static void handleNoSanitizeAddressAttr(Sema &S, Decl *D,
6722 const ParsedAttr &AL) {
6723 StringRef SanitizerName = "address";
6724 AttributeCommonInfo Info = getNoSanitizeAttrInfo(NoSanitizeSpecificAttr: AL);
6725 D->addAttr(A: ::new (S.Context)
6726 NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
6727}
6728
6729static void handleNoSanitizeThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6730 StringRef SanitizerName = "thread";
6731 AttributeCommonInfo Info = getNoSanitizeAttrInfo(NoSanitizeSpecificAttr: AL);
6732 D->addAttr(A: ::new (S.Context)
6733 NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
6734}
6735
6736static void handleNoSanitizeMemoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6737 StringRef SanitizerName = "memory";
6738 AttributeCommonInfo Info = getNoSanitizeAttrInfo(NoSanitizeSpecificAttr: AL);
6739 D->addAttr(A: ::new (S.Context)
6740 NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
6741}
6742
6743static void handleInternalLinkageAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6744 if (InternalLinkageAttr *Internal = S.mergeInternalLinkageAttr(D, AL))
6745 D->addAttr(A: Internal);
6746}
6747
6748static void handleZeroCallUsedRegsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6749 // Check that the argument is a string literal.
6750 StringRef KindStr;
6751 SourceLocation LiteralLoc;
6752 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: KindStr, ArgLocation: &LiteralLoc))
6753 return;
6754
6755 ZeroCallUsedRegsAttr::ZeroCallUsedRegsKind Kind;
6756 if (!ZeroCallUsedRegsAttr::ConvertStrToZeroCallUsedRegsKind(Val: KindStr, Out&: Kind)) {
6757 S.Diag(Loc: LiteralLoc, DiagID: diag::warn_attribute_type_not_supported)
6758 << AL << KindStr;
6759 return;
6760 }
6761
6762 D->dropAttr<ZeroCallUsedRegsAttr>();
6763 D->addAttr(A: ZeroCallUsedRegsAttr::Create(Ctx&: S.Context, ZeroCallUsedRegs: Kind, CommonInfo: AL));
6764}
6765
6766static void handleNoPFPAttrField(Sema &S, Decl *D, const ParsedAttr &AL) {
6767 D->addAttr(A: NoFieldProtectionAttr::Create(Ctx&: S.Context, CommonInfo: AL));
6768}
6769
6770static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL) {
6771 auto *FD = dyn_cast<FieldDecl>(Val: D);
6772 assert(FD);
6773
6774 auto *CountExpr = AL.getArgAsExpr(Arg: 0);
6775 if (!CountExpr)
6776 return;
6777
6778 bool CountInBytes;
6779 bool OrNull;
6780 switch (AL.getKind()) {
6781 case ParsedAttr::AT_CountedBy:
6782 CountInBytes = false;
6783 OrNull = false;
6784 break;
6785 case ParsedAttr::AT_CountedByOrNull:
6786 CountInBytes = false;
6787 OrNull = true;
6788 break;
6789 case ParsedAttr::AT_SizedBy:
6790 CountInBytes = true;
6791 OrNull = false;
6792 break;
6793 case ParsedAttr::AT_SizedByOrNull:
6794 CountInBytes = true;
6795 OrNull = true;
6796 break;
6797 default:
6798 llvm_unreachable("unexpected counted_by family attribute");
6799 }
6800
6801 if (S.CheckCountedByAttrOnField(FD, E: CountExpr, CountInBytes, OrNull))
6802 return;
6803
6804 QualType CAT = S.BuildCountAttributedArrayOrPointerType(
6805 WrappedTy: FD->getType(), CountExpr, CountInBytes, OrNull);
6806 FD->setType(CAT);
6807}
6808
6809static void handleFunctionReturnThunksAttr(Sema &S, Decl *D,
6810 const ParsedAttr &AL) {
6811 StringRef KindStr;
6812 SourceLocation LiteralLoc;
6813 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: KindStr, ArgLocation: &LiteralLoc))
6814 return;
6815
6816 FunctionReturnThunksAttr::Kind Kind;
6817 if (!FunctionReturnThunksAttr::ConvertStrToKind(Val: KindStr, Out&: Kind)) {
6818 S.Diag(Loc: LiteralLoc, DiagID: diag::warn_attribute_type_not_supported)
6819 << AL << KindStr;
6820 return;
6821 }
6822 // FIXME: it would be good to better handle attribute merging rather than
6823 // silently replacing the existing attribute, so long as it does not break
6824 // the expected codegen tests.
6825 D->dropAttr<FunctionReturnThunksAttr>();
6826 D->addAttr(A: FunctionReturnThunksAttr::Create(Ctx&: S.Context, ThunkType: Kind, CommonInfo: AL));
6827}
6828
6829static void handleAvailableOnlyInDefaultEvalMethod(Sema &S, Decl *D,
6830 const ParsedAttr &AL) {
6831 assert(isa<TypedefNameDecl>(D) && "This attribute only applies to a typedef");
6832 handleSimpleAttribute<AvailableOnlyInDefaultEvalMethodAttr>(S, D, CI: AL);
6833}
6834
6835static void handleNoMergeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6836 auto *VDecl = dyn_cast<VarDecl>(Val: D);
6837 if (VDecl && !VDecl->isFunctionPointerType()) {
6838 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_ignored_non_function_pointer)
6839 << AL << VDecl;
6840 return;
6841 }
6842 D->addAttr(A: NoMergeAttr::Create(Ctx&: S.Context, CommonInfo: AL));
6843}
6844
6845static void handleNoUniqueAddressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6846 D->addAttr(A: NoUniqueAddressAttr::Create(Ctx&: S.Context, CommonInfo: AL));
6847}
6848
6849static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A) {
6850 if (!cast<VarDecl>(Val: D)->hasGlobalStorage()) {
6851 S.Diag(Loc: D->getLocation(), DiagID: diag::err_destroy_attr_on_non_static_var)
6852 << (A.getKind() == ParsedAttr::AT_AlwaysDestroy);
6853 return;
6854 }
6855
6856 if (A.getKind() == ParsedAttr::AT_AlwaysDestroy)
6857 handleSimpleAttribute<AlwaysDestroyAttr>(S, D, CI: A);
6858 else
6859 handleSimpleAttribute<NoDestroyAttr>(S, D, CI: A);
6860}
6861
6862static void handleUninitializedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6863 assert(cast<VarDecl>(D)->getStorageDuration() == SD_Automatic &&
6864 "uninitialized is only valid on automatic duration variables");
6865 D->addAttr(A: ::new (S.Context) UninitializedAttr(S.Context, AL));
6866}
6867
6868static void handleMIGServerRoutineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6869 // Check that the return type is a `typedef int kern_return_t` or a typedef
6870 // around it, because otherwise MIG convention checks make no sense.
6871 // BlockDecl doesn't store a return type, so it's annoying to check,
6872 // so let's skip it for now.
6873 if (!isa<BlockDecl>(Val: D)) {
6874 QualType T = getFunctionOrMethodResultType(D);
6875 bool IsKernReturnT = false;
6876 while (const auto *TT = T->getAs<TypedefType>()) {
6877 IsKernReturnT = (TT->getDecl()->getName() == "kern_return_t");
6878 T = TT->desugar();
6879 }
6880 if (!IsKernReturnT || T.getCanonicalType() != S.getASTContext().IntTy) {
6881 S.Diag(Loc: D->getBeginLoc(),
6882 DiagID: diag::warn_mig_server_routine_does_not_return_kern_return_t);
6883 return;
6884 }
6885 }
6886
6887 handleSimpleAttribute<MIGServerRoutineAttr>(S, D, CI: AL);
6888}
6889
6890static void handleMSAllocatorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6891 // Warn if the return type is not a pointer or reference type.
6892 if (auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
6893 QualType RetTy = FD->getReturnType();
6894 if (!RetTy->isPointerOrReferenceType()) {
6895 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_declspec_allocator_nonpointer)
6896 << AL.getRange() << RetTy;
6897 return;
6898 }
6899 }
6900
6901 handleSimpleAttribute<MSAllocatorAttr>(S, D, CI: AL);
6902}
6903
6904static void handleAcquireHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6905 if (AL.isUsedAsTypeAttr())
6906 return;
6907 // Warn if the parameter is definitely not an output parameter.
6908 if (const auto *PVD = dyn_cast<ParmVarDecl>(Val: D)) {
6909 if (PVD->getType()->isIntegerType()) {
6910 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_output_parameter)
6911 << AL.getRange();
6912 return;
6913 }
6914 }
6915 StringRef Argument;
6916 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: Argument))
6917 return;
6918 D->addAttr(A: AcquireHandleAttr::Create(Ctx&: S.Context, HandleType: Argument, CommonInfo: AL));
6919}
6920
6921template<typename Attr>
6922static void handleHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6923 StringRef Argument;
6924 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: Argument))
6925 return;
6926 D->addAttr(A: Attr::Create(S.Context, Argument, AL));
6927}
6928
6929template<typename Attr>
6930static void handleUnsafeBufferUsage(Sema &S, Decl *D, const ParsedAttr &AL) {
6931 D->addAttr(A: Attr::Create(S.Context, AL));
6932}
6933
6934static void handleCFGuardAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6935 // The guard attribute takes a single identifier argument.
6936
6937 if (!AL.isArgIdent(Arg: 0)) {
6938 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
6939 << AL << AANT_ArgumentIdentifier;
6940 return;
6941 }
6942
6943 CFGuardAttr::GuardArg Arg;
6944 IdentifierInfo *II = AL.getArgAsIdent(Arg: 0)->getIdentifierInfo();
6945 if (!CFGuardAttr::ConvertStrToGuardArg(Val: II->getName(), Out&: Arg)) {
6946 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_type_not_supported) << AL << II;
6947 return;
6948 }
6949
6950 D->addAttr(A: ::new (S.Context) CFGuardAttr(S.Context, AL, Arg));
6951}
6952
6953
6954template <typename AttrTy>
6955static const AttrTy *findEnforceTCBAttrByName(Decl *D, StringRef Name) {
6956 auto Attrs = D->specific_attrs<AttrTy>();
6957 auto I = llvm::find_if(Attrs,
6958 [Name](const AttrTy *A) {
6959 return A->getTCBName() == Name;
6960 });
6961 return I == Attrs.end() ? nullptr : *I;
6962}
6963
6964template <typename AttrTy, typename ConflictingAttrTy>
6965static void handleEnforceTCBAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6966 StringRef Argument;
6967 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: Argument))
6968 return;
6969
6970 // A function cannot be have both regular and leaf membership in the same TCB.
6971 if (const ConflictingAttrTy *ConflictingAttr =
6972 findEnforceTCBAttrByName<ConflictingAttrTy>(D, Argument)) {
6973 // We could attach a note to the other attribute but in this case
6974 // there's no need given how the two are very close to each other.
6975 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_tcb_conflicting_attributes)
6976 << AL.getAttrName()->getName() << ConflictingAttr->getAttrName()->getName()
6977 << Argument;
6978
6979 // Error recovery: drop the non-leaf attribute so that to suppress
6980 // all future warnings caused by erroneous attributes. The leaf attribute
6981 // needs to be kept because it can only suppresses warnings, not cause them.
6982 D->dropAttr<EnforceTCBAttr>();
6983 return;
6984 }
6985
6986 D->addAttr(A: AttrTy::Create(S.Context, Argument, AL));
6987}
6988
6989template <typename AttrTy, typename ConflictingAttrTy>
6990static AttrTy *mergeEnforceTCBAttrImpl(Sema &S, Decl *D, const AttrTy &AL) {
6991 // Check if the new redeclaration has different leaf-ness in the same TCB.
6992 StringRef TCBName = AL.getTCBName();
6993 if (const ConflictingAttrTy *ConflictingAttr =
6994 findEnforceTCBAttrByName<ConflictingAttrTy>(D, TCBName)) {
6995 S.Diag(ConflictingAttr->getLoc(), diag::err_tcb_conflicting_attributes)
6996 << ConflictingAttr->getAttrName()->getName()
6997 << AL.getAttrName()->getName() << TCBName;
6998
6999 // Add a note so that the user could easily find the conflicting attribute.
7000 S.Diag(AL.getLoc(), diag::note_conflicting_attribute);
7001
7002 // More error recovery.
7003 D->dropAttr<EnforceTCBAttr>();
7004 return nullptr;
7005 }
7006
7007 ASTContext &Context = S.getASTContext();
7008 return ::new(Context) AttrTy(Context, AL, AL.getTCBName());
7009}
7010
7011EnforceTCBAttr *Sema::mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL) {
7012 return mergeEnforceTCBAttrImpl<EnforceTCBAttr, EnforceTCBLeafAttr>(
7013 S&: *this, D, AL);
7014}
7015
7016EnforceTCBLeafAttr *Sema::mergeEnforceTCBLeafAttr(
7017 Decl *D, const EnforceTCBLeafAttr &AL) {
7018 return mergeEnforceTCBAttrImpl<EnforceTCBLeafAttr, EnforceTCBAttr>(
7019 S&: *this, D, AL);
7020}
7021
7022static void handleVTablePointerAuthentication(Sema &S, Decl *D,
7023 const ParsedAttr &AL) {
7024 CXXRecordDecl *Decl = cast<CXXRecordDecl>(Val: D);
7025 const uint32_t NumArgs = AL.getNumArgs();
7026 if (NumArgs > 4) {
7027 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_too_many_arguments) << AL << 4;
7028 AL.setInvalid();
7029 }
7030
7031 if (NumArgs == 0) {
7032 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_too_few_arguments) << AL;
7033 AL.setInvalid();
7034 return;
7035 }
7036
7037 if (D->getAttr<VTablePointerAuthenticationAttr>()) {
7038 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_duplicated_vtable_pointer_auth) << Decl;
7039 AL.setInvalid();
7040 }
7041
7042 auto KeyType = VTablePointerAuthenticationAttr::VPtrAuthKeyType::DefaultKey;
7043 if (AL.isArgIdent(Arg: 0)) {
7044 IdentifierLoc *IL = AL.getArgAsIdent(Arg: 0);
7045 if (!VTablePointerAuthenticationAttr::ConvertStrToVPtrAuthKeyType(
7046 Val: IL->getIdentifierInfo()->getName(), Out&: KeyType)) {
7047 S.Diag(Loc: IL->getLoc(), DiagID: diag::err_invalid_authentication_key)
7048 << IL->getIdentifierInfo();
7049 AL.setInvalid();
7050 }
7051 if (KeyType == VTablePointerAuthenticationAttr::DefaultKey &&
7052 !S.getLangOpts().PointerAuthCalls) {
7053 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_no_default_vtable_pointer_auth) << 0;
7054 AL.setInvalid();
7055 }
7056 } else {
7057 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
7058 << AL << AANT_ArgumentIdentifier;
7059 return;
7060 }
7061
7062 auto AddressDiversityMode = VTablePointerAuthenticationAttr::
7063 AddressDiscriminationMode::DefaultAddressDiscrimination;
7064 if (AL.getNumArgs() > 1) {
7065 if (AL.isArgIdent(Arg: 1)) {
7066 IdentifierLoc *IL = AL.getArgAsIdent(Arg: 1);
7067 if (!VTablePointerAuthenticationAttr::
7068 ConvertStrToAddressDiscriminationMode(
7069 Val: IL->getIdentifierInfo()->getName(), Out&: AddressDiversityMode)) {
7070 S.Diag(Loc: IL->getLoc(), DiagID: diag::err_invalid_address_discrimination)
7071 << IL->getIdentifierInfo();
7072 AL.setInvalid();
7073 }
7074 if (AddressDiversityMode ==
7075 VTablePointerAuthenticationAttr::DefaultAddressDiscrimination &&
7076 !S.getLangOpts().PointerAuthCalls) {
7077 S.Diag(Loc: IL->getLoc(), DiagID: diag::err_no_default_vtable_pointer_auth) << 1;
7078 AL.setInvalid();
7079 }
7080 } else {
7081 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
7082 << AL << AANT_ArgumentIdentifier;
7083 }
7084 }
7085
7086 auto ED = VTablePointerAuthenticationAttr::ExtraDiscrimination::
7087 DefaultExtraDiscrimination;
7088 if (AL.getNumArgs() > 2) {
7089 if (AL.isArgIdent(Arg: 2)) {
7090 IdentifierLoc *IL = AL.getArgAsIdent(Arg: 2);
7091 if (!VTablePointerAuthenticationAttr::ConvertStrToExtraDiscrimination(
7092 Val: IL->getIdentifierInfo()->getName(), Out&: ED)) {
7093 S.Diag(Loc: IL->getLoc(), DiagID: diag::err_invalid_extra_discrimination)
7094 << IL->getIdentifierInfo();
7095 AL.setInvalid();
7096 }
7097 if (ED == VTablePointerAuthenticationAttr::DefaultExtraDiscrimination &&
7098 !S.getLangOpts().PointerAuthCalls) {
7099 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_no_default_vtable_pointer_auth) << 2;
7100 AL.setInvalid();
7101 }
7102 } else {
7103 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
7104 << AL << AANT_ArgumentIdentifier;
7105 }
7106 }
7107
7108 uint32_t CustomDiscriminationValue = 0;
7109 if (ED == VTablePointerAuthenticationAttr::CustomDiscrimination) {
7110 if (NumArgs < 4) {
7111 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_missing_custom_discrimination) << AL << 4;
7112 AL.setInvalid();
7113 return;
7114 }
7115 if (NumArgs > 4) {
7116 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_too_many_arguments) << AL << 4;
7117 AL.setInvalid();
7118 }
7119
7120 if (!AL.isArgExpr(Arg: 3) || !S.checkUInt32Argument(AI: AL, Expr: AL.getArgAsExpr(Arg: 3),
7121 Val&: CustomDiscriminationValue)) {
7122 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_invalid_custom_discrimination);
7123 AL.setInvalid();
7124 }
7125 } else if (NumArgs > 3) {
7126 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_too_many_arguments) << AL << 3;
7127 AL.setInvalid();
7128 }
7129
7130 Decl->addAttr(A: ::new (S.Context) VTablePointerAuthenticationAttr(
7131 S.Context, AL, KeyType, AddressDiversityMode, ED,
7132 CustomDiscriminationValue));
7133}
7134
7135static bool modularFormatAttrsEquiv(const ModularFormatAttr *Existing,
7136 const IdentifierInfo *ModularImplFn,
7137 StringRef ImplName,
7138 ArrayRef<StringRef> Aspects) {
7139 return Existing->getModularImplFn() == ModularImplFn &&
7140 Existing->getImplName() == ImplName &&
7141 Existing->aspects_size() == Aspects.size() &&
7142 llvm::equal(LRange: Existing->aspects(), RRange&: Aspects);
7143}
7144
7145ModularFormatAttr *Sema::mergeModularFormatAttr(
7146 Decl *D, const AttributeCommonInfo &CI, const IdentifierInfo *ModularImplFn,
7147 StringRef ImplName, MutableArrayRef<StringRef> Aspects) {
7148 if (const auto *Existing = D->getAttr<ModularFormatAttr>()) {
7149 if (!modularFormatAttrsEquiv(Existing, ModularImplFn, ImplName, Aspects)) {
7150 Diag(Loc: Existing->getLocation(), DiagID: diag::err_duplicate_attribute) << *Existing;
7151 Diag(Loc: CI.getLoc(), DiagID: diag::note_conflicting_attribute);
7152 }
7153 return nullptr;
7154 }
7155 return ::new (Context) ModularFormatAttr(Context, CI, ModularImplFn, ImplName,
7156 Aspects.data(), Aspects.size());
7157}
7158
7159static void handleModularFormat(Sema &S, Decl *D, const ParsedAttr &AL) {
7160 bool Valid = true;
7161 if (!AL.isArgIdent(Arg: 0)) {
7162 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
7163 << AL << 1 << AANT_ArgumentIdentifier;
7164 Valid = false;
7165 }
7166 StringRef ImplName;
7167 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 1, Str&: ImplName))
7168 Valid = false;
7169 SmallVector<StringRef> Aspects;
7170 llvm::DenseSet<StringRef> SeenAspects;
7171 for (unsigned I = 2, E = AL.getNumArgs(); I != E; ++I) {
7172 StringRef Aspect;
7173 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: Aspect))
7174 return;
7175 if (!SeenAspects.insert(V: Aspect).second) {
7176 S.Diag(Loc: AL.getArgAsExpr(Arg: I)->getExprLoc(),
7177 DiagID: diag::err_modular_format_duplicate_aspect)
7178 << Aspect;
7179 Valid = false;
7180 continue;
7181 }
7182 Aspects.push_back(Elt: Aspect);
7183 }
7184 if (!Valid)
7185 return;
7186
7187 // Store aspects sorted.
7188 llvm::sort(C&: Aspects);
7189 IdentifierInfo *ModularImplFn = AL.getArgAsIdent(Arg: 0)->getIdentifierInfo();
7190
7191 if (const auto *Existing = D->getAttr<ModularFormatAttr>()) {
7192 if (!modularFormatAttrsEquiv(Existing, ModularImplFn, ImplName, Aspects)) {
7193 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_duplicate_attribute) << *Existing;
7194 S.Diag(Loc: Existing->getLoc(), DiagID: diag::note_conflicting_attribute);
7195 }
7196 // Ignore the later declaration in favor of the earlier one.
7197 return;
7198 }
7199
7200 D->addAttr(A: ::new (S.Context) ModularFormatAttr(
7201 S.Context, AL, ModularImplFn, ImplName, Aspects.data(), Aspects.size()));
7202}
7203
7204//===----------------------------------------------------------------------===//
7205// Top Level Sema Entry Points
7206//===----------------------------------------------------------------------===//
7207
7208// Returns true if the attribute must delay setting its arguments until after
7209// template instantiation, and false otherwise.
7210static bool MustDelayAttributeArguments(const ParsedAttr &AL) {
7211 // Only attributes that accept expression parameter packs can delay arguments.
7212 if (!AL.acceptsExprPack())
7213 return false;
7214
7215 bool AttrHasVariadicArg = AL.hasVariadicArg();
7216 unsigned AttrNumArgs = AL.getNumArgMembers();
7217 for (size_t I = 0; I < std::min(a: AL.getNumArgs(), b: AttrNumArgs); ++I) {
7218 bool IsLastAttrArg = I == (AttrNumArgs - 1);
7219 // If the argument is the last argument and it is variadic it can contain
7220 // any expression.
7221 if (IsLastAttrArg && AttrHasVariadicArg)
7222 return false;
7223 Expr *E = AL.getArgAsExpr(Arg: I);
7224 bool ArgMemberCanHoldExpr = AL.isParamExpr(N: I);
7225 // If the expression is a pack expansion then arguments must be delayed
7226 // unless the argument is an expression and it is the last argument of the
7227 // attribute.
7228 if (isa<PackExpansionExpr>(Val: E))
7229 return !(IsLastAttrArg && ArgMemberCanHoldExpr);
7230 // Last case is if the expression is value dependent then it must delay
7231 // arguments unless the corresponding argument is able to hold the
7232 // expression.
7233 if (E->isValueDependent() && !ArgMemberCanHoldExpr)
7234 return true;
7235 }
7236 return false;
7237}
7238
7239PersonalityAttr *Sema::mergePersonalityAttr(Decl *D, FunctionDecl *Routine,
7240 const AttributeCommonInfo &CI) {
7241 if (PersonalityAttr *PA = D->getAttr<PersonalityAttr>()) {
7242 const FunctionDecl *Personality = PA->getRoutine();
7243 if (Context.isSameEntity(X: Personality, Y: Routine))
7244 return nullptr;
7245 Diag(Loc: PA->getLocation(), DiagID: diag::err_mismatched_personality);
7246 Diag(Loc: CI.getLoc(), DiagID: diag::note_previous_attribute);
7247 D->dropAttr<PersonalityAttr>();
7248 }
7249 return ::new (Context) PersonalityAttr(Context, CI, Routine);
7250}
7251
7252static void handlePersonalityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7253 Expr *E = AL.getArgAsExpr(Arg: 0);
7254 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Val: E))
7255 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Val: DRE->getDecl()))
7256 if (Attr *A = S.mergePersonalityAttr(D, Routine: FD, CI: AL))
7257 return D->addAttr(A);
7258 S.Diag(Loc: E->getExprLoc(), DiagID: diag::err_attribute_personality_arg_not_function)
7259 << AL.getAttrName();
7260}
7261
7262/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
7263/// the attribute applies to decls. If the attribute is a type attribute, just
7264/// silently ignore it if a GNU attribute.
7265static void
7266ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
7267 const Sema::ProcessDeclAttributeOptions &Options) {
7268 if (AL.isInvalid() || AL.getKind() == ParsedAttr::IgnoredAttribute)
7269 return;
7270
7271 // Ignore C++11 attributes on declarator chunks: they appertain to the type
7272 // instead. Note, isCXX11Attribute() will look at whether the attribute is
7273 // [[]] or alignas, while isC23Attribute() will only look at [[]]. This is
7274 // important for ensuring that alignas in C23 is properly handled on a
7275 // structure member declaration because it is a type-specifier-qualifier in
7276 // C but still applies to the declaration rather than the type.
7277 if ((S.getLangOpts().CPlusPlus ? AL.isCXX11Attribute()
7278 : AL.isC23Attribute()) &&
7279 !Options.IncludeCXX11Attributes)
7280 return;
7281
7282 // Unknown attributes are automatically warned on. Target-specific attributes
7283 // which do not apply to the current target architecture are treated as
7284 // though they were unknown attributes.
7285 if (AL.getKind() == ParsedAttr::UnknownAttribute ||
7286 !AL.existsInTarget(Target: S.Context.getTargetInfo())) {
7287 if (AL.isRegularKeywordAttribute()) {
7288 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_keyword_not_supported_on_target)
7289 << AL.getAttrName() << AL.getRange();
7290 } else if (AL.isDeclspecAttribute()) {
7291 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_unhandled_ms_attribute_ignored)
7292 << AL.getAttrName() << AL.getRange();
7293 } else {
7294 S.DiagnoseUnknownAttribute(AL);
7295 }
7296 return;
7297 }
7298
7299 if (S.getLangOpts().HLSL && isa<FunctionDecl>(Val: D) &&
7300 AL.getKind() == ParsedAttr::AT_NoInline) {
7301 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
7302 for (const ParmVarDecl *PVD : FD->parameters()) {
7303 if (PVD->hasAttr<HLSLGroupSharedAddressSpaceAttr>()) {
7304 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_hlsl_attr_incompatible)
7305 << "'noinline'" << "'groupshared' parameter";
7306 return;
7307 }
7308 }
7309 }
7310 }
7311
7312 // Check if argument population must delayed to after template instantiation.
7313 bool MustDelayArgs = MustDelayAttributeArguments(AL);
7314
7315 // Argument number check must be skipped if arguments are delayed.
7316 if (S.checkCommonAttributeFeatures(D, A: AL, SkipArgCountCheck: MustDelayArgs))
7317 return;
7318
7319 if (MustDelayArgs) {
7320 AL.handleAttrWithDelayedArgs(S, D);
7321 return;
7322 }
7323
7324 switch (AL.getKind()) {
7325 default:
7326 if (AL.getInfo().handleDeclAttribute(S, D, Attr: AL) != ParsedAttrInfo::NotHandled)
7327 break;
7328 if (!AL.isStmtAttr()) {
7329 assert(AL.isTypeAttr() && "Non-type attribute not handled");
7330 }
7331 if (AL.isTypeAttr()) {
7332 if (Options.IgnoreTypeAttributes)
7333 break;
7334 if (!AL.isStandardAttributeSyntax() && !AL.isRegularKeywordAttribute()) {
7335 // Non-[[]] type attributes are handled in processTypeAttrs(); silently
7336 // move on.
7337 break;
7338 }
7339
7340 // According to the C and C++ standards, we should never see a
7341 // [[]] type attribute on a declaration. However, we have in the past
7342 // allowed some type attributes to "slide" to the `DeclSpec`, so we need
7343 // to continue to support this legacy behavior. We only do this, however,
7344 // if
7345 // - we actually have a `DeclSpec`, i.e. if we're looking at a
7346 // `DeclaratorDecl`, or
7347 // - we are looking at an alias-declaration, where historically we have
7348 // allowed type attributes after the identifier to slide to the type.
7349 if (AL.slidesFromDeclToDeclSpecLegacyBehavior() &&
7350 isa<DeclaratorDecl, TypeAliasDecl>(Val: D)) {
7351 // Suggest moving the attribute to the type instead, but only for our
7352 // own vendor attributes; moving other vendors' attributes might hurt
7353 // portability.
7354 if (AL.isClangScope()) {
7355 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_type_attribute_deprecated_on_decl)
7356 << AL << D->getLocation();
7357 }
7358
7359 // Allow this type attribute to be handled in processTypeAttrs();
7360 // silently move on.
7361 break;
7362 }
7363
7364 if (AL.getKind() == ParsedAttr::AT_Regparm) {
7365 // `regparm` is a special case: It's a type attribute but we still want
7366 // to treat it as if it had been written on the declaration because that
7367 // way we'll be able to handle it directly in `processTypeAttr()`.
7368 // If we treated `regparm` it as if it had been written on the
7369 // `DeclSpec`, the logic in `distributeFunctionTypeAttrFromDeclSepc()`
7370 // would try to move it to the declarator, but that doesn't work: We
7371 // can't remove the attribute from the list of declaration attributes
7372 // because it might be needed by other declarators in the same
7373 // declaration.
7374 break;
7375 }
7376
7377 if (AL.getKind() == ParsedAttr::AT_VectorSize) {
7378 // `vector_size` is a special case: It's a type attribute semantically,
7379 // but GCC expects the [[]] syntax to be written on the declaration (and
7380 // warns that the attribute has no effect if it is placed on the
7381 // decl-specifier-seq).
7382 // Silently move on and allow the attribute to be handled in
7383 // processTypeAttr().
7384 break;
7385 }
7386
7387 if (AL.getKind() == ParsedAttr::AT_NoDeref) {
7388 // FIXME: `noderef` currently doesn't work correctly in [[]] syntax.
7389 // See https://github.com/llvm/llvm-project/issues/55790 for details.
7390 // We allow processTypeAttrs() to emit a warning and silently move on.
7391 break;
7392 }
7393 }
7394 // N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a
7395 // statement attribute is not written on a declaration, but this code is
7396 // needed for type attributes as well as statement attributes in Attr.td
7397 // that do not list any subjects.
7398 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_invalid_on_decl)
7399 << AL << AL.isRegularKeywordAttribute() << D->getLocation();
7400 break;
7401 case ParsedAttr::AT_Interrupt:
7402 handleInterruptAttr(S, D, AL);
7403 break;
7404 case ParsedAttr::AT_ARMInterruptSaveFP:
7405 S.ARM().handleInterruptSaveFPAttr(D, AL);
7406 break;
7407 case ParsedAttr::AT_X86ForceAlignArgPointer:
7408 S.X86().handleForceAlignArgPointerAttr(D, AL);
7409 break;
7410 case ParsedAttr::AT_ReadOnlyPlacement:
7411 handleSimpleAttribute<ReadOnlyPlacementAttr>(S, D, CI: AL);
7412 break;
7413 case ParsedAttr::AT_DLLExport:
7414 case ParsedAttr::AT_DLLImport:
7415 handleDLLAttr(S, D, A: AL);
7416 break;
7417 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
7418 S.AMDGPU().handleAMDGPUFlatWorkGroupSizeAttr(D, AL);
7419 break;
7420 case ParsedAttr::AT_AMDGPUWavesPerEU:
7421 S.AMDGPU().handleAMDGPUWavesPerEUAttr(D, AL);
7422 break;
7423 case ParsedAttr::AT_AMDGPUNumSGPR:
7424 S.AMDGPU().handleAMDGPUNumSGPRAttr(D, AL);
7425 break;
7426 case ParsedAttr::AT_AMDGPUNumVGPR:
7427 S.AMDGPU().handleAMDGPUNumVGPRAttr(D, AL);
7428 break;
7429 case ParsedAttr::AT_AMDGPUMaxNumWorkGroups:
7430 S.AMDGPU().handleAMDGPUMaxNumWorkGroupsAttr(D, AL);
7431 break;
7432 case ParsedAttr::AT_AVRSignal:
7433 S.AVR().handleSignalAttr(D, AL);
7434 break;
7435 case ParsedAttr::AT_BPFPreserveAccessIndex:
7436 S.BPF().handlePreserveAccessIndexAttr(D, AL);
7437 break;
7438 case ParsedAttr::AT_BPFPreserveStaticOffset:
7439 handleSimpleAttribute<BPFPreserveStaticOffsetAttr>(S, D, CI: AL);
7440 break;
7441 case ParsedAttr::AT_BTFDeclTag:
7442 handleBTFDeclTagAttr(S, D, AL);
7443 break;
7444 case ParsedAttr::AT_WebAssemblyExportName:
7445 S.Wasm().handleWebAssemblyExportNameAttr(D, AL);
7446 break;
7447 case ParsedAttr::AT_WebAssemblyImportModule:
7448 S.Wasm().handleWebAssemblyImportModuleAttr(D, AL);
7449 break;
7450 case ParsedAttr::AT_WebAssemblyImportName:
7451 S.Wasm().handleWebAssemblyImportNameAttr(D, AL);
7452 break;
7453 case ParsedAttr::AT_IBOutlet:
7454 S.ObjC().handleIBOutlet(D, AL);
7455 break;
7456 case ParsedAttr::AT_IBOutletCollection:
7457 S.ObjC().handleIBOutletCollection(D, AL);
7458 break;
7459 case ParsedAttr::AT_IFunc:
7460 handleIFuncAttr(S, D, AL);
7461 break;
7462 case ParsedAttr::AT_Alias:
7463 handleAliasAttr(S, D, AL);
7464 break;
7465 case ParsedAttr::AT_Aligned:
7466 handleAlignedAttr(S, D, AL);
7467 break;
7468 case ParsedAttr::AT_AlignValue:
7469 handleAlignValueAttr(S, D, AL);
7470 break;
7471 case ParsedAttr::AT_AllocSize:
7472 handleAllocSizeAttr(S, D, AL);
7473 break;
7474 case ParsedAttr::AT_AlwaysInline:
7475 handleAlwaysInlineAttr(S, D, AL);
7476 break;
7477 case ParsedAttr::AT_AnalyzerNoReturn:
7478 handleAnalyzerNoReturnAttr(S, D, AL);
7479 break;
7480 case ParsedAttr::AT_TLSModel:
7481 handleTLSModelAttr(S, D, AL);
7482 break;
7483 case ParsedAttr::AT_Annotate:
7484 handleAnnotateAttr(S, D, AL);
7485 break;
7486 case ParsedAttr::AT_Availability:
7487 handleAvailabilityAttr(S, D, AL);
7488 break;
7489 case ParsedAttr::AT_CarriesDependency:
7490 handleDependencyAttr(S, Scope: scope, D, AL);
7491 break;
7492 case ParsedAttr::AT_CPUDispatch:
7493 case ParsedAttr::AT_CPUSpecific:
7494 handleCPUSpecificAttr(S, D, AL);
7495 break;
7496 case ParsedAttr::AT_Common:
7497 handleCommonAttr(S, D, AL);
7498 break;
7499 case ParsedAttr::AT_CUDAConstant:
7500 handleConstantAttr(S, D, AL);
7501 break;
7502 case ParsedAttr::AT_PassObjectSize:
7503 handlePassObjectSizeAttr(S, D, AL);
7504 break;
7505 case ParsedAttr::AT_Constructor:
7506 handleConstructorAttr(S, D, AL);
7507 break;
7508 case ParsedAttr::AT_Deprecated:
7509 handleDeprecatedAttr(S, D, AL);
7510 break;
7511 case ParsedAttr::AT_Destructor:
7512 handleDestructorAttr(S, D, AL);
7513 break;
7514 case ParsedAttr::AT_EnableIf:
7515 handleEnableIfAttr(S, D, AL);
7516 break;
7517 case ParsedAttr::AT_Error:
7518 handleErrorAttr(S, D, AL);
7519 break;
7520 case ParsedAttr::AT_ExcludeFromExplicitInstantiation:
7521 handleExcludeFromExplicitInstantiationAttr(S, D, AL);
7522 break;
7523 case ParsedAttr::AT_DiagnoseIf:
7524 handleDiagnoseIfAttr(S, D, AL);
7525 break;
7526 case ParsedAttr::AT_DiagnoseAsBuiltin:
7527 handleDiagnoseAsBuiltinAttr(S, D, AL);
7528 break;
7529 case ParsedAttr::AT_NoBuiltin:
7530 handleNoBuiltinAttr(S, D, AL);
7531 break;
7532 case ParsedAttr::AT_CFIUncheckedCallee:
7533 handleCFIUncheckedCalleeAttr(S, D, Attrs: AL);
7534 break;
7535 case ParsedAttr::AT_ExtVectorType:
7536 handleExtVectorTypeAttr(S, D, AL);
7537 break;
7538 case ParsedAttr::AT_ExternalSourceSymbol:
7539 handleExternalSourceSymbolAttr(S, D, AL);
7540 break;
7541 case ParsedAttr::AT_MinSize:
7542 handleMinSizeAttr(S, D, AL);
7543 break;
7544 case ParsedAttr::AT_OptimizeNone:
7545 handleOptimizeNoneAttr(S, D, AL);
7546 break;
7547 case ParsedAttr::AT_EnumExtensibility:
7548 handleEnumExtensibilityAttr(S, D, AL);
7549 break;
7550 case ParsedAttr::AT_SYCLKernel:
7551 S.SYCL().handleKernelAttr(D, AL);
7552 break;
7553 case ParsedAttr::AT_SYCLExternal:
7554 handleSimpleAttribute<SYCLExternalAttr>(S, D, CI: AL);
7555 break;
7556 case ParsedAttr::AT_SYCLKernelEntryPoint:
7557 S.SYCL().handleKernelEntryPointAttr(D, AL);
7558 break;
7559 case ParsedAttr::AT_SYCLSpecialClass:
7560 handleSimpleAttribute<SYCLSpecialClassAttr>(S, D, CI: AL);
7561 break;
7562 case ParsedAttr::AT_Format:
7563 handleFormatAttr(S, D, AL);
7564 break;
7565 case ParsedAttr::AT_FormatMatches:
7566 handleFormatMatchesAttr(S, D, AL);
7567 break;
7568 case ParsedAttr::AT_FormatArg:
7569 handleFormatArgAttr(S, D, AL);
7570 break;
7571 case ParsedAttr::AT_Callback:
7572 handleCallbackAttr(S, D, AL);
7573 break;
7574 case ParsedAttr::AT_LifetimeCaptureBy:
7575 handleLifetimeCaptureByAttr(S, D, AL);
7576 break;
7577 case ParsedAttr::AT_CalledOnce:
7578 handleCalledOnceAttr(S, D, AL);
7579 break;
7580 case ParsedAttr::AT_CUDAGlobal:
7581 handleGlobalAttr(S, D, AL);
7582 break;
7583 case ParsedAttr::AT_CUDADevice:
7584 handleDeviceAttr(S, D, AL);
7585 break;
7586 case ParsedAttr::AT_CUDAGridConstant:
7587 handleGridConstantAttr(S, D, AL);
7588 break;
7589 case ParsedAttr::AT_HIPManaged:
7590 handleManagedAttr(S, D, AL);
7591 break;
7592 case ParsedAttr::AT_GNUInline:
7593 handleGNUInlineAttr(S, D, AL);
7594 break;
7595 case ParsedAttr::AT_CUDALaunchBounds:
7596 handleLaunchBoundsAttr(S, D, AL);
7597 break;
7598 case ParsedAttr::AT_CUDAClusterDims:
7599 handleClusterDimsAttr(S, D, AL);
7600 break;
7601 case ParsedAttr::AT_CUDANoCluster:
7602 handleNoClusterAttr(S, D, AL);
7603 break;
7604 case ParsedAttr::AT_Restrict:
7605 handleRestrictAttr(S, D, AL);
7606 break;
7607 case ParsedAttr::AT_MallocSpan:
7608 handleMallocSpanAttr(S, D, AL);
7609 break;
7610 case ParsedAttr::AT_Mode:
7611 handleModeAttr(S, D, AL);
7612 break;
7613 case ParsedAttr::AT_NonString:
7614 handleNonStringAttr(S, D, AL);
7615 break;
7616 case ParsedAttr::AT_NonNull:
7617 if (auto *PVD = dyn_cast<ParmVarDecl>(Val: D))
7618 handleNonNullAttrParameter(S, D: PVD, AL);
7619 else
7620 handleNonNullAttr(S, D, AL);
7621 break;
7622 case ParsedAttr::AT_ReturnsNonNull:
7623 handleReturnsNonNullAttr(S, D, AL);
7624 break;
7625 case ParsedAttr::AT_NoEscape:
7626 handleNoEscapeAttr(S, D, AL);
7627 break;
7628 case ParsedAttr::AT_MaybeUndef:
7629 handleSimpleAttribute<MaybeUndefAttr>(S, D, CI: AL);
7630 break;
7631 case ParsedAttr::AT_AssumeAligned:
7632 handleAssumeAlignedAttr(S, D, AL);
7633 break;
7634 case ParsedAttr::AT_AllocAlign:
7635 handleAllocAlignAttr(S, D, AL);
7636 break;
7637 case ParsedAttr::AT_Ownership:
7638 handleOwnershipAttr(S, D, AL);
7639 break;
7640 case ParsedAttr::AT_Naked:
7641 handleNakedAttr(S, D, AL);
7642 break;
7643 case ParsedAttr::AT_NoReturn:
7644 handleNoReturnAttr(S, D, Attrs: AL);
7645 break;
7646 case ParsedAttr::AT_CXX11NoReturn:
7647 handleStandardNoReturnAttr(S, D, A: AL);
7648 break;
7649 case ParsedAttr::AT_AnyX86NoCfCheck:
7650 handleNoCfCheckAttr(S, D, Attrs: AL);
7651 break;
7652 case ParsedAttr::AT_NoThrow:
7653 if (!AL.isUsedAsTypeAttr())
7654 handleSimpleAttribute<NoThrowAttr>(S, D, CI: AL);
7655 break;
7656 case ParsedAttr::AT_CUDAShared:
7657 handleSharedAttr(S, D, AL);
7658 break;
7659 case ParsedAttr::AT_VecReturn:
7660 handleVecReturnAttr(S, D, AL);
7661 break;
7662 case ParsedAttr::AT_ObjCOwnership:
7663 S.ObjC().handleOwnershipAttr(D, AL);
7664 break;
7665 case ParsedAttr::AT_ObjCPreciseLifetime:
7666 S.ObjC().handlePreciseLifetimeAttr(D, AL);
7667 break;
7668 case ParsedAttr::AT_ObjCReturnsInnerPointer:
7669 S.ObjC().handleReturnsInnerPointerAttr(D, Attrs: AL);
7670 break;
7671 case ParsedAttr::AT_ObjCRequiresSuper:
7672 S.ObjC().handleRequiresSuperAttr(D, Attrs: AL);
7673 break;
7674 case ParsedAttr::AT_ObjCBridge:
7675 S.ObjC().handleBridgeAttr(D, AL);
7676 break;
7677 case ParsedAttr::AT_ObjCBridgeMutable:
7678 S.ObjC().handleBridgeMutableAttr(D, AL);
7679 break;
7680 case ParsedAttr::AT_ObjCBridgeRelated:
7681 S.ObjC().handleBridgeRelatedAttr(D, AL);
7682 break;
7683 case ParsedAttr::AT_ObjCDesignatedInitializer:
7684 S.ObjC().handleDesignatedInitializer(D, AL);
7685 break;
7686 case ParsedAttr::AT_ObjCRuntimeName:
7687 S.ObjC().handleRuntimeName(D, AL);
7688 break;
7689 case ParsedAttr::AT_ObjCBoxable:
7690 S.ObjC().handleBoxable(D, AL);
7691 break;
7692 case ParsedAttr::AT_NSErrorDomain:
7693 S.ObjC().handleNSErrorDomain(D, Attr: AL);
7694 break;
7695 case ParsedAttr::AT_CFConsumed:
7696 case ParsedAttr::AT_NSConsumed:
7697 case ParsedAttr::AT_OSConsumed:
7698 S.ObjC().AddXConsumedAttr(D, CI: AL,
7699 K: S.ObjC().parsedAttrToRetainOwnershipKind(AL),
7700 /*IsTemplateInstantiation=*/false);
7701 break;
7702 case ParsedAttr::AT_OSReturnsRetainedOnZero:
7703 handleSimpleAttributeOrDiagnose<OSReturnsRetainedOnZeroAttr>(
7704 S, D, CI: AL, PassesCheck: S.ObjC().isValidOSObjectOutParameter(D),
7705 DiagID: diag::warn_ns_attribute_wrong_parameter_type,
7706 /*Extra Args=*/ExtraArgs: AL, /*pointer-to-OSObject-pointer*/ ExtraArgs: 3, ExtraArgs: AL.getRange());
7707 break;
7708 case ParsedAttr::AT_OSReturnsRetainedOnNonZero:
7709 handleSimpleAttributeOrDiagnose<OSReturnsRetainedOnNonZeroAttr>(
7710 S, D, CI: AL, PassesCheck: S.ObjC().isValidOSObjectOutParameter(D),
7711 DiagID: diag::warn_ns_attribute_wrong_parameter_type,
7712 /*Extra Args=*/ExtraArgs: AL, /*pointer-to-OSObject-poointer*/ ExtraArgs: 3, ExtraArgs: AL.getRange());
7713 break;
7714 case ParsedAttr::AT_NSReturnsAutoreleased:
7715 case ParsedAttr::AT_NSReturnsNotRetained:
7716 case ParsedAttr::AT_NSReturnsRetained:
7717 case ParsedAttr::AT_CFReturnsNotRetained:
7718 case ParsedAttr::AT_CFReturnsRetained:
7719 case ParsedAttr::AT_OSReturnsNotRetained:
7720 case ParsedAttr::AT_OSReturnsRetained:
7721 S.ObjC().handleXReturnsXRetainedAttr(D, AL);
7722 break;
7723 case ParsedAttr::AT_WorkGroupSizeHint:
7724 handleWorkGroupSize<WorkGroupSizeHintAttr>(S, D, AL);
7725 break;
7726 case ParsedAttr::AT_ReqdWorkGroupSize:
7727 handleWorkGroupSize<ReqdWorkGroupSizeAttr>(S, D, AL);
7728 break;
7729 case ParsedAttr::AT_OpenCLIntelReqdSubGroupSize:
7730 S.OpenCL().handleSubGroupSize(D, AL);
7731 break;
7732 case ParsedAttr::AT_VecTypeHint:
7733 handleVecTypeHint(S, D, AL);
7734 break;
7735 case ParsedAttr::AT_InitPriority:
7736 handleInitPriorityAttr(S, D, AL);
7737 break;
7738 case ParsedAttr::AT_Packed:
7739 handlePackedAttr(S, D, AL);
7740 break;
7741 case ParsedAttr::AT_PreferredName:
7742 handlePreferredName(S, D, AL);
7743 break;
7744 case ParsedAttr::AT_NoSpecializations:
7745 handleNoSpecializations(S, D, AL);
7746 break;
7747 case ParsedAttr::AT_Section:
7748 handleSectionAttr(S, D, AL);
7749 break;
7750 case ParsedAttr::AT_CodeModel:
7751 handleCodeModelAttr(S, D, AL);
7752 break;
7753 case ParsedAttr::AT_RandomizeLayout:
7754 handleRandomizeLayoutAttr(S, D, AL);
7755 break;
7756 case ParsedAttr::AT_NoRandomizeLayout:
7757 handleNoRandomizeLayoutAttr(S, D, AL);
7758 break;
7759 case ParsedAttr::AT_CodeSeg:
7760 handleCodeSegAttr(S, D, AL);
7761 break;
7762 case ParsedAttr::AT_Target:
7763 handleTargetAttr(S, D, AL);
7764 break;
7765 case ParsedAttr::AT_TargetVersion:
7766 handleTargetVersionAttr(S, D, AL);
7767 break;
7768 case ParsedAttr::AT_TargetClones:
7769 handleTargetClonesAttr(S, D, AL);
7770 break;
7771 case ParsedAttr::AT_MinVectorWidth:
7772 handleMinVectorWidthAttr(S, D, AL);
7773 break;
7774 case ParsedAttr::AT_Unavailable:
7775 handleAttrWithMessage<UnavailableAttr>(S, D, AL);
7776 break;
7777 case ParsedAttr::AT_OMPAssume:
7778 S.OpenMP().handleOMPAssumeAttr(D, AL);
7779 break;
7780 case ParsedAttr::AT_ObjCDirect:
7781 S.ObjC().handleDirectAttr(D, AL);
7782 break;
7783 case ParsedAttr::AT_ObjCDirectMembers:
7784 S.ObjC().handleDirectMembersAttr(D, AL);
7785 handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, CI: AL);
7786 break;
7787 case ParsedAttr::AT_ObjCExplicitProtocolImpl:
7788 S.ObjC().handleSuppresProtocolAttr(D, AL);
7789 break;
7790 case ParsedAttr::AT_Unused:
7791 handleUnusedAttr(S, D, AL);
7792 break;
7793 case ParsedAttr::AT_Visibility:
7794 handleVisibilityAttr(S, D, AL, isTypeVisibility: false);
7795 break;
7796 case ParsedAttr::AT_TypeVisibility:
7797 handleVisibilityAttr(S, D, AL, isTypeVisibility: true);
7798 break;
7799 case ParsedAttr::AT_WarnUnusedResult:
7800 handleWarnUnusedResult(S, D, AL);
7801 break;
7802 case ParsedAttr::AT_WeakRef:
7803 handleWeakRefAttr(S, D, AL);
7804 break;
7805 case ParsedAttr::AT_WeakImport:
7806 handleWeakImportAttr(S, D, AL);
7807 break;
7808 case ParsedAttr::AT_TransparentUnion:
7809 handleTransparentUnionAttr(S, D, AL);
7810 break;
7811 case ParsedAttr::AT_ObjCMethodFamily:
7812 S.ObjC().handleMethodFamilyAttr(D, AL);
7813 break;
7814 case ParsedAttr::AT_ObjCNSObject:
7815 S.ObjC().handleNSObject(D, AL);
7816 break;
7817 case ParsedAttr::AT_ObjCIndependentClass:
7818 S.ObjC().handleIndependentClass(D, AL);
7819 break;
7820 case ParsedAttr::AT_Blocks:
7821 S.ObjC().handleBlocksAttr(D, AL);
7822 break;
7823 case ParsedAttr::AT_Sentinel:
7824 handleSentinelAttr(S, D, AL);
7825 break;
7826 case ParsedAttr::AT_Cleanup:
7827 handleCleanupAttr(S, D, AL);
7828 break;
7829 case ParsedAttr::AT_NoDebug:
7830 handleNoDebugAttr(S, D, AL);
7831 break;
7832 case ParsedAttr::AT_CmseNSEntry:
7833 S.ARM().handleCmseNSEntryAttr(D, AL);
7834 break;
7835 case ParsedAttr::AT_StdCall:
7836 case ParsedAttr::AT_CDecl:
7837 case ParsedAttr::AT_FastCall:
7838 case ParsedAttr::AT_ThisCall:
7839 case ParsedAttr::AT_Pascal:
7840 case ParsedAttr::AT_RegCall:
7841 case ParsedAttr::AT_SwiftCall:
7842 case ParsedAttr::AT_SwiftAsyncCall:
7843 case ParsedAttr::AT_VectorCall:
7844 case ParsedAttr::AT_MSABI:
7845 case ParsedAttr::AT_SysVABI:
7846 case ParsedAttr::AT_Pcs:
7847 case ParsedAttr::AT_IntelOclBicc:
7848 case ParsedAttr::AT_PreserveMost:
7849 case ParsedAttr::AT_PreserveAll:
7850 case ParsedAttr::AT_AArch64VectorPcs:
7851 case ParsedAttr::AT_AArch64SVEPcs:
7852 case ParsedAttr::AT_M68kRTD:
7853 case ParsedAttr::AT_PreserveNone:
7854 case ParsedAttr::AT_RISCVVectorCC:
7855 case ParsedAttr::AT_RISCVVLSCC:
7856 handleCallConvAttr(S, D, AL);
7857 break;
7858 case ParsedAttr::AT_DeviceKernel:
7859 handleDeviceKernelAttr(S, D, AL);
7860 break;
7861 case ParsedAttr::AT_Suppress:
7862 handleSuppressAttr(S, D, AL);
7863 break;
7864 case ParsedAttr::AT_Owner:
7865 case ParsedAttr::AT_Pointer:
7866 handleLifetimeCategoryAttr(S, D, AL);
7867 break;
7868 case ParsedAttr::AT_OpenCLAccess:
7869 S.OpenCL().handleAccessAttr(D, AL);
7870 break;
7871 case ParsedAttr::AT_OpenCLNoSVM:
7872 S.OpenCL().handleNoSVMAttr(D, AL);
7873 break;
7874 case ParsedAttr::AT_SwiftContext:
7875 S.Swift().AddParameterABIAttr(D, CI: AL, abi: ParameterABI::SwiftContext);
7876 break;
7877 case ParsedAttr::AT_SwiftAsyncContext:
7878 S.Swift().AddParameterABIAttr(D, CI: AL, abi: ParameterABI::SwiftAsyncContext);
7879 break;
7880 case ParsedAttr::AT_SwiftErrorResult:
7881 S.Swift().AddParameterABIAttr(D, CI: AL, abi: ParameterABI::SwiftErrorResult);
7882 break;
7883 case ParsedAttr::AT_SwiftIndirectResult:
7884 S.Swift().AddParameterABIAttr(D, CI: AL, abi: ParameterABI::SwiftIndirectResult);
7885 break;
7886 case ParsedAttr::AT_InternalLinkage:
7887 handleInternalLinkageAttr(S, D, AL);
7888 break;
7889 case ParsedAttr::AT_ZeroCallUsedRegs:
7890 handleZeroCallUsedRegsAttr(S, D, AL);
7891 break;
7892 case ParsedAttr::AT_FunctionReturnThunks:
7893 handleFunctionReturnThunksAttr(S, D, AL);
7894 break;
7895 case ParsedAttr::AT_NoMerge:
7896 handleNoMergeAttr(S, D, AL);
7897 break;
7898 case ParsedAttr::AT_NoUniqueAddress:
7899 handleNoUniqueAddressAttr(S, D, AL);
7900 break;
7901
7902 case ParsedAttr::AT_AvailableOnlyInDefaultEvalMethod:
7903 handleAvailableOnlyInDefaultEvalMethod(S, D, AL);
7904 break;
7905
7906 case ParsedAttr::AT_CountedBy:
7907 case ParsedAttr::AT_CountedByOrNull:
7908 case ParsedAttr::AT_SizedBy:
7909 case ParsedAttr::AT_SizedByOrNull:
7910 handleCountedByAttrField(S, D, AL);
7911 break;
7912
7913 case ParsedAttr::AT_NoFieldProtection:
7914 handleNoPFPAttrField(S, D, AL);
7915 break;
7916
7917 case ParsedAttr::AT_Personality:
7918 handlePersonalityAttr(S, D, AL);
7919 break;
7920
7921 // Microsoft attributes:
7922 case ParsedAttr::AT_LayoutVersion:
7923 handleLayoutVersion(S, D, AL);
7924 break;
7925 case ParsedAttr::AT_Uuid:
7926 handleUuidAttr(S, D, AL);
7927 break;
7928 case ParsedAttr::AT_MSInheritance:
7929 handleMSInheritanceAttr(S, D, AL);
7930 break;
7931 case ParsedAttr::AT_Thread:
7932 handleDeclspecThreadAttr(S, D, AL);
7933 break;
7934 case ParsedAttr::AT_MSConstexpr:
7935 handleMSConstexprAttr(S, D, AL);
7936 break;
7937 case ParsedAttr::AT_HybridPatchable:
7938 handleSimpleAttribute<HybridPatchableAttr>(S, D, CI: AL);
7939 break;
7940
7941 // HLSL attributes:
7942 case ParsedAttr::AT_RootSignature:
7943 S.HLSL().handleRootSignatureAttr(D, AL);
7944 break;
7945 case ParsedAttr::AT_HLSLNumThreads:
7946 S.HLSL().handleNumThreadsAttr(D, AL);
7947 break;
7948 case ParsedAttr::AT_HLSLWaveSize:
7949 S.HLSL().handleWaveSizeAttr(D, AL);
7950 break;
7951 case ParsedAttr::AT_HLSLVkExtBuiltinInput:
7952 S.HLSL().handleVkExtBuiltinInputAttr(D, AL);
7953 break;
7954 case ParsedAttr::AT_HLSLVkPushConstant:
7955 S.HLSL().handleVkPushConstantAttr(D, AL);
7956 break;
7957 case ParsedAttr::AT_HLSLVkConstantId:
7958 S.HLSL().handleVkConstantIdAttr(D, AL);
7959 break;
7960 case ParsedAttr::AT_HLSLVkBinding:
7961 S.HLSL().handleVkBindingAttr(D, AL);
7962 break;
7963 case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
7964 handleSimpleAttribute<HLSLGroupSharedAddressSpaceAttr>(S, D, CI: AL);
7965 break;
7966 case ParsedAttr::AT_HLSLPackOffset:
7967 S.HLSL().handlePackOffsetAttr(D, AL);
7968 break;
7969 case ParsedAttr::AT_HLSLShader:
7970 S.HLSL().handleShaderAttr(D, AL);
7971 break;
7972 case ParsedAttr::AT_HLSLResourceBinding:
7973 S.HLSL().handleResourceBindingAttr(D, AL);
7974 break;
7975 case ParsedAttr::AT_HLSLParamModifier:
7976 S.HLSL().handleParamModifierAttr(D, AL);
7977 break;
7978 case ParsedAttr::AT_HLSLUnparsedSemantic:
7979 S.HLSL().handleSemanticAttr(D, AL);
7980 break;
7981 case ParsedAttr::AT_HLSLVkLocation:
7982 S.HLSL().handleVkLocationAttr(D, AL);
7983 break;
7984
7985 case ParsedAttr::AT_AbiTag:
7986 handleAbiTagAttr(S, D, AL);
7987 break;
7988 case ParsedAttr::AT_CFGuard:
7989 handleCFGuardAttr(S, D, AL);
7990 break;
7991
7992 // Thread safety attributes:
7993 case ParsedAttr::AT_PtGuardedVar:
7994 handlePtGuardedVarAttr(S, D, AL);
7995 break;
7996 case ParsedAttr::AT_NoSanitize:
7997 handleNoSanitizeAttr(S, D, AL);
7998 break;
7999 case ParsedAttr::AT_NoSanitizeAddress:
8000 handleNoSanitizeAddressAttr(S, D, AL);
8001 break;
8002 case ParsedAttr::AT_NoSanitizeThread:
8003 handleNoSanitizeThreadAttr(S, D, AL);
8004 break;
8005 case ParsedAttr::AT_NoSanitizeMemory:
8006 handleNoSanitizeMemoryAttr(S, D, AL);
8007 break;
8008 case ParsedAttr::AT_GuardedBy:
8009 handleGuardedByAttr(S, D, AL);
8010 break;
8011 case ParsedAttr::AT_PtGuardedBy:
8012 handlePtGuardedByAttr(S, D, AL);
8013 break;
8014 case ParsedAttr::AT_LockReturned:
8015 handleLockReturnedAttr(S, D, AL);
8016 break;
8017 case ParsedAttr::AT_LocksExcluded:
8018 handleLocksExcludedAttr(S, D, AL);
8019 break;
8020 case ParsedAttr::AT_AcquiredBefore:
8021 handleAcquiredBeforeAttr(S, D, AL);
8022 break;
8023 case ParsedAttr::AT_AcquiredAfter:
8024 handleAcquiredAfterAttr(S, D, AL);
8025 break;
8026
8027 // Capability analysis attributes.
8028 case ParsedAttr::AT_Capability:
8029 case ParsedAttr::AT_Lockable:
8030 handleCapabilityAttr(S, D, AL);
8031 break;
8032 case ParsedAttr::AT_ReentrantCapability:
8033 handleReentrantCapabilityAttr(S, D, AL);
8034 break;
8035 case ParsedAttr::AT_RequiresCapability:
8036 handleRequiresCapabilityAttr(S, D, AL);
8037 break;
8038
8039 case ParsedAttr::AT_AssertCapability:
8040 handleAssertCapabilityAttr(S, D, AL);
8041 break;
8042 case ParsedAttr::AT_AcquireCapability:
8043 handleAcquireCapabilityAttr(S, D, AL);
8044 break;
8045 case ParsedAttr::AT_ReleaseCapability:
8046 handleReleaseCapabilityAttr(S, D, AL);
8047 break;
8048 case ParsedAttr::AT_TryAcquireCapability:
8049 handleTryAcquireCapabilityAttr(S, D, AL);
8050 break;
8051
8052 // Consumed analysis attributes.
8053 case ParsedAttr::AT_Consumable:
8054 handleConsumableAttr(S, D, AL);
8055 break;
8056 case ParsedAttr::AT_CallableWhen:
8057 handleCallableWhenAttr(S, D, AL);
8058 break;
8059 case ParsedAttr::AT_ParamTypestate:
8060 handleParamTypestateAttr(S, D, AL);
8061 break;
8062 case ParsedAttr::AT_ReturnTypestate:
8063 handleReturnTypestateAttr(S, D, AL);
8064 break;
8065 case ParsedAttr::AT_SetTypestate:
8066 handleSetTypestateAttr(S, D, AL);
8067 break;
8068 case ParsedAttr::AT_TestTypestate:
8069 handleTestTypestateAttr(S, D, AL);
8070 break;
8071
8072 // Type safety attributes.
8073 case ParsedAttr::AT_ArgumentWithTypeTag:
8074 handleArgumentWithTypeTagAttr(S, D, AL);
8075 break;
8076 case ParsedAttr::AT_TypeTagForDatatype:
8077 handleTypeTagForDatatypeAttr(S, D, AL);
8078 break;
8079
8080 // Swift attributes.
8081 case ParsedAttr::AT_SwiftAsyncName:
8082 S.Swift().handleAsyncName(D, AL);
8083 break;
8084 case ParsedAttr::AT_SwiftAttr:
8085 S.Swift().handleAttrAttr(D, AL);
8086 break;
8087 case ParsedAttr::AT_SwiftBridge:
8088 S.Swift().handleBridge(D, AL);
8089 break;
8090 case ParsedAttr::AT_SwiftError:
8091 S.Swift().handleError(D, AL);
8092 break;
8093 case ParsedAttr::AT_SwiftName:
8094 S.Swift().handleName(D, AL);
8095 break;
8096 case ParsedAttr::AT_SwiftNewType:
8097 S.Swift().handleNewType(D, AL);
8098 break;
8099 case ParsedAttr::AT_SwiftAsync:
8100 S.Swift().handleAsyncAttr(D, AL);
8101 break;
8102 case ParsedAttr::AT_SwiftAsyncError:
8103 S.Swift().handleAsyncError(D, AL);
8104 break;
8105
8106 // XRay attributes.
8107 case ParsedAttr::AT_XRayLogArgs:
8108 handleXRayLogArgsAttr(S, D, AL);
8109 break;
8110
8111 case ParsedAttr::AT_PatchableFunctionEntry:
8112 handlePatchableFunctionEntryAttr(S, D, AL);
8113 break;
8114
8115 case ParsedAttr::AT_AlwaysDestroy:
8116 case ParsedAttr::AT_NoDestroy:
8117 handleDestroyAttr(S, D, A: AL);
8118 break;
8119
8120 case ParsedAttr::AT_Uninitialized:
8121 handleUninitializedAttr(S, D, AL);
8122 break;
8123
8124 case ParsedAttr::AT_ObjCExternallyRetained:
8125 S.ObjC().handleExternallyRetainedAttr(D, AL);
8126 break;
8127
8128 case ParsedAttr::AT_MIGServerRoutine:
8129 handleMIGServerRoutineAttr(S, D, AL);
8130 break;
8131
8132 case ParsedAttr::AT_MSAllocator:
8133 handleMSAllocatorAttr(S, D, AL);
8134 break;
8135
8136 case ParsedAttr::AT_ArmBuiltinAlias:
8137 S.ARM().handleBuiltinAliasAttr(D, AL);
8138 break;
8139
8140 case ParsedAttr::AT_ArmLocallyStreaming:
8141 handleSimpleAttribute<ArmLocallyStreamingAttr>(S, D, CI: AL);
8142 break;
8143
8144 case ParsedAttr::AT_ArmNew:
8145 S.ARM().handleNewAttr(D, AL);
8146 break;
8147
8148 case ParsedAttr::AT_AcquireHandle:
8149 handleAcquireHandleAttr(S, D, AL);
8150 break;
8151
8152 case ParsedAttr::AT_ReleaseHandle:
8153 handleHandleAttr<ReleaseHandleAttr>(S, D, AL);
8154 break;
8155
8156 case ParsedAttr::AT_UnsafeBufferUsage:
8157 handleUnsafeBufferUsage<UnsafeBufferUsageAttr>(S, D, AL);
8158 break;
8159
8160 case ParsedAttr::AT_UseHandle:
8161 handleHandleAttr<UseHandleAttr>(S, D, AL);
8162 break;
8163
8164 case ParsedAttr::AT_EnforceTCB:
8165 handleEnforceTCBAttr<EnforceTCBAttr, EnforceTCBLeafAttr>(S, D, AL);
8166 break;
8167
8168 case ParsedAttr::AT_EnforceTCBLeaf:
8169 handleEnforceTCBAttr<EnforceTCBLeafAttr, EnforceTCBAttr>(S, D, AL);
8170 break;
8171
8172 case ParsedAttr::AT_BuiltinAlias:
8173 handleBuiltinAliasAttr(S, D, AL);
8174 break;
8175
8176 case ParsedAttr::AT_PreferredType:
8177 handlePreferredTypeAttr(S, D, AL);
8178 break;
8179
8180 case ParsedAttr::AT_UsingIfExists:
8181 handleSimpleAttribute<UsingIfExistsAttr>(S, D, CI: AL);
8182 break;
8183
8184 case ParsedAttr::AT_TypeNullable:
8185 handleNullableTypeAttr(S, D, AL);
8186 break;
8187
8188 case ParsedAttr::AT_VTablePointerAuthentication:
8189 handleVTablePointerAuthentication(S, D, AL);
8190 break;
8191
8192 case ParsedAttr::AT_ModularFormat:
8193 handleModularFormat(S, D, AL);
8194 break;
8195
8196 case ParsedAttr::AT_MSStruct:
8197 handleMSStructAttr(S, D, AL);
8198 break;
8199
8200 case ParsedAttr::AT_GCCStruct:
8201 handleGCCStructAttr(S, D, AL);
8202 break;
8203
8204 case ParsedAttr::AT_PointerFieldProtection:
8205 if (!S.getLangOpts().PointerFieldProtectionAttr)
8206 S.Diag(Loc: AL.getLoc(),
8207 DiagID: diag::err_attribute_pointer_field_protection_experimental)
8208 << AL << AL.isRegularKeywordAttribute() << D->getLocation();
8209 handleSimpleAttribute<PointerFieldProtectionAttr>(S, D, CI: AL);
8210 break;
8211 }
8212}
8213
8214static bool isKernelDecl(Decl *D) {
8215 const FunctionType *FnTy = D->getFunctionType();
8216 return D->hasAttr<DeviceKernelAttr>() ||
8217 (FnTy && FnTy->getCallConv() == CallingConv::CC_DeviceKernel) ||
8218 D->hasAttr<CUDAGlobalAttr>();
8219}
8220
8221void Sema::ProcessDeclAttributeList(
8222 Scope *S, Decl *D, const ParsedAttributesView &AttrList,
8223 const ProcessDeclAttributeOptions &Options) {
8224 if (AttrList.empty())
8225 return;
8226
8227 for (const ParsedAttr &AL : AttrList)
8228 ProcessDeclAttribute(S&: *this, scope: S, D, AL, Options);
8229
8230 // FIXME: We should be able to handle these cases in TableGen.
8231 // GCC accepts
8232 // static int a9 __attribute__((weakref));
8233 // but that looks really pointless. We reject it.
8234 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
8235 Diag(Loc: AttrList.begin()->getLoc(), DiagID: diag::err_attribute_weakref_without_alias)
8236 << cast<NamedDecl>(Val: D);
8237 D->dropAttr<WeakRefAttr>();
8238 return;
8239 }
8240
8241 // FIXME: We should be able to handle this in TableGen as well. It would be
8242 // good to have a way to specify "these attributes must appear as a group",
8243 // for these. Additionally, it would be good to have a way to specify "these
8244 // attribute must never appear as a group" for attributes like cold and hot.
8245 if (!(D->hasAttr<DeviceKernelAttr>() ||
8246 (D->hasAttr<CUDAGlobalAttr>() &&
8247 Context.getTargetInfo().getTriple().isSPIRV()))) {
8248 // These attributes cannot be applied to a non-kernel function.
8249 if (const auto *A = D->getAttr<ReqdWorkGroupSizeAttr>()) {
8250 // FIXME: This emits a different error message than
8251 // diag::err_attribute_wrong_decl_type + ExpectedKernelFunction.
8252 Diag(Loc: D->getLocation(), DiagID: diag::err_opencl_kernel_attr) << A;
8253 D->setInvalidDecl();
8254 } else if (const auto *A = D->getAttr<WorkGroupSizeHintAttr>()) {
8255 Diag(Loc: D->getLocation(), DiagID: diag::err_opencl_kernel_attr) << A;
8256 D->setInvalidDecl();
8257 } else if (const auto *A = D->getAttr<VecTypeHintAttr>()) {
8258 Diag(Loc: D->getLocation(), DiagID: diag::err_opencl_kernel_attr) << A;
8259 D->setInvalidDecl();
8260 } else if (const auto *A = D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {
8261 Diag(Loc: D->getLocation(), DiagID: diag::err_opencl_kernel_attr) << A;
8262 D->setInvalidDecl();
8263 }
8264 }
8265 if (!isKernelDecl(D)) {
8266 if (const auto *A = D->getAttr<AMDGPUFlatWorkGroupSizeAttr>()) {
8267 Diag(Loc: D->getLocation(), DiagID: diag::err_attribute_wrong_decl_type)
8268 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8269 D->setInvalidDecl();
8270 } else if (const auto *A = D->getAttr<AMDGPUWavesPerEUAttr>()) {
8271 Diag(Loc: D->getLocation(), DiagID: diag::err_attribute_wrong_decl_type)
8272 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8273 D->setInvalidDecl();
8274 } else if (const auto *A = D->getAttr<AMDGPUNumSGPRAttr>()) {
8275 Diag(Loc: D->getLocation(), DiagID: diag::err_attribute_wrong_decl_type)
8276 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8277 D->setInvalidDecl();
8278 } else if (const auto *A = D->getAttr<AMDGPUNumVGPRAttr>()) {
8279 Diag(Loc: D->getLocation(), DiagID: diag::err_attribute_wrong_decl_type)
8280 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8281 D->setInvalidDecl();
8282 }
8283 }
8284
8285 // CUDA/HIP: restrict explicit CUDA target attributes on deduction guides.
8286 //
8287 // Deduction guides are not callable functions and never participate in
8288 // codegen; they are always treated as host+device for CUDA/HIP semantic
8289 // checks. We therefore allow either no CUDA target attributes or an explicit
8290 // '__host__ __device__' annotation, but reject guides that are host-only,
8291 // device-only, or marked '__global__'. The use of explicit CUDA/HIP target
8292 // attributes on deduction guides is deprecated and will be rejected in a
8293 // future Clang version.
8294 if (getLangOpts().CUDA)
8295 if (auto *Guide = dyn_cast<CXXDeductionGuideDecl>(Val: D)) {
8296 bool HasHost = Guide->hasAttr<CUDAHostAttr>();
8297 bool HasDevice = Guide->hasAttr<CUDADeviceAttr>();
8298 bool HasGlobal = Guide->hasAttr<CUDAGlobalAttr>();
8299
8300 if (HasGlobal || HasHost != HasDevice) {
8301 Diag(Loc: Guide->getLocation(), DiagID: diag::err_deduction_guide_target_attr);
8302 Guide->setInvalidDecl();
8303 } else if (HasHost && HasDevice) {
8304 Diag(Loc: Guide->getLocation(),
8305 DiagID: diag::warn_deduction_guide_target_attr_deprecated);
8306 }
8307 }
8308
8309 // Do not permit 'constructor' or 'destructor' attributes on __device__ code.
8310 if (getLangOpts().CUDAIsDevice && D->hasAttr<CUDADeviceAttr>() &&
8311 (D->hasAttr<ConstructorAttr>() || D->hasAttr<DestructorAttr>()) &&
8312 !getLangOpts().GPUAllowDeviceInit) {
8313 Diag(Loc: D->getLocation(), DiagID: diag::err_cuda_ctor_dtor_attrs)
8314 << (D->hasAttr<ConstructorAttr>() ? "constructors" : "destructors");
8315 D->setInvalidDecl();
8316 }
8317
8318 // Do this check after processing D's attributes because the attribute
8319 // objc_method_family can change whether the given method is in the init
8320 // family, and it can be applied after objc_designated_initializer. This is a
8321 // bit of a hack, but we need it to be compatible with versions of clang that
8322 // processed the attribute list in the wrong order.
8323 if (D->hasAttr<ObjCDesignatedInitializerAttr>() &&
8324 cast<ObjCMethodDecl>(Val: D)->getMethodFamily() != OMF_init) {
8325 Diag(Loc: D->getLocation(), DiagID: diag::err_designated_init_attr_non_init);
8326 D->dropAttr<ObjCDesignatedInitializerAttr>();
8327 }
8328}
8329
8330void Sema::ProcessDeclAttributeDelayed(Decl *D,
8331 const ParsedAttributesView &AttrList) {
8332 for (const ParsedAttr &AL : AttrList)
8333 if (AL.getKind() == ParsedAttr::AT_TransparentUnion) {
8334 handleTransparentUnionAttr(S&: *this, D, AL);
8335 break;
8336 }
8337
8338 // For BPFPreserveAccessIndexAttr, we want to populate the attributes
8339 // to fields and inner records as well.
8340 if (D && D->hasAttr<BPFPreserveAccessIndexAttr>())
8341 BPF().handlePreserveAIRecord(RD: cast<RecordDecl>(Val: D));
8342}
8343
8344bool Sema::ProcessAccessDeclAttributeList(
8345 AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList) {
8346 for (const ParsedAttr &AL : AttrList) {
8347 if (AL.getKind() == ParsedAttr::AT_Annotate) {
8348 ProcessDeclAttribute(S&: *this, scope: nullptr, D: ASDecl, AL,
8349 Options: ProcessDeclAttributeOptions());
8350 } else {
8351 Diag(Loc: AL.getLoc(), DiagID: diag::err_only_annotate_after_access_spec);
8352 return true;
8353 }
8354 }
8355 return false;
8356}
8357
8358/// checkUnusedDeclAttributes - Check a list of attributes to see if it
8359/// contains any decl attributes that we should warn about.
8360static void checkUnusedDeclAttributes(Sema &S, const ParsedAttributesView &A) {
8361 for (const ParsedAttr &AL : A) {
8362 // Only warn if the attribute is an unignored, non-type attribute.
8363 if (AL.isUsedAsTypeAttr() || AL.isInvalid())
8364 continue;
8365 if (AL.getKind() == ParsedAttr::IgnoredAttribute)
8366 continue;
8367
8368 if (AL.getKind() == ParsedAttr::UnknownAttribute) {
8369 S.DiagnoseUnknownAttribute(AL);
8370 } else {
8371 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_not_on_decl) << AL
8372 << AL.getRange();
8373 }
8374 }
8375}
8376
8377void Sema::checkUnusedDeclAttributes(Declarator &D) {
8378 ::checkUnusedDeclAttributes(S&: *this, A: D.getDeclarationAttributes());
8379 ::checkUnusedDeclAttributes(S&: *this, A: D.getDeclSpec().getAttributes());
8380 ::checkUnusedDeclAttributes(S&: *this, A: D.getAttributes());
8381 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
8382 ::checkUnusedDeclAttributes(S&: *this, A: D.getTypeObject(i).getAttrs());
8383}
8384
8385void Sema::DiagnoseUnknownAttribute(const ParsedAttr &AL) {
8386 SourceRange NR = AL.getNormalizedRange();
8387 StringRef ScopeName = AL.getNormalizedScopeName();
8388 std::optional<StringRef> CorrectedScopeName =
8389 AL.tryGetCorrectedScopeName(ScopeName);
8390 if (CorrectedScopeName) {
8391 ScopeName = *CorrectedScopeName;
8392 }
8393
8394 StringRef AttrName = AL.getNormalizedAttrName(ScopeName);
8395 std::optional<StringRef> CorrectedAttrName = AL.tryGetCorrectedAttrName(
8396 ScopeName, AttrName, Target: Context.getTargetInfo(), LangOpts: getLangOpts());
8397 if (CorrectedAttrName) {
8398 AttrName = *CorrectedAttrName;
8399 }
8400
8401 if (CorrectedScopeName || CorrectedAttrName) {
8402 std::string CorrectedFullName =
8403 AL.getNormalizedFullName(ScopeName, AttrName);
8404 SemaDiagnosticBuilder D =
8405 Diag(Loc: CorrectedScopeName ? NR.getBegin() : AL.getRange().getBegin(),
8406 DiagID: diag::warn_unknown_attribute_ignored_suggestion);
8407
8408 D << AL << CorrectedFullName;
8409
8410 if (AL.isExplicitScope()) {
8411 D << FixItHint::CreateReplacement(RemoveRange: NR, Code: CorrectedFullName) << NR;
8412 } else {
8413 if (CorrectedScopeName) {
8414 D << FixItHint::CreateReplacement(RemoveRange: SourceRange(AL.getScopeLoc()),
8415 Code: ScopeName);
8416 }
8417 if (CorrectedAttrName) {
8418 D << FixItHint::CreateReplacement(RemoveRange: AL.getRange(), Code: AttrName);
8419 }
8420 }
8421 } else {
8422 Diag(Loc: NR.getBegin(), DiagID: diag::warn_unknown_attribute_ignored) << AL << NR;
8423 }
8424}
8425
8426NamedDecl *Sema::DeclClonePragmaWeak(NamedDecl *ND, const IdentifierInfo *II,
8427 SourceLocation Loc) {
8428 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
8429 NamedDecl *NewD = nullptr;
8430 if (auto *FD = dyn_cast<FunctionDecl>(Val: ND)) {
8431 FunctionDecl *NewFD;
8432 // FIXME: Missing call to CheckFunctionDeclaration().
8433 // FIXME: Mangling?
8434 // FIXME: Is the qualifier info correct?
8435 // FIXME: Is the DeclContext correct?
8436 NewFD = FunctionDecl::Create(
8437 C&: FD->getASTContext(), DC: FD->getDeclContext(), StartLoc: Loc, NLoc: Loc,
8438 N: DeclarationName(II), T: FD->getType(), TInfo: FD->getTypeSourceInfo(), SC: SC_None,
8439 UsesFPIntrin: getCurFPFeatures().isFPConstrained(), isInlineSpecified: false /*isInlineSpecified*/,
8440 hasWrittenPrototype: FD->hasPrototype(), ConstexprKind: ConstexprSpecKind::Unspecified,
8441 TrailingRequiresClause: FD->getTrailingRequiresClause());
8442 NewD = NewFD;
8443
8444 if (FD->getQualifier())
8445 NewFD->setQualifierInfo(FD->getQualifierLoc());
8446
8447 // Fake up parameter variables; they are declared as if this were
8448 // a typedef.
8449 QualType FDTy = FD->getType();
8450 if (const auto *FT = FDTy->getAs<FunctionProtoType>()) {
8451 SmallVector<ParmVarDecl*, 16> Params;
8452 for (const auto &AI : FT->param_types()) {
8453 ParmVarDecl *Param = BuildParmVarDeclForTypedef(DC: NewFD, Loc, T: AI);
8454 Param->setScopeInfo(scopeDepth: 0, parameterIndex: Params.size());
8455 Params.push_back(Elt: Param);
8456 }
8457 NewFD->setParams(Params);
8458 }
8459 } else if (auto *VD = dyn_cast<VarDecl>(Val: ND)) {
8460 NewD = VarDecl::Create(C&: VD->getASTContext(), DC: VD->getDeclContext(),
8461 StartLoc: VD->getInnerLocStart(), IdLoc: VD->getLocation(), Id: II,
8462 T: VD->getType(), TInfo: VD->getTypeSourceInfo(),
8463 S: VD->getStorageClass());
8464 if (VD->getQualifier())
8465 cast<VarDecl>(Val: NewD)->setQualifierInfo(VD->getQualifierLoc());
8466 }
8467 return NewD;
8468}
8469
8470void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, const WeakInfo &W) {
8471 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
8472 IdentifierInfo *NDId = ND->getIdentifier();
8473 NamedDecl *NewD = DeclClonePragmaWeak(ND, II: W.getAlias(), Loc: W.getLocation());
8474 NewD->addAttr(
8475 A: AliasAttr::CreateImplicit(Ctx&: Context, Aliasee: NDId->getName(), Range: W.getLocation()));
8476 NewD->addAttr(A: WeakAttr::CreateImplicit(Ctx&: Context, Range: W.getLocation()));
8477 WeakTopLevelDecl.push_back(Elt: NewD);
8478 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
8479 // to insert Decl at TU scope, sorry.
8480 DeclContext *SavedContext = CurContext;
8481 CurContext = Context.getTranslationUnitDecl();
8482 NewD->setDeclContext(CurContext);
8483 NewD->setLexicalDeclContext(CurContext);
8484 PushOnScopeChains(D: NewD, S);
8485 CurContext = SavedContext;
8486 } else { // just add weak to existing
8487 ND->addAttr(A: WeakAttr::CreateImplicit(Ctx&: Context, Range: W.getLocation()));
8488 }
8489}
8490
8491void Sema::ProcessPragmaWeak(Scope *S, Decl *D) {
8492 // It's valid to "forward-declare" #pragma weak, in which case we
8493 // have to do this.
8494 LoadExternalWeakUndeclaredIdentifiers();
8495 if (WeakUndeclaredIdentifiers.empty())
8496 return;
8497 NamedDecl *ND = nullptr;
8498 if (auto *VD = dyn_cast<VarDecl>(Val: D))
8499 if (VD->isExternC())
8500 ND = VD;
8501 if (auto *FD = dyn_cast<FunctionDecl>(Val: D))
8502 if (FD->isExternC())
8503 ND = FD;
8504 if (!ND)
8505 return;
8506 if (IdentifierInfo *Id = ND->getIdentifier()) {
8507 auto I = WeakUndeclaredIdentifiers.find(Key: Id);
8508 if (I != WeakUndeclaredIdentifiers.end()) {
8509 auto &WeakInfos = I->second;
8510 for (const auto &W : WeakInfos)
8511 DeclApplyPragmaWeak(S, ND, W);
8512 std::remove_reference_t<decltype(WeakInfos)> EmptyWeakInfos;
8513 WeakInfos.swap(RHS&: EmptyWeakInfos);
8514 }
8515 }
8516}
8517
8518/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
8519/// it, apply them to D. This is a bit tricky because PD can have attributes
8520/// specified in many different places, and we need to find and apply them all.
8521void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
8522 // Ordering of attributes can be important, so we take care to process
8523 // attributes in the order in which they appeared in the source code.
8524
8525 auto ProcessAttributesWithSliding =
8526 [&](const ParsedAttributesView &Src,
8527 const ProcessDeclAttributeOptions &Options) {
8528 ParsedAttributesView NonSlidingAttrs;
8529 for (ParsedAttr &AL : Src) {
8530 // FIXME: this sliding is specific to standard attributes and should
8531 // eventually be deprecated and removed as those are not intended to
8532 // slide to anything.
8533 if ((AL.isStandardAttributeSyntax() || AL.isAlignas()) &&
8534 AL.slidesFromDeclToDeclSpecLegacyBehavior()) {
8535 // Skip processing the attribute, but do check if it appertains to
8536 // the declaration. This is needed for the `MatrixType` attribute,
8537 // which, despite being a type attribute, defines a `SubjectList`
8538 // that only allows it to be used on typedef declarations.
8539 AL.diagnoseAppertainsTo(S&: *this, D);
8540 } else {
8541 NonSlidingAttrs.addAtEnd(newAttr: &AL);
8542 }
8543 }
8544 ProcessDeclAttributeList(S, D, AttrList: NonSlidingAttrs, Options);
8545 };
8546
8547 // First, process attributes that appeared on the declaration itself (but
8548 // only if they don't have the legacy behavior of "sliding" to the DeclSepc).
8549 ProcessAttributesWithSliding(PD.getDeclarationAttributes(), {});
8550
8551 // Apply decl attributes from the DeclSpec if present.
8552 ProcessAttributesWithSliding(PD.getDeclSpec().getAttributes(),
8553 ProcessDeclAttributeOptions()
8554 .WithIncludeCXX11Attributes(Val: false)
8555 .WithIgnoreTypeAttributes(Val: true));
8556
8557 // Walk the declarator structure, applying decl attributes that were in a type
8558 // position to the decl itself. This handles cases like:
8559 // int *__attr__(x)** D;
8560 // when X is a decl attribute.
8561 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) {
8562 ProcessDeclAttributeList(S, D, AttrList: PD.getTypeObject(i).getAttrs(),
8563 Options: ProcessDeclAttributeOptions()
8564 .WithIncludeCXX11Attributes(Val: false)
8565 .WithIgnoreTypeAttributes(Val: true));
8566 }
8567
8568 // Finally, apply any attributes on the decl itself.
8569 ProcessDeclAttributeList(S, D, AttrList: PD.getAttributes());
8570
8571 // Apply additional attributes specified by '#pragma clang attribute'.
8572 AddPragmaAttributes(S, D);
8573
8574 // Look for API notes that map to attributes.
8575 ProcessAPINotes(D);
8576}
8577
8578/// Is the given declaration allowed to use a forbidden type?
8579/// If so, it'll still be annotated with an attribute that makes it
8580/// illegal to actually use.
8581static bool isForbiddenTypeAllowed(Sema &S, Decl *D,
8582 const DelayedDiagnostic &diag,
8583 UnavailableAttr::ImplicitReason &reason) {
8584 // Private ivars are always okay. Unfortunately, people don't
8585 // always properly make their ivars private, even in system headers.
8586 // Plus we need to make fields okay, too.
8587 if (!isa<FieldDecl>(Val: D) && !isa<ObjCPropertyDecl>(Val: D) &&
8588 !isa<FunctionDecl>(Val: D))
8589 return false;
8590
8591 // Silently accept unsupported uses of __weak in both user and system
8592 // declarations when it's been disabled, for ease of integration with
8593 // -fno-objc-arc files. We do have to take some care against attempts
8594 // to define such things; for now, we've only done that for ivars
8595 // and properties.
8596 if ((isa<ObjCIvarDecl>(Val: D) || isa<ObjCPropertyDecl>(Val: D))) {
8597 if (diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_disabled ||
8598 diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_no_runtime) {
8599 reason = UnavailableAttr::IR_ForbiddenWeak;
8600 return true;
8601 }
8602 }
8603
8604 // Allow all sorts of things in system headers.
8605 if (S.Context.getSourceManager().isInSystemHeader(Loc: D->getLocation())) {
8606 // Currently, all the failures dealt with this way are due to ARC
8607 // restrictions.
8608 reason = UnavailableAttr::IR_ARCForbiddenType;
8609 return true;
8610 }
8611
8612 return false;
8613}
8614
8615/// Handle a delayed forbidden-type diagnostic.
8616static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &DD,
8617 Decl *D) {
8618 auto Reason = UnavailableAttr::IR_None;
8619 if (D && isForbiddenTypeAllowed(S, D, diag: DD, reason&: Reason)) {
8620 assert(Reason && "didn't set reason?");
8621 D->addAttr(A: UnavailableAttr::CreateImplicit(Ctx&: S.Context, Message: "", ImplicitReason: Reason, Range: DD.Loc));
8622 return;
8623 }
8624 if (S.getLangOpts().ObjCAutoRefCount)
8625 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
8626 // FIXME: we may want to suppress diagnostics for all
8627 // kind of forbidden type messages on unavailable functions.
8628 if (FD->hasAttr<UnavailableAttr>() &&
8629 DD.getForbiddenTypeDiagnostic() ==
8630 diag::err_arc_array_param_no_ownership) {
8631 DD.Triggered = true;
8632 return;
8633 }
8634 }
8635
8636 S.Diag(Loc: DD.Loc, DiagID: DD.getForbiddenTypeDiagnostic())
8637 << DD.getForbiddenTypeOperand() << DD.getForbiddenTypeArgument();
8638 DD.Triggered = true;
8639}
8640
8641
8642void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
8643 assert(DelayedDiagnostics.getCurrentPool());
8644 DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool();
8645 DelayedDiagnostics.popWithoutEmitting(state);
8646
8647 // When delaying diagnostics to run in the context of a parsed
8648 // declaration, we only want to actually emit anything if parsing
8649 // succeeds.
8650 if (!decl) return;
8651
8652 // We emit all the active diagnostics in this pool or any of its
8653 // parents. In general, we'll get one pool for the decl spec
8654 // and a child pool for each declarator; in a decl group like:
8655 // deprecated_typedef foo, *bar, baz();
8656 // only the declarator pops will be passed decls. This is correct;
8657 // we really do need to consider delayed diagnostics from the decl spec
8658 // for each of the different declarations.
8659 const DelayedDiagnosticPool *pool = &poppedPool;
8660 do {
8661 bool AnyAccessFailures = false;
8662 for (DelayedDiagnosticPool::pool_iterator
8663 i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
8664 // This const_cast is a bit lame. Really, Triggered should be mutable.
8665 DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
8666 if (diag.Triggered)
8667 continue;
8668
8669 switch (diag.Kind) {
8670 case DelayedDiagnostic::Availability:
8671 // Don't bother giving deprecation/unavailable diagnostics if
8672 // the decl is invalid.
8673 if (!decl->isInvalidDecl())
8674 handleDelayedAvailabilityCheck(DD&: diag, Ctx: decl);
8675 break;
8676
8677 case DelayedDiagnostic::Access:
8678 // Only produce one access control diagnostic for a structured binding
8679 // declaration: we don't need to tell the user that all the fields are
8680 // inaccessible one at a time.
8681 if (AnyAccessFailures && isa<DecompositionDecl>(Val: decl))
8682 continue;
8683 HandleDelayedAccessCheck(DD&: diag, Ctx: decl);
8684 if (diag.Triggered)
8685 AnyAccessFailures = true;
8686 break;
8687
8688 case DelayedDiagnostic::ForbiddenType:
8689 handleDelayedForbiddenType(S&: *this, DD&: diag, D: decl);
8690 break;
8691 }
8692 }
8693 } while ((pool = pool->getParent()));
8694}
8695
8696void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {
8697 DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool();
8698 assert(curPool && "re-emitting in undelayed context not supported");
8699 curPool->steal(pool);
8700}
8701
8702void Sema::ActOnCleanupAttr(Decl *D, const Attr *A) {
8703 VarDecl *VD = cast<VarDecl>(Val: D);
8704 if (VD->getType()->isDependentType())
8705 return;
8706
8707 // Obtains the FunctionDecl that was found when handling the attribute
8708 // earlier.
8709 CleanupAttr *Attr = D->getAttr<CleanupAttr>();
8710 FunctionDecl *FD = Attr->getFunctionDecl();
8711 DeclarationNameInfo NI = FD->getNameInfo();
8712
8713 // We're currently more strict than GCC about what function types we accept.
8714 // If this ever proves to be a problem it should be easy to fix.
8715 QualType Ty = this->Context.getPointerType(T: VD->getType());
8716 QualType ParamTy = FD->getParamDecl(i: 0)->getType();
8717 if (!this->IsAssignConvertCompatible(ConvTy: this->CheckAssignmentConstraints(
8718 Loc: FD->getParamDecl(i: 0)->getLocation(), LHSType: ParamTy, RHSType: Ty))) {
8719 this->Diag(Loc: Attr->getArgLoc(),
8720 DiagID: diag::err_attribute_cleanup_func_arg_incompatible_type)
8721 << NI.getName() << ParamTy << Ty;
8722 D->dropAttr<CleanupAttr>();
8723 return;
8724 }
8725}
8726
8727void Sema::ActOnInitPriorityAttr(Decl *D, const Attr *A) {
8728 QualType T = cast<VarDecl>(Val: D)->getType();
8729 if (this->Context.getAsArrayType(T))
8730 T = this->Context.getBaseElementType(QT: T);
8731 if (!T->isRecordType()) {
8732 this->Diag(Loc: A->getLoc(), DiagID: diag::err_init_priority_object_attr);
8733 D->dropAttr<InitPriorityAttr>();
8734 }
8735}
8736