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