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