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