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