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