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 auto *attr = ::new (S.Context) CleanupAttr(S.Context, AL, FD);
3908 attr->setArgLoc(E->getExprLoc());
3909 D->addAttr(A: attr);
3910}
3911
3912static void handleEnumExtensibilityAttr(Sema &S, Decl *D,
3913 const ParsedAttr &AL) {
3914 if (!AL.isArgIdent(Arg: 0)) {
3915 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
3916 << AL << 0 << AANT_ArgumentIdentifier;
3917 return;
3918 }
3919
3920 EnumExtensibilityAttr::Kind ExtensibilityKind;
3921 IdentifierInfo *II = AL.getArgAsIdent(Arg: 0)->getIdentifierInfo();
3922 if (!EnumExtensibilityAttr::ConvertStrToKind(Val: II->getName(),
3923 Out&: ExtensibilityKind)) {
3924 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_type_not_supported) << AL << II;
3925 return;
3926 }
3927
3928 D->addAttr(A: ::new (S.Context)
3929 EnumExtensibilityAttr(S.Context, AL, ExtensibilityKind));
3930}
3931
3932/// Handle __attribute__((format_arg((idx)))) attribute based on
3933/// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
3934static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
3935 const Expr *IdxExpr = AL.getArgAsExpr(Arg: 0);
3936 ParamIdx Idx;
3937 if (!S.checkFunctionOrMethodParameterIndex(D, AI: AL, AttrArgNum: 1, IdxExpr, Idx))
3938 return;
3939
3940 // Make sure the format string is really a string.
3941 QualType Ty = getFunctionOrMethodParamType(D, Idx: Idx.getASTIndex());
3942
3943 bool NotNSStringTy = !S.ObjC().isNSStringType(T: Ty);
3944 if (NotNSStringTy && !S.ObjC().isCFStringType(T: Ty) &&
3945 (!Ty->isPointerType() ||
3946 !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
3947 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_format_attribute_not)
3948 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, Idx: 0);
3949 return;
3950 }
3951 Ty = getFunctionOrMethodResultType(D);
3952 // replace instancetype with the class type
3953 auto *Instancetype = cast<TypedefType>(Val: S.Context.getTypedefType(
3954 Keyword: ElaboratedTypeKeyword::None, /*Qualifier=*/std::nullopt,
3955 Decl: S.Context.getObjCInstanceTypeDecl()));
3956 if (Ty->getAs<TypedefType>() == Instancetype)
3957 if (auto *OMD = dyn_cast<ObjCMethodDecl>(Val: D))
3958 if (auto *Interface = OMD->getClassInterface())
3959 Ty = S.Context.getObjCObjectPointerType(
3960 OIT: QualType(Interface->getTypeForDecl(), 0));
3961 if (!S.ObjC().isNSStringType(T: Ty, /*AllowNSAttributedString=*/true) &&
3962 !S.ObjC().isCFStringType(T: Ty) &&
3963 (!Ty->isPointerType() ||
3964 !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
3965 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_format_attribute_result_not)
3966 << (NotNSStringTy ? "string type" : "NSString")
3967 << IdxExpr->getSourceRange() << getFunctionOrMethodParamRange(D, Idx: 0);
3968 return;
3969 }
3970
3971 D->addAttr(A: ::new (S.Context) FormatArgAttr(S.Context, AL, Idx));
3972}
3973
3974enum FormatAttrKind {
3975 CFStringFormat,
3976 NSStringFormat,
3977 StrftimeFormat,
3978 SupportedFormat,
3979 IgnoredFormat,
3980 InvalidFormat
3981};
3982
3983/// getFormatAttrKind - Map from format attribute names to supported format
3984/// types.
3985static FormatAttrKind getFormatAttrKind(StringRef Format) {
3986 return llvm::StringSwitch<FormatAttrKind>(Format)
3987 // Check for formats that get handled specially.
3988 .Case(S: "NSString", Value: NSStringFormat)
3989 .Case(S: "CFString", Value: CFStringFormat)
3990 .Cases(CaseStrings: {"gnu_strftime", "strftime"}, Value: StrftimeFormat)
3991
3992 // Otherwise, check for supported formats.
3993 .Cases(CaseStrings: {"gnu_scanf", "scanf", "gnu_printf", "printf", "printf0",
3994 "gnu_strfmon", "strfmon"},
3995 Value: SupportedFormat)
3996 .Cases(CaseStrings: {"cmn_err", "vcmn_err", "zcmn_err"}, Value: SupportedFormat)
3997 .Cases(CaseStrings: {"kprintf", "syslog"}, Value: SupportedFormat) // OpenBSD.
3998 .Case(S: "freebsd_kprintf", Value: SupportedFormat) // FreeBSD.
3999 .Case(S: "os_trace", Value: SupportedFormat)
4000 .Case(S: "os_log", Value: SupportedFormat)
4001
4002 .Cases(CaseStrings: {"gcc_diag", "gcc_cdiag", "gcc_cxxdiag", "gcc_tdiag"},
4003 Value: IgnoredFormat)
4004 .Default(Value: InvalidFormat);
4005}
4006
4007/// Handle __attribute__((init_priority(priority))) attributes based on
4008/// http://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Attributes.html
4009static void handleInitPriorityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4010 if (!S.getLangOpts().CPlusPlus) {
4011 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_ignored) << AL;
4012 return;
4013 }
4014
4015 if (S.getLangOpts().HLSL) {
4016 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_hlsl_init_priority_unsupported);
4017 return;
4018 }
4019
4020 if (S.getCurFunctionOrMethodDecl()) {
4021 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_init_priority_object_attr);
4022 AL.setInvalid();
4023 return;
4024 }
4025
4026 Expr *E = AL.getArgAsExpr(Arg: 0);
4027 uint32_t prioritynum;
4028 if (!S.checkUInt32Argument(AI: AL, Expr: E, Val&: prioritynum)) {
4029 AL.setInvalid();
4030 return;
4031 }
4032
4033 if (prioritynum > 65535) {
4034 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_out_of_range)
4035 << E->getSourceRange() << AL << 0 << 65535;
4036 AL.setInvalid();
4037 return;
4038 }
4039
4040 // Values <= 100 are reserved for the implementation, and libc++
4041 // benefits from being able to specify values in that range.
4042 if (prioritynum < 101)
4043 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_init_priority_reserved)
4044 << E->getSourceRange() << prioritynum;
4045 D->addAttr(A: ::new (S.Context) InitPriorityAttr(S.Context, AL, prioritynum));
4046}
4047
4048ErrorAttr *Sema::mergeErrorAttr(Decl *D, const AttributeCommonInfo &CI,
4049 StringRef NewUserDiagnostic) {
4050 if (const auto *EA = D->getAttr<ErrorAttr>()) {
4051 std::string NewAttr = CI.getNormalizedFullName();
4052 assert((NewAttr == "error" || NewAttr == "warning") &&
4053 "unexpected normalized full name");
4054 bool Match = (EA->isError() && NewAttr == "error") ||
4055 (EA->isWarning() && NewAttr == "warning");
4056 if (!Match) {
4057 Diag(Loc: EA->getLocation(), DiagID: diag::err_attributes_are_not_compatible)
4058 << CI << EA
4059 << (CI.isRegularKeywordAttribute() ||
4060 EA->isRegularKeywordAttribute());
4061 Diag(Loc: CI.getLoc(), DiagID: diag::note_conflicting_attribute);
4062 return nullptr;
4063 }
4064 if (EA->getUserDiagnostic() != NewUserDiagnostic) {
4065 Diag(Loc: CI.getLoc(), DiagID: diag::warn_duplicate_attribute) << EA;
4066 Diag(Loc: EA->getLoc(), DiagID: diag::note_previous_attribute);
4067 }
4068 D->dropAttr<ErrorAttr>();
4069 }
4070 return ::new (Context) ErrorAttr(Context, CI, NewUserDiagnostic);
4071}
4072
4073FormatAttr *Sema::mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI,
4074 const IdentifierInfo *Format, int FormatIdx,
4075 int FirstArg) {
4076 // Check whether we already have an equivalent format attribute.
4077 for (auto *F : D->specific_attrs<FormatAttr>()) {
4078 if (F->getType() == Format &&
4079 F->getFormatIdx() == FormatIdx &&
4080 F->getFirstArg() == FirstArg) {
4081 // If we don't have a valid location for this attribute, adopt the
4082 // location.
4083 if (F->getLocation().isInvalid())
4084 F->setRange(CI.getRange());
4085 return nullptr;
4086 }
4087 }
4088
4089 return ::new (Context) FormatAttr(Context, CI, Format, FormatIdx, FirstArg);
4090}
4091
4092FormatMatchesAttr *Sema::mergeFormatMatchesAttr(Decl *D,
4093 const AttributeCommonInfo &CI,
4094 const IdentifierInfo *Format,
4095 int FormatIdx,
4096 StringLiteral *FormatStr) {
4097 // Check whether we already have an equivalent FormatMatches attribute.
4098 for (auto *F : D->specific_attrs<FormatMatchesAttr>()) {
4099 if (F->getType() == Format && F->getFormatIdx() == FormatIdx) {
4100 if (!CheckFormatStringsCompatible(FST: GetFormatStringType(FormatFlavor: Format->getName()),
4101 AuthoritativeFormatString: F->getFormatString(), TestedFormatString: FormatStr))
4102 return nullptr;
4103
4104 // If we don't have a valid location for this attribute, adopt the
4105 // location.
4106 if (F->getLocation().isInvalid())
4107 F->setRange(CI.getRange());
4108 return nullptr;
4109 }
4110 }
4111
4112 return ::new (Context)
4113 FormatMatchesAttr(Context, CI, Format, FormatIdx, FormatStr);
4114}
4115
4116struct FormatAttrCommon {
4117 FormatAttrKind Kind;
4118 IdentifierInfo *Identifier;
4119 unsigned NumArgs;
4120 unsigned FormatStringIdx;
4121};
4122
4123/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
4124/// https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
4125static bool handleFormatAttrCommon(Sema &S, Decl *D, const ParsedAttr &AL,
4126 FormatAttrCommon *Info) {
4127 // Checks the first two arguments of the attribute; this is shared between
4128 // Format and FormatMatches attributes.
4129
4130 if (!AL.isArgIdent(Arg: 0)) {
4131 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
4132 << AL << 1 << AANT_ArgumentIdentifier;
4133 return false;
4134 }
4135
4136 // In C++ the implicit 'this' function parameter also counts, and they are
4137 // counted from one.
4138 bool HasImplicitThisParam = hasImplicitObjectParameter(D);
4139 Info->NumArgs = getFunctionOrMethodNumParams(D) + HasImplicitThisParam;
4140
4141 Info->Identifier = AL.getArgAsIdent(Arg: 0)->getIdentifierInfo();
4142 StringRef Format = Info->Identifier->getName();
4143
4144 if (normalizeName(AttrName&: Format)) {
4145 // If we've modified the string name, we need a new identifier for it.
4146 Info->Identifier = &S.Context.Idents.get(Name: Format);
4147 }
4148
4149 // Check for supported formats.
4150 Info->Kind = getFormatAttrKind(Format);
4151
4152 if (Info->Kind == IgnoredFormat)
4153 return false;
4154
4155 if (Info->Kind == InvalidFormat) {
4156 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_type_not_supported)
4157 << AL << Info->Identifier->getName();
4158 return false;
4159 }
4160
4161 // checks for the 2nd argument
4162 Expr *IdxExpr = AL.getArgAsExpr(Arg: 1);
4163 if (!S.checkUInt32Argument(AI: AL, Expr: IdxExpr, Val&: Info->FormatStringIdx, Idx: 2))
4164 return false;
4165
4166 if (Info->FormatStringIdx < 1 || Info->FormatStringIdx > Info->NumArgs) {
4167 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_out_of_bounds)
4168 << AL << 2 << IdxExpr->getSourceRange();
4169 return false;
4170 }
4171
4172 // FIXME: Do we need to bounds check?
4173 unsigned ArgIdx = Info->FormatStringIdx - 1;
4174
4175 if (HasImplicitThisParam) {
4176 if (ArgIdx == 0) {
4177 S.Diag(Loc: AL.getLoc(),
4178 DiagID: diag::err_format_attribute_implicit_this_format_string)
4179 << IdxExpr->getSourceRange();
4180 return false;
4181 }
4182 ArgIdx--;
4183 }
4184
4185 // make sure the format string is really a string
4186 QualType Ty = getFunctionOrMethodParamType(D, Idx: ArgIdx);
4187
4188 if (!S.ObjC().isNSStringType(T: Ty, AllowNSAttributedString: true) && !S.ObjC().isCFStringType(T: Ty) &&
4189 (!Ty->isPointerType() ||
4190 !Ty->castAs<PointerType>()->getPointeeType()->isCharType())) {
4191 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_format_attribute_not)
4192 << IdxExpr->getSourceRange()
4193 << getFunctionOrMethodParamRange(D, Idx: ArgIdx);
4194 return false;
4195 }
4196
4197 return true;
4198}
4199
4200static void handleFormatAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4201 FormatAttrCommon Info;
4202 if (!handleFormatAttrCommon(S, D, AL, Info: &Info))
4203 return;
4204
4205 // check the 3rd argument
4206 Expr *FirstArgExpr = AL.getArgAsExpr(Arg: 2);
4207 uint32_t FirstArg;
4208 if (!S.checkUInt32Argument(AI: AL, Expr: FirstArgExpr, Val&: FirstArg, Idx: 3))
4209 return;
4210
4211 // FirstArg == 0 is is always valid.
4212 if (FirstArg != 0) {
4213 if (Info.Kind == StrftimeFormat) {
4214 // If the kind is strftime, FirstArg must be 0 because strftime does not
4215 // use any variadic arguments.
4216 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_format_strftime_third_parameter)
4217 << FirstArgExpr->getSourceRange()
4218 << FixItHint::CreateReplacement(RemoveRange: FirstArgExpr->getSourceRange(), Code: "0");
4219 return;
4220 } else if (isFunctionOrMethodVariadic(D)) {
4221 // Else, if the function is variadic, then FirstArg must be 0 or the
4222 // "position" of the ... parameter. It's unusual to use 0 with variadic
4223 // functions, so the fixit proposes the latter.
4224 if (FirstArg != Info.NumArgs + 1) {
4225 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_out_of_bounds)
4226 << AL << 3 << FirstArgExpr->getSourceRange()
4227 << FixItHint::CreateReplacement(RemoveRange: FirstArgExpr->getSourceRange(),
4228 Code: std::to_string(val: Info.NumArgs + 1));
4229 return;
4230 }
4231 } else {
4232 // Inescapable GCC compatibility diagnostic.
4233 S.Diag(Loc: D->getLocation(), DiagID: diag::warn_gcc_requires_variadic_function) << AL;
4234 if (FirstArg <= Info.FormatStringIdx) {
4235 // Else, the function is not variadic, and FirstArg must be 0 or any
4236 // parameter after the format parameter. We don't offer a fixit because
4237 // there are too many possible good values.
4238 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_out_of_bounds)
4239 << AL << 3 << FirstArgExpr->getSourceRange();
4240 return;
4241 }
4242 }
4243 }
4244
4245 FormatAttr *NewAttr =
4246 S.mergeFormatAttr(D, CI: AL, Format: Info.Identifier, FormatIdx: Info.FormatStringIdx, FirstArg);
4247 if (NewAttr)
4248 D->addAttr(A: NewAttr);
4249}
4250
4251static void handleFormatMatchesAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4252 FormatAttrCommon Info;
4253 if (!handleFormatAttrCommon(S, D, AL, Info: &Info))
4254 return;
4255
4256 Expr *FormatStrExpr = AL.getArgAsExpr(Arg: 2)->IgnoreParenImpCasts();
4257 if (auto *SL = dyn_cast<StringLiteral>(Val: FormatStrExpr)) {
4258 FormatStringType FST = S.GetFormatStringType(FormatFlavor: Info.Identifier->getName());
4259 if (S.ValidateFormatString(FST, Str: SL))
4260 if (auto *NewAttr = S.mergeFormatMatchesAttr(D, CI: AL, Format: Info.Identifier,
4261 FormatIdx: Info.FormatStringIdx, FormatStr: SL))
4262 D->addAttr(A: NewAttr);
4263 return;
4264 }
4265
4266 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_format_nonliteral)
4267 << FormatStrExpr->getSourceRange();
4268}
4269
4270/// Handle __attribute__((callback(CalleeIdx, PayloadIdx0, ...))) attributes.
4271static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4272 // The index that identifies the callback callee is mandatory.
4273 if (AL.getNumArgs() == 0) {
4274 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_attribute_no_callee)
4275 << AL.getRange();
4276 return;
4277 }
4278
4279 bool HasImplicitThisParam = hasImplicitObjectParameter(D);
4280 int32_t NumArgs = getFunctionOrMethodNumParams(D);
4281
4282 FunctionDecl *FD = D->getAsFunction();
4283 assert(FD && "Expected a function declaration!");
4284
4285 llvm::StringMap<int> NameIdxMapping;
4286 NameIdxMapping["__"] = -1;
4287
4288 NameIdxMapping["this"] = 0;
4289
4290 int Idx = 1;
4291 for (const ParmVarDecl *PVD : FD->parameters())
4292 NameIdxMapping[PVD->getName()] = Idx++;
4293
4294 auto UnknownName = NameIdxMapping.end();
4295
4296 SmallVector<int, 8> EncodingIndices;
4297 for (unsigned I = 0, E = AL.getNumArgs(); I < E; ++I) {
4298 SourceRange SR;
4299 int32_t ArgIdx;
4300
4301 if (AL.isArgIdent(Arg: I)) {
4302 IdentifierLoc *IdLoc = AL.getArgAsIdent(Arg: I);
4303 auto It = NameIdxMapping.find(Key: IdLoc->getIdentifierInfo()->getName());
4304 if (It == UnknownName) {
4305 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_attribute_argument_unknown)
4306 << IdLoc->getIdentifierInfo() << IdLoc->getLoc();
4307 return;
4308 }
4309
4310 SR = SourceRange(IdLoc->getLoc());
4311 ArgIdx = It->second;
4312 } else if (AL.isArgExpr(Arg: I)) {
4313 Expr *IdxExpr = AL.getArgAsExpr(Arg: I);
4314
4315 // If the expression is not parseable as an int32_t we have a problem.
4316 if (!S.checkUInt32Argument(AI: AL, Expr: IdxExpr, Val&: (uint32_t &)ArgIdx, Idx: I + 1,
4317 StrictlyUnsigned: false)) {
4318 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_out_of_bounds)
4319 << AL << (I + 1) << IdxExpr->getSourceRange();
4320 return;
4321 }
4322
4323 // Check oob, excluding the special values, 0 and -1.
4324 if (ArgIdx < -1 || ArgIdx > NumArgs) {
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 SR = IdxExpr->getSourceRange();
4331 } else {
4332 llvm_unreachable("Unexpected ParsedAttr argument type!");
4333 }
4334
4335 if (ArgIdx == 0 && !HasImplicitThisParam) {
4336 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_implicit_this_not_available)
4337 << (I + 1) << SR;
4338 return;
4339 }
4340
4341 // Adjust for the case we do not have an implicit "this" parameter. In this
4342 // case we decrease all positive values by 1 to get LLVM argument indices.
4343 if (!HasImplicitThisParam && ArgIdx > 0)
4344 ArgIdx -= 1;
4345
4346 EncodingIndices.push_back(Elt: ArgIdx);
4347 }
4348
4349 int CalleeIdx = EncodingIndices.front();
4350 // Check if the callee index is proper, thus not "this" and not "unknown".
4351 // This means the "CalleeIdx" has to be non-negative if "HasImplicitThisParam"
4352 // is false and positive if "HasImplicitThisParam" is true.
4353 if (CalleeIdx < (int)HasImplicitThisParam) {
4354 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_attribute_invalid_callee)
4355 << AL.getRange();
4356 return;
4357 }
4358
4359 // Get the callee type, note the index adjustment as the AST doesn't contain
4360 // the this type (which the callee cannot reference anyway!).
4361 const Type *CalleeType =
4362 getFunctionOrMethodParamType(D, Idx: CalleeIdx - HasImplicitThisParam)
4363 .getTypePtr();
4364 if (!CalleeType || !CalleeType->isFunctionPointerType()) {
4365 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_callee_no_function_type)
4366 << AL.getRange();
4367 return;
4368 }
4369
4370 const Type *CalleeFnType =
4371 CalleeType->getPointeeType()->getUnqualifiedDesugaredType();
4372
4373 // TODO: Check the type of the callee arguments.
4374
4375 const auto *CalleeFnProtoType = dyn_cast<FunctionProtoType>(Val: CalleeFnType);
4376 if (!CalleeFnProtoType) {
4377 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_callee_no_function_type)
4378 << AL.getRange();
4379 return;
4380 }
4381
4382 if (CalleeFnProtoType->getNumParams() != EncodingIndices.size() - 1) {
4383 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_wrong_arg_count_for_func)
4384 << AL << QualType{CalleeFnProtoType, 0}
4385 << CalleeFnProtoType->getNumParams()
4386 << (unsigned)(EncodingIndices.size() - 1);
4387 return;
4388 }
4389
4390 if (CalleeFnProtoType->isVariadic()) {
4391 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_callee_is_variadic) << AL.getRange();
4392 return;
4393 }
4394
4395 // Do not allow multiple callback attributes.
4396 if (D->hasAttr<CallbackAttr>()) {
4397 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_callback_attribute_multiple) << AL.getRange();
4398 return;
4399 }
4400
4401 D->addAttr(A: ::new (S.Context) CallbackAttr(
4402 S.Context, AL, EncodingIndices.data(), EncodingIndices.size()));
4403}
4404
4405LifetimeCaptureByAttr *Sema::ParseLifetimeCaptureByAttr(const ParsedAttr &AL,
4406 StringRef ParamName) {
4407 // Atleast one capture by is required.
4408 if (AL.getNumArgs() == 0) {
4409 Diag(Loc: AL.getLoc(), DiagID: diag::err_capture_by_attribute_no_entity)
4410 << AL.getRange();
4411 return nullptr;
4412 }
4413 unsigned N = AL.getNumArgs();
4414 auto ParamIdents =
4415 MutableArrayRef<IdentifierInfo *>(new (Context) IdentifierInfo *[N], N);
4416 auto ParamLocs =
4417 MutableArrayRef<SourceLocation>(new (Context) SourceLocation[N], N);
4418 bool IsValid = true;
4419 for (unsigned I = 0; I < N; ++I) {
4420 if (AL.isArgExpr(Arg: I)) {
4421 Expr *E = AL.getArgAsExpr(Arg: I);
4422 Diag(Loc: E->getExprLoc(), DiagID: diag::err_capture_by_attribute_argument_unknown)
4423 << E << E->getExprLoc();
4424 IsValid = false;
4425 continue;
4426 }
4427 assert(AL.isArgIdent(I));
4428 IdentifierLoc *IdLoc = AL.getArgAsIdent(Arg: I);
4429 if (IdLoc->getIdentifierInfo()->getName() == ParamName) {
4430 Diag(Loc: IdLoc->getLoc(), DiagID: diag::err_capture_by_references_itself)
4431 << IdLoc->getLoc();
4432 IsValid = false;
4433 continue;
4434 }
4435 ParamIdents[I] = IdLoc->getIdentifierInfo();
4436 ParamLocs[I] = IdLoc->getLoc();
4437 }
4438 if (!IsValid)
4439 return nullptr;
4440 SmallVector<int> FakeParamIndices(N, LifetimeCaptureByAttr::Invalid);
4441 auto *CapturedBy =
4442 LifetimeCaptureByAttr::Create(Ctx&: Context, Params: FakeParamIndices.data(), ParamsSize: N, CommonInfo: AL);
4443 CapturedBy->setArgs(Idents: ParamIdents, Locs: ParamLocs);
4444 return CapturedBy;
4445}
4446
4447static void handleLifetimeCaptureByAttr(Sema &S, Decl *D,
4448 const ParsedAttr &AL) {
4449 // Do not allow multiple attributes.
4450 if (D->hasAttr<LifetimeCaptureByAttr>()) {
4451 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_capture_by_attribute_multiple)
4452 << AL.getRange();
4453 return;
4454 }
4455 auto *PVD = dyn_cast<ParmVarDecl>(Val: D);
4456 assert(PVD);
4457 auto *CaptureByAttr = S.ParseLifetimeCaptureByAttr(AL, ParamName: PVD->getName());
4458 if (CaptureByAttr)
4459 D->addAttr(A: CaptureByAttr);
4460}
4461
4462void Sema::LazyProcessLifetimeCaptureByParams(FunctionDecl *FD) {
4463 bool HasImplicitThisParam = hasImplicitObjectParameter(D: FD);
4464 SmallVector<LifetimeCaptureByAttr *, 1> Attrs;
4465 for (ParmVarDecl *PVD : FD->parameters())
4466 if (auto *A = PVD->getAttr<LifetimeCaptureByAttr>())
4467 Attrs.push_back(Elt: A);
4468 if (HasImplicitThisParam) {
4469 TypeSourceInfo *TSI = FD->getTypeSourceInfo();
4470 if (!TSI)
4471 return;
4472 AttributedTypeLoc ATL;
4473 for (TypeLoc TL = TSI->getTypeLoc();
4474 (ATL = TL.getAsAdjusted<AttributedTypeLoc>());
4475 TL = ATL.getModifiedLoc()) {
4476 if (auto *A = ATL.getAttrAs<LifetimeCaptureByAttr>())
4477 Attrs.push_back(Elt: const_cast<LifetimeCaptureByAttr *>(A));
4478 }
4479 }
4480 if (Attrs.empty())
4481 return;
4482 llvm::StringMap<int> NameIdxMapping = {
4483 {"global", LifetimeCaptureByAttr::Global},
4484 {"unknown", LifetimeCaptureByAttr::Unknown}};
4485 int Idx = 0;
4486 if (HasImplicitThisParam) {
4487 NameIdxMapping["this"] = 0;
4488 Idx++;
4489 }
4490 for (const ParmVarDecl *PVD : FD->parameters())
4491 NameIdxMapping[PVD->getName()] = Idx++;
4492 auto DisallowReservedParams = [&](StringRef Reserved) {
4493 for (const ParmVarDecl *PVD : FD->parameters())
4494 if (PVD->getName() == Reserved)
4495 Diag(Loc: PVD->getLocation(), DiagID: diag::err_capture_by_param_uses_reserved_name)
4496 << (PVD->getName() == "unknown");
4497 };
4498 for (auto *CapturedBy : Attrs) {
4499 const auto &Entities = CapturedBy->getArgIdents();
4500 for (size_t I = 0; I < Entities.size(); ++I) {
4501 StringRef Name = Entities[I]->getName();
4502 auto It = NameIdxMapping.find(Key: Name);
4503 if (It == NameIdxMapping.end()) {
4504 auto Loc = CapturedBy->getArgLocs()[I];
4505 if (!HasImplicitThisParam && Name == "this")
4506 Diag(Loc, DiagID: diag::err_capture_by_implicit_this_not_available) << Loc;
4507 else
4508 Diag(Loc, DiagID: diag::err_capture_by_attribute_argument_unknown)
4509 << Entities[I] << Loc;
4510 continue;
4511 }
4512 if (Name == "unknown" || Name == "global")
4513 DisallowReservedParams(Name);
4514 CapturedBy->setParamIdx(Idx: I, Val: It->second);
4515 }
4516 }
4517}
4518
4519static bool isFunctionLike(const Type &T) {
4520 // Check for explicit function types.
4521 // 'called_once' is only supported in Objective-C and it has
4522 // function pointers and block pointers.
4523 return T.isFunctionPointerType() || T.isBlockPointerType();
4524}
4525
4526/// Handle 'called_once' attribute.
4527static void handleCalledOnceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4528 // 'called_once' only applies to parameters representing functions.
4529 QualType T = cast<ParmVarDecl>(Val: D)->getType();
4530
4531 if (!isFunctionLike(T: *T)) {
4532 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_called_once_attribute_wrong_type);
4533 return;
4534 }
4535
4536 D->addAttr(A: ::new (S.Context) CalledOnceAttr(S.Context, AL));
4537}
4538
4539static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4540 // Try to find the underlying union declaration.
4541 RecordDecl *RD = nullptr;
4542 const auto *TD = dyn_cast<TypedefNameDecl>(Val: D);
4543 if (TD && TD->getUnderlyingType()->isUnionType())
4544 RD = TD->getUnderlyingType()->getAsRecordDecl();
4545 else
4546 RD = dyn_cast<RecordDecl>(Val: D);
4547
4548 if (!RD || !RD->isUnion()) {
4549 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_wrong_decl_type)
4550 << AL << AL.isRegularKeywordAttribute() << ExpectedUnion;
4551 return;
4552 }
4553
4554 if (!RD->isCompleteDefinition()) {
4555 if (!RD->isBeingDefined())
4556 S.Diag(Loc: AL.getLoc(),
4557 DiagID: diag::warn_transparent_union_attribute_not_definition);
4558 return;
4559 }
4560
4561 RecordDecl::field_iterator Field = RD->field_begin(),
4562 FieldEnd = RD->field_end();
4563 if (Field == FieldEnd) {
4564 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_transparent_union_attribute_zero_fields);
4565 return;
4566 }
4567
4568 FieldDecl *FirstField = *Field;
4569 QualType FirstType = FirstField->getType();
4570 if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
4571 S.Diag(Loc: FirstField->getLocation(),
4572 DiagID: diag::warn_transparent_union_attribute_floating)
4573 << FirstType->isVectorType() << FirstType;
4574 return;
4575 }
4576
4577 if (FirstType->isIncompleteType())
4578 return;
4579 uint64_t FirstSize = S.Context.getTypeSize(T: FirstType);
4580 uint64_t FirstAlign = S.Context.getTypeAlign(T: FirstType);
4581 for (; Field != FieldEnd; ++Field) {
4582 QualType FieldType = Field->getType();
4583 if (FieldType->isIncompleteType())
4584 return;
4585 // FIXME: this isn't fully correct; we also need to test whether the
4586 // members of the union would all have the same calling convention as the
4587 // first member of the union. Checking just the size and alignment isn't
4588 // sufficient (consider structs passed on the stack instead of in registers
4589 // as an example).
4590 if (S.Context.getTypeSize(T: FieldType) != FirstSize ||
4591 S.Context.getTypeAlign(T: FieldType) > FirstAlign) {
4592 // Warn if we drop the attribute.
4593 bool isSize = S.Context.getTypeSize(T: FieldType) != FirstSize;
4594 unsigned FieldBits = isSize ? S.Context.getTypeSize(T: FieldType)
4595 : S.Context.getTypeAlign(T: FieldType);
4596 S.Diag(Loc: Field->getLocation(),
4597 DiagID: diag::warn_transparent_union_attribute_field_size_align)
4598 << isSize << *Field << FieldBits;
4599 unsigned FirstBits = isSize ? FirstSize : FirstAlign;
4600 S.Diag(Loc: FirstField->getLocation(),
4601 DiagID: diag::note_transparent_union_first_field_size_align)
4602 << isSize << FirstBits;
4603 return;
4604 }
4605 }
4606
4607 RD->addAttr(A: ::new (S.Context) TransparentUnionAttr(S.Context, AL));
4608}
4609
4610static void handleAnnotateAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4611 auto *Attr = S.CreateAnnotationAttr(AL);
4612 if (Attr) {
4613 D->addAttr(A: Attr);
4614 }
4615}
4616
4617static void handleAlignValueAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4618 S.AddAlignValueAttr(D, CI: AL, E: AL.getArgAsExpr(Arg: 0));
4619}
4620
4621void Sema::AddAlignValueAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E) {
4622 SourceLocation AttrLoc = CI.getLoc();
4623
4624 QualType T;
4625 if (const auto *TD = dyn_cast<TypedefNameDecl>(Val: D))
4626 T = TD->getUnderlyingType();
4627 else if (const auto *VD = dyn_cast<ValueDecl>(Val: D))
4628 T = VD->getType();
4629 else
4630 llvm_unreachable("Unknown decl type for align_value");
4631
4632 if (!T->isDependentType() && !T->isAnyPointerType() &&
4633 !T->isReferenceType() && !T->isMemberPointerType()) {
4634 Diag(Loc: AttrLoc, DiagID: diag::warn_attribute_pointer_or_reference_only)
4635 << CI << T << D->getSourceRange();
4636 return;
4637 }
4638
4639 if (!E->isValueDependent()) {
4640 llvm::APSInt Alignment;
4641 ExprResult ICE = VerifyIntegerConstantExpression(
4642 E, Result: &Alignment, DiagID: diag::err_align_value_attribute_argument_not_int);
4643 if (ICE.isInvalid())
4644 return;
4645
4646 if (!Alignment.isPowerOf2()) {
4647 Diag(Loc: AttrLoc, DiagID: diag::err_alignment_not_power_of_two)
4648 << E->getSourceRange();
4649 return;
4650 }
4651
4652 D->addAttr(A: ::new (Context) AlignValueAttr(Context, CI, ICE.get()));
4653 return;
4654 }
4655
4656 // Save dependent expressions in the AST to be instantiated.
4657 D->addAttr(A: ::new (Context) AlignValueAttr(Context, CI, E));
4658}
4659
4660static void handleAlignedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
4661 if (AL.hasParsedType()) {
4662 const ParsedType &TypeArg = AL.getTypeArg();
4663 TypeSourceInfo *TInfo;
4664 (void)S.GetTypeFromParser(
4665 Ty: ParsedType::getFromOpaquePtr(P: TypeArg.getAsOpaquePtr()), TInfo: &TInfo);
4666 if (AL.isPackExpansion() &&
4667 !TInfo->getType()->containsUnexpandedParameterPack()) {
4668 S.Diag(Loc: AL.getEllipsisLoc(),
4669 DiagID: diag::err_pack_expansion_without_parameter_packs);
4670 return;
4671 }
4672
4673 if (!AL.isPackExpansion() &&
4674 S.DiagnoseUnexpandedParameterPack(Loc: TInfo->getTypeLoc().getBeginLoc(),
4675 T: TInfo, UPPC: Sema::UPPC_Expression))
4676 return;
4677
4678 S.AddAlignedAttr(D, CI: AL, T: TInfo, IsPackExpansion: AL.isPackExpansion());
4679 return;
4680 }
4681
4682 // check the attribute arguments.
4683 if (AL.getNumArgs() > 1) {
4684 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_wrong_number_arguments) << AL << 1;
4685 return;
4686 }
4687
4688 if (AL.getNumArgs() == 0) {
4689 D->addAttr(A: ::new (S.Context) AlignedAttr(S.Context, AL, true, nullptr));
4690 return;
4691 }
4692
4693 Expr *E = AL.getArgAsExpr(Arg: 0);
4694 if (AL.isPackExpansion() && !E->containsUnexpandedParameterPack()) {
4695 S.Diag(Loc: AL.getEllipsisLoc(),
4696 DiagID: diag::err_pack_expansion_without_parameter_packs);
4697 return;
4698 }
4699
4700 if (!AL.isPackExpansion() && S.DiagnoseUnexpandedParameterPack(E))
4701 return;
4702
4703 S.AddAlignedAttr(D, CI: AL, E, IsPackExpansion: AL.isPackExpansion());
4704}
4705
4706/// Perform checking of type validity
4707///
4708/// C++11 [dcl.align]p1:
4709/// An alignment-specifier may be applied to a variable or to a class
4710/// data member, but it shall not be applied to a bit-field, a function
4711/// parameter, the formal parameter of a catch clause, or a variable
4712/// declared with the register storage class specifier. An
4713/// alignment-specifier may also be applied to the declaration of a class
4714/// or enumeration type.
4715/// CWG 2354:
4716/// CWG agreed to remove permission for alignas to be applied to
4717/// enumerations.
4718/// C11 6.7.5/2:
4719/// An alignment attribute shall not be specified in a declaration of
4720/// a typedef, or a bit-field, or a function, or a parameter, or an
4721/// object declared with the register storage-class specifier.
4722static bool validateAlignasAppliedType(Sema &S, Decl *D,
4723 const AlignedAttr &Attr,
4724 SourceLocation AttrLoc) {
4725 int DiagKind = -1;
4726 if (isa<ParmVarDecl>(Val: D)) {
4727 DiagKind = 0;
4728 } else if (const auto *VD = dyn_cast<VarDecl>(Val: D)) {
4729 if (VD->getStorageClass() == SC_Register)
4730 DiagKind = 1;
4731 if (VD->isExceptionVariable())
4732 DiagKind = 2;
4733 } else if (const auto *FD = dyn_cast<FieldDecl>(Val: D)) {
4734 if (FD->isBitField())
4735 DiagKind = 3;
4736 } else if (const auto *ED = dyn_cast<EnumDecl>(Val: D)) {
4737 if (ED->getLangOpts().CPlusPlus)
4738 DiagKind = 4;
4739 } else if (!isa<TagDecl>(Val: D)) {
4740 return S.Diag(Loc: AttrLoc, DiagID: diag::err_attribute_wrong_decl_type)
4741 << &Attr << Attr.isRegularKeywordAttribute()
4742 << (Attr.isC11() ? ExpectedVariableOrField
4743 : ExpectedVariableFieldOrTag);
4744 }
4745 if (DiagKind != -1) {
4746 return S.Diag(Loc: AttrLoc, DiagID: diag::err_alignas_attribute_wrong_decl_type)
4747 << &Attr << DiagKind;
4748 }
4749 return false;
4750}
4751
4752void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI, Expr *E,
4753 bool IsPackExpansion) {
4754 AlignedAttr TmpAttr(Context, CI, true, E);
4755 SourceLocation AttrLoc = CI.getLoc();
4756
4757 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
4758 if (TmpAttr.isAlignas() &&
4759 validateAlignasAppliedType(S&: *this, D, Attr: TmpAttr, AttrLoc))
4760 return;
4761
4762 if (E->isValueDependent()) {
4763 // We can't support a dependent alignment on a non-dependent type,
4764 // because we have no way to model that a type is "alignment-dependent"
4765 // but not dependent in any other way.
4766 if (const auto *TND = dyn_cast<TypedefNameDecl>(Val: D)) {
4767 if (!TND->getUnderlyingType()->isDependentType()) {
4768 Diag(Loc: AttrLoc, DiagID: diag::err_alignment_dependent_typedef_name)
4769 << E->getSourceRange();
4770 return;
4771 }
4772 }
4773
4774 // Save dependent expressions in the AST to be instantiated.
4775 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, E);
4776 AA->setPackExpansion(IsPackExpansion);
4777 D->addAttr(A: AA);
4778 return;
4779 }
4780
4781 // FIXME: Cache the number on the AL object?
4782 llvm::APSInt Alignment;
4783 ExprResult ICE = VerifyIntegerConstantExpression(
4784 E, Result: &Alignment, DiagID: diag::err_aligned_attribute_argument_not_int);
4785 if (ICE.isInvalid())
4786 return;
4787
4788 uint64_t MaximumAlignment = Sema::MaximumAlignment;
4789 if (Context.getTargetInfo().getTriple().isOSBinFormatCOFF())
4790 MaximumAlignment = std::min(a: MaximumAlignment, b: uint64_t(8192));
4791 if (Alignment > MaximumAlignment) {
4792 Diag(Loc: AttrLoc, DiagID: diag::err_attribute_aligned_too_great)
4793 << MaximumAlignment << E->getSourceRange();
4794 return;
4795 }
4796
4797 uint64_t AlignVal = Alignment.getZExtValue();
4798 // C++11 [dcl.align]p2:
4799 // -- if the constant expression evaluates to zero, the alignment
4800 // specifier shall have no effect
4801 // C11 6.7.5p6:
4802 // An alignment specification of zero has no effect.
4803 if (!(TmpAttr.isAlignas() && !Alignment)) {
4804 if (!llvm::isPowerOf2_64(Value: AlignVal)) {
4805 Diag(Loc: AttrLoc, DiagID: diag::err_alignment_not_power_of_two)
4806 << E->getSourceRange();
4807 return;
4808 }
4809 }
4810
4811 const auto *VD = dyn_cast<VarDecl>(Val: D);
4812 if (VD) {
4813 unsigned MaxTLSAlign =
4814 Context.toCharUnitsFromBits(BitSize: Context.getTargetInfo().getMaxTLSAlign())
4815 .getQuantity();
4816 if (MaxTLSAlign && AlignVal > MaxTLSAlign &&
4817 VD->getTLSKind() != VarDecl::TLS_None) {
4818 Diag(Loc: VD->getLocation(), DiagID: diag::err_tls_var_aligned_over_maximum)
4819 << (unsigned)AlignVal << VD << MaxTLSAlign;
4820 return;
4821 }
4822 }
4823
4824 // On AIX, an aligned attribute can not decrease the alignment when applied
4825 // to a variable declaration with vector type.
4826 if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {
4827 const Type *Ty = VD->getType().getTypePtr();
4828 if (Ty->isVectorType() && AlignVal < 16) {
4829 Diag(Loc: VD->getLocation(), DiagID: diag::warn_aligned_attr_underaligned)
4830 << VD->getType() << 16;
4831 return;
4832 }
4833 }
4834
4835 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, true, ICE.get());
4836 AA->setPackExpansion(IsPackExpansion);
4837 AA->setCachedAlignmentValue(
4838 static_cast<unsigned>(AlignVal * Context.getCharWidth()));
4839 D->addAttr(A: AA);
4840}
4841
4842void Sema::AddAlignedAttr(Decl *D, const AttributeCommonInfo &CI,
4843 TypeSourceInfo *TS, bool IsPackExpansion) {
4844 AlignedAttr TmpAttr(Context, CI, false, TS);
4845 SourceLocation AttrLoc = CI.getLoc();
4846
4847 // C++11 alignas(...) and C11 _Alignas(...) have additional requirements.
4848 if (TmpAttr.isAlignas() &&
4849 validateAlignasAppliedType(S&: *this, D, Attr: TmpAttr, AttrLoc))
4850 return;
4851
4852 if (TS->getType()->isDependentType()) {
4853 // We can't support a dependent alignment on a non-dependent type,
4854 // because we have no way to model that a type is "type-dependent"
4855 // but not dependent in any other way.
4856 if (const auto *TND = dyn_cast<TypedefNameDecl>(Val: D)) {
4857 if (!TND->getUnderlyingType()->isDependentType()) {
4858 Diag(Loc: AttrLoc, DiagID: diag::err_alignment_dependent_typedef_name)
4859 << TS->getTypeLoc().getSourceRange();
4860 return;
4861 }
4862 }
4863
4864 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
4865 AA->setPackExpansion(IsPackExpansion);
4866 D->addAttr(A: AA);
4867 return;
4868 }
4869
4870 const auto *VD = dyn_cast<VarDecl>(Val: D);
4871 unsigned AlignVal = TmpAttr.getAlignment(Ctx&: Context);
4872 // On AIX, an aligned attribute can not decrease the alignment when applied
4873 // to a variable declaration with vector type.
4874 if (VD && Context.getTargetInfo().getTriple().isOSAIX()) {
4875 const Type *Ty = VD->getType().getTypePtr();
4876 if (Ty->isVectorType() &&
4877 Context.toCharUnitsFromBits(BitSize: AlignVal).getQuantity() < 16) {
4878 Diag(Loc: VD->getLocation(), DiagID: diag::warn_aligned_attr_underaligned)
4879 << VD->getType() << 16;
4880 return;
4881 }
4882 }
4883
4884 AlignedAttr *AA = ::new (Context) AlignedAttr(Context, CI, false, TS);
4885 AA->setPackExpansion(IsPackExpansion);
4886 AA->setCachedAlignmentValue(AlignVal);
4887 D->addAttr(A: AA);
4888}
4889
4890void Sema::CheckAlignasUnderalignment(Decl *D) {
4891 assert(D->hasAttrs() && "no attributes on decl");
4892
4893 QualType UnderlyingTy, DiagTy;
4894 if (const auto *VD = dyn_cast<ValueDecl>(Val: D)) {
4895 UnderlyingTy = DiagTy = VD->getType();
4896 } else {
4897 UnderlyingTy = DiagTy = Context.getCanonicalTagType(TD: cast<TagDecl>(Val: D));
4898 if (const auto *ED = dyn_cast<EnumDecl>(Val: D))
4899 UnderlyingTy = ED->getIntegerType();
4900 }
4901 if (DiagTy->isDependentType() || DiagTy->isIncompleteType())
4902 return;
4903
4904 // C++11 [dcl.align]p5, C11 6.7.5/4:
4905 // The combined effect of all alignment attributes in a declaration shall
4906 // not specify an alignment that is less strict than the alignment that
4907 // would otherwise be required for the entity being declared.
4908 AlignedAttr *AlignasAttr = nullptr;
4909 AlignedAttr *LastAlignedAttr = nullptr;
4910 unsigned Align = 0;
4911 for (auto *I : D->specific_attrs<AlignedAttr>()) {
4912 if (I->isAlignmentDependent())
4913 return;
4914 if (I->isAlignas())
4915 AlignasAttr = I;
4916 Align = std::max(a: Align, b: I->getAlignment(Ctx&: Context));
4917 LastAlignedAttr = I;
4918 }
4919
4920 if (Align && DiagTy->isSizelessType()) {
4921 Diag(Loc: LastAlignedAttr->getLocation(), DiagID: diag::err_attribute_sizeless_type)
4922 << LastAlignedAttr << DiagTy;
4923 } else if (AlignasAttr && Align) {
4924 CharUnits RequestedAlign = Context.toCharUnitsFromBits(BitSize: Align);
4925 CharUnits NaturalAlign = Context.getTypeAlignInChars(T: UnderlyingTy);
4926 if (NaturalAlign > RequestedAlign)
4927 Diag(Loc: AlignasAttr->getLocation(), DiagID: diag::err_alignas_underaligned)
4928 << DiagTy << (unsigned)NaturalAlign.getQuantity();
4929 }
4930}
4931
4932bool Sema::checkMSInheritanceAttrOnDefinition(
4933 CXXRecordDecl *RD, SourceRange Range, bool BestCase,
4934 MSInheritanceModel ExplicitModel) {
4935 assert(RD->hasDefinition() && "RD has no definition!");
4936
4937 // We may not have seen base specifiers or any virtual methods yet. We will
4938 // have to wait until the record is defined to catch any mismatches.
4939 if (!RD->getDefinition()->isCompleteDefinition())
4940 return false;
4941
4942 // The unspecified model never matches what a definition could need.
4943 if (ExplicitModel == MSInheritanceModel::Unspecified)
4944 return false;
4945
4946 if (BestCase) {
4947 if (RD->calculateInheritanceModel() == ExplicitModel)
4948 return false;
4949 } else {
4950 if (RD->calculateInheritanceModel() <= ExplicitModel)
4951 return false;
4952 }
4953
4954 Diag(Loc: Range.getBegin(), DiagID: diag::err_mismatched_ms_inheritance)
4955 << 0 /*definition*/;
4956 Diag(Loc: RD->getDefinition()->getLocation(), DiagID: diag::note_defined_here) << RD;
4957 return true;
4958}
4959
4960/// parseModeAttrArg - Parses attribute mode string and returns parsed type
4961/// attribute.
4962static void parseModeAttrArg(Sema &S, StringRef Str, unsigned &DestWidth,
4963 bool &IntegerMode, bool &ComplexMode,
4964 FloatModeKind &ExplicitType) {
4965 IntegerMode = true;
4966 ComplexMode = false;
4967 ExplicitType = FloatModeKind::NoFloat;
4968 switch (Str.size()) {
4969 case 2:
4970 switch (Str[0]) {
4971 case 'Q':
4972 DestWidth = 8;
4973 break;
4974 case 'H':
4975 DestWidth = 16;
4976 break;
4977 case 'S':
4978 DestWidth = 32;
4979 break;
4980 case 'D':
4981 DestWidth = 64;
4982 break;
4983 case 'X':
4984 DestWidth = 96;
4985 break;
4986 case 'K': // KFmode - IEEE quad precision (__float128)
4987 ExplicitType = FloatModeKind::Float128;
4988 DestWidth = Str[1] == 'I' ? 0 : 128;
4989 break;
4990 case 'T':
4991 ExplicitType = FloatModeKind::LongDouble;
4992 DestWidth = 128;
4993 break;
4994 case 'I':
4995 ExplicitType = FloatModeKind::Ibm128;
4996 DestWidth = Str[1] == 'I' ? 0 : 128;
4997 break;
4998 }
4999 if (Str[1] == 'F') {
5000 IntegerMode = false;
5001 } else if (Str[1] == 'C') {
5002 IntegerMode = false;
5003 ComplexMode = true;
5004 } else if (Str[1] != 'I') {
5005 DestWidth = 0;
5006 }
5007 break;
5008 case 4:
5009 // FIXME: glibc uses 'word' to define register_t; this is narrower than a
5010 // pointer on PIC16 and other embedded platforms.
5011 if (Str == "word")
5012 DestWidth = S.Context.getTargetInfo().getRegisterWidth();
5013 else if (Str == "byte")
5014 DestWidth = S.Context.getTargetInfo().getCharWidth();
5015 break;
5016 case 7:
5017 if (Str == "pointer")
5018 DestWidth = S.Context.getTargetInfo().getPointerWidth(AddrSpace: LangAS::Default);
5019 break;
5020 case 11:
5021 if (Str == "unwind_word")
5022 DestWidth = S.Context.getTargetInfo().getUnwindWordWidth();
5023 break;
5024 }
5025}
5026
5027/// handleModeAttr - This attribute modifies the width of a decl with primitive
5028/// type.
5029///
5030/// Despite what would be logical, the mode attribute is a decl attribute, not a
5031/// type attribute: 'int ** __attribute((mode(HI))) *G;' tries to make 'G' be
5032/// HImode, not an intermediate pointer.
5033static void handleModeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5034 // This attribute isn't documented, but glibc uses it. It changes
5035 // the width of an int or unsigned int to the specified size.
5036 if (!AL.isArgIdent(Arg: 0)) {
5037 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
5038 << AL << AANT_ArgumentIdentifier;
5039 return;
5040 }
5041
5042 IdentifierInfo *Name = AL.getArgAsIdent(Arg: 0)->getIdentifierInfo();
5043
5044 S.AddModeAttr(D, CI: AL, Name);
5045}
5046
5047void Sema::AddModeAttr(Decl *D, const AttributeCommonInfo &CI,
5048 const IdentifierInfo *Name, bool InInstantiation) {
5049 StringRef Str = Name->getName();
5050 normalizeName(AttrName&: Str);
5051 SourceLocation AttrLoc = CI.getLoc();
5052
5053 unsigned DestWidth = 0;
5054 bool IntegerMode = true;
5055 bool ComplexMode = false;
5056 FloatModeKind ExplicitType = FloatModeKind::NoFloat;
5057 llvm::APInt VectorSize(64, 0);
5058 if (Str.size() >= 4 && Str[0] == 'V') {
5059 // Minimal length of vector mode is 4: 'V' + NUMBER(>=1) + TYPE(>=2).
5060 size_t StrSize = Str.size();
5061 size_t VectorStringLength = 0;
5062 while ((VectorStringLength + 1) < StrSize &&
5063 isdigit(Str[VectorStringLength + 1]))
5064 ++VectorStringLength;
5065 if (VectorStringLength &&
5066 !Str.substr(Start: 1, N: VectorStringLength).getAsInteger(Radix: 10, Result&: VectorSize) &&
5067 VectorSize.isPowerOf2()) {
5068 parseModeAttrArg(S&: *this, Str: Str.substr(Start: VectorStringLength + 1), DestWidth,
5069 IntegerMode, ComplexMode, ExplicitType);
5070 // Avoid duplicate warning from template instantiation.
5071 if (!InInstantiation)
5072 Diag(Loc: AttrLoc, DiagID: diag::warn_vector_mode_deprecated);
5073 } else {
5074 VectorSize = 0;
5075 }
5076 }
5077
5078 if (!VectorSize)
5079 parseModeAttrArg(S&: *this, Str, DestWidth, IntegerMode, ComplexMode,
5080 ExplicitType);
5081
5082 // FIXME: Sync this with InitializePredefinedMacros; we need to match int8_t
5083 // and friends, at least with glibc.
5084 // FIXME: Make sure floating-point mappings are accurate
5085 // FIXME: Support XF and TF types
5086 if (!DestWidth) {
5087 Diag(Loc: AttrLoc, DiagID: diag::err_machine_mode) << 0 /*Unknown*/ << Name;
5088 return;
5089 }
5090
5091 QualType OldTy;
5092 if (const auto *TD = dyn_cast<TypedefNameDecl>(Val: D))
5093 OldTy = TD->getUnderlyingType();
5094 else if (const auto *ED = dyn_cast<EnumDecl>(Val: D)) {
5095 // Something like 'typedef enum { X } __attribute__((mode(XX))) T;'.
5096 // Try to get type from enum declaration, default to int.
5097 OldTy = ED->getIntegerType();
5098 if (OldTy.isNull())
5099 OldTy = Context.IntTy;
5100 } else
5101 OldTy = cast<ValueDecl>(Val: D)->getType();
5102
5103 if (OldTy->isDependentType()) {
5104 D->addAttr(A: ::new (Context) ModeAttr(Context, CI, Name));
5105 return;
5106 }
5107
5108 // Base type can also be a vector type (see PR17453).
5109 // Distinguish between base type and base element type.
5110 QualType OldElemTy = OldTy;
5111 if (const auto *VT = OldTy->getAs<VectorType>())
5112 OldElemTy = VT->getElementType();
5113
5114 // GCC allows 'mode' attribute on enumeration types (even incomplete), except
5115 // for vector modes. So, 'enum X __attribute__((mode(QI)));' forms a complete
5116 // type, 'enum { A } __attribute__((mode(V4SI)))' is rejected.
5117 if ((isa<EnumDecl>(Val: D) || OldElemTy->isEnumeralType()) &&
5118 VectorSize.getBoolValue()) {
5119 Diag(Loc: AttrLoc, DiagID: diag::err_enum_mode_vector_type) << Name << CI.getRange();
5120 return;
5121 }
5122 bool IntegralOrAnyEnumType = (OldElemTy->isIntegralOrEnumerationType() &&
5123 !OldElemTy->isBitIntType()) ||
5124 OldElemTy->isEnumeralType();
5125
5126 if (!OldElemTy->getAs<BuiltinType>() && !OldElemTy->isComplexType() &&
5127 !IntegralOrAnyEnumType)
5128 Diag(Loc: AttrLoc, DiagID: diag::err_mode_not_primitive);
5129 else if (IntegerMode) {
5130 if (!IntegralOrAnyEnumType)
5131 Diag(Loc: AttrLoc, DiagID: diag::err_mode_wrong_type);
5132 } else if (ComplexMode) {
5133 if (!OldElemTy->isComplexType())
5134 Diag(Loc: AttrLoc, DiagID: diag::err_mode_wrong_type);
5135 } else {
5136 if (!OldElemTy->isFloatingType())
5137 Diag(Loc: AttrLoc, DiagID: diag::err_mode_wrong_type);
5138 }
5139
5140 QualType NewElemTy;
5141
5142 if (IntegerMode)
5143 NewElemTy = Context.getIntTypeForBitwidth(DestWidth,
5144 Signed: OldElemTy->isSignedIntegerType());
5145 else
5146 NewElemTy = Context.getRealTypeForBitwidth(DestWidth, ExplicitType);
5147
5148 if (NewElemTy.isNull()) {
5149 // Only emit diagnostic on host for 128-bit mode attribute
5150 if (!(DestWidth == 128 &&
5151 (getLangOpts().CUDAIsDevice || getLangOpts().SYCLIsDevice)))
5152 Diag(Loc: AttrLoc, DiagID: diag::err_machine_mode) << 1 /*Unsupported*/ << Name;
5153 return;
5154 }
5155
5156 if (ComplexMode) {
5157 NewElemTy = Context.getComplexType(T: NewElemTy);
5158 }
5159
5160 QualType NewTy = NewElemTy;
5161 if (VectorSize.getBoolValue()) {
5162 NewTy = Context.getVectorType(VectorType: NewTy, NumElts: VectorSize.getZExtValue(),
5163 VecKind: VectorKind::Generic);
5164 } else if (const auto *OldVT = OldTy->getAs<VectorType>()) {
5165 // Complex machine mode does not support base vector types.
5166 if (ComplexMode) {
5167 Diag(Loc: AttrLoc, DiagID: diag::err_complex_mode_vector_type);
5168 return;
5169 }
5170 unsigned NumElements = Context.getTypeSize(T: OldElemTy) *
5171 OldVT->getNumElements() /
5172 Context.getTypeSize(T: NewElemTy);
5173 NewTy =
5174 Context.getVectorType(VectorType: NewElemTy, NumElts: NumElements, VecKind: OldVT->getVectorKind());
5175 }
5176
5177 if (NewTy.isNull()) {
5178 Diag(Loc: AttrLoc, DiagID: diag::err_mode_wrong_type);
5179 return;
5180 }
5181
5182 // Install the new type.
5183 if (auto *TD = dyn_cast<TypedefNameDecl>(Val: D))
5184 TD->setModedTypeSourceInfo(unmodedTSI: TD->getTypeSourceInfo(), modedTy: NewTy);
5185 else if (auto *ED = dyn_cast<EnumDecl>(Val: D))
5186 ED->setIntegerType(NewTy);
5187 else
5188 cast<ValueDecl>(Val: D)->setType(NewTy);
5189
5190 D->addAttr(A: ::new (Context) ModeAttr(Context, CI, Name));
5191}
5192
5193static void handleNonStringAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5194 // This only applies to fields and variable declarations which have an array
5195 // type or pointer type, with character elements.
5196 QualType QT = cast<ValueDecl>(Val: D)->getType();
5197 if ((!QT->isArrayType() && !QT->isPointerType()) ||
5198 !QT->getPointeeOrArrayElementType()->isAnyCharacterType()) {
5199 S.Diag(Loc: D->getBeginLoc(), DiagID: diag::warn_attribute_non_character_array)
5200 << AL << AL.isRegularKeywordAttribute() << QT << AL.getRange();
5201 return;
5202 }
5203
5204 D->addAttr(A: ::new (S.Context) NonStringAttr(S.Context, AL));
5205}
5206
5207static void handleNoDebugAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5208 D->addAttr(A: ::new (S.Context) NoDebugAttr(S.Context, AL));
5209}
5210
5211AlwaysInlineAttr *Sema::mergeAlwaysInlineAttr(Decl *D,
5212 const AttributeCommonInfo &CI,
5213 const IdentifierInfo *Ident) {
5214 if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
5215 Diag(Loc: CI.getLoc(), DiagID: diag::warn_attribute_ignored) << Ident;
5216 Diag(Loc: Optnone->getLocation(), DiagID: diag::note_conflicting_attribute);
5217 return nullptr;
5218 }
5219
5220 if (D->hasAttr<AlwaysInlineAttr>())
5221 return nullptr;
5222
5223 return ::new (Context) AlwaysInlineAttr(Context, CI);
5224}
5225
5226InternalLinkageAttr *Sema::mergeInternalLinkageAttr(Decl *D,
5227 const ParsedAttr &AL) {
5228 if (const auto *VD = dyn_cast<VarDecl>(Val: D)) {
5229 // Attribute applies to Var but not any subclass of it (like ParmVar,
5230 // ImplicitParm or VarTemplateSpecialization).
5231 if (VD->getKind() != Decl::Var) {
5232 Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_wrong_decl_type)
5233 << AL << AL.isRegularKeywordAttribute()
5234 << (getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass
5235 : ExpectedVariableOrFunction);
5236 return nullptr;
5237 }
5238 // Attribute does not apply to non-static local variables.
5239 if (VD->hasLocalStorage()) {
5240 Diag(Loc: VD->getLocation(), DiagID: diag::warn_internal_linkage_local_storage);
5241 return nullptr;
5242 }
5243 }
5244
5245 return ::new (Context) InternalLinkageAttr(Context, AL);
5246}
5247InternalLinkageAttr *
5248Sema::mergeInternalLinkageAttr(Decl *D, const InternalLinkageAttr &AL) {
5249 if (const auto *VD = dyn_cast<VarDecl>(Val: D)) {
5250 // Attribute applies to Var but not any subclass of it (like ParmVar,
5251 // ImplicitParm or VarTemplateSpecialization).
5252 if (VD->getKind() != Decl::Var) {
5253 Diag(Loc: AL.getLocation(), DiagID: diag::warn_attribute_wrong_decl_type)
5254 << &AL << AL.isRegularKeywordAttribute()
5255 << (getLangOpts().CPlusPlus ? ExpectedFunctionVariableOrClass
5256 : ExpectedVariableOrFunction);
5257 return nullptr;
5258 }
5259 // Attribute does not apply to non-static local variables.
5260 if (VD->hasLocalStorage()) {
5261 Diag(Loc: VD->getLocation(), DiagID: diag::warn_internal_linkage_local_storage);
5262 return nullptr;
5263 }
5264 }
5265
5266 return ::new (Context) InternalLinkageAttr(Context, AL);
5267}
5268
5269MinSizeAttr *Sema::mergeMinSizeAttr(Decl *D, const AttributeCommonInfo &CI) {
5270 if (OptimizeNoneAttr *Optnone = D->getAttr<OptimizeNoneAttr>()) {
5271 Diag(Loc: CI.getLoc(), DiagID: diag::warn_attribute_ignored) << "'minsize'";
5272 Diag(Loc: Optnone->getLocation(), DiagID: diag::note_conflicting_attribute);
5273 return nullptr;
5274 }
5275
5276 if (D->hasAttr<MinSizeAttr>())
5277 return nullptr;
5278
5279 return ::new (Context) MinSizeAttr(Context, CI);
5280}
5281
5282OptimizeNoneAttr *Sema::mergeOptimizeNoneAttr(Decl *D,
5283 const AttributeCommonInfo &CI) {
5284 if (AlwaysInlineAttr *Inline = D->getAttr<AlwaysInlineAttr>()) {
5285 Diag(Loc: Inline->getLocation(), DiagID: diag::warn_attribute_ignored) << Inline;
5286 Diag(Loc: CI.getLoc(), DiagID: diag::note_conflicting_attribute);
5287 D->dropAttr<AlwaysInlineAttr>();
5288 }
5289 if (MinSizeAttr *MinSize = D->getAttr<MinSizeAttr>()) {
5290 Diag(Loc: MinSize->getLocation(), DiagID: diag::warn_attribute_ignored) << MinSize;
5291 Diag(Loc: CI.getLoc(), DiagID: diag::note_conflicting_attribute);
5292 D->dropAttr<MinSizeAttr>();
5293 }
5294
5295 if (D->hasAttr<OptimizeNoneAttr>())
5296 return nullptr;
5297
5298 return ::new (Context) OptimizeNoneAttr(Context, CI);
5299}
5300
5301static void handleAlwaysInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5302 AlwaysInlineAttr AIA(S.Context, AL);
5303 if (!S.getLangOpts().MicrosoftExt &&
5304 (AIA.isMSVCForceInline() || AIA.isMSVCForceInlineCalls())) {
5305 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_ignored) << AL;
5306 return;
5307 }
5308 if (AIA.isMSVCForceInlineCalls()) {
5309 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_stmt_attribute_ignored_in_function)
5310 << "[[msvc::forceinline]]";
5311 return;
5312 }
5313
5314 if (AlwaysInlineAttr *Inline =
5315 S.mergeAlwaysInlineAttr(D, CI: AL, Ident: AL.getAttrName()))
5316 D->addAttr(A: Inline);
5317}
5318
5319static void handleMinSizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5320 if (MinSizeAttr *MinSize = S.mergeMinSizeAttr(D, CI: AL))
5321 D->addAttr(A: MinSize);
5322}
5323
5324static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5325 if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr(D, CI: AL))
5326 D->addAttr(A: Optnone);
5327}
5328
5329static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5330 const auto *VD = cast<VarDecl>(Val: D);
5331 if (VD->hasLocalStorage()) {
5332 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_cuda_nonstatic_constdev);
5333 return;
5334 }
5335 if (!S.CheckVarDeclSizeAddressSpace(VD, AS: LangAS::cuda_constant))
5336 return;
5337 // constexpr variable may already get an implicit constant attr, which should
5338 // be replaced by the explicit constant attr.
5339 if (auto *A = D->getAttr<CUDAConstantAttr>()) {
5340 if (!A->isImplicit())
5341 return;
5342 D->dropAttr<CUDAConstantAttr>();
5343 }
5344 D->addAttr(A: ::new (S.Context) CUDAConstantAttr(S.Context, AL));
5345}
5346
5347static void handleSharedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5348 const auto *VD = cast<VarDecl>(Val: D);
5349 // extern __shared__ is only allowed on arrays with no length (e.g.
5350 // "int x[]").
5351 if (!S.getLangOpts().GPURelocatableDeviceCode && VD->hasExternalStorage() &&
5352 !isa<IncompleteArrayType>(Val: VD->getType())) {
5353 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_cuda_extern_shared) << VD;
5354 return;
5355 }
5356 if (!S.CheckVarDeclSizeAddressSpace(VD, AS: LangAS::cuda_shared))
5357 return;
5358 if (S.getLangOpts().CUDA && VD->hasLocalStorage() &&
5359 S.CUDA().DiagIfHostCode(Loc: AL.getLoc(), DiagID: diag::err_cuda_host_shared)
5360 << S.CUDA().CurrentTarget())
5361 return;
5362 D->addAttr(A: ::new (S.Context) CUDASharedAttr(S.Context, AL));
5363}
5364
5365static void handleGlobalAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5366 const auto *FD = cast<FunctionDecl>(Val: D);
5367 if (!FD->getReturnType()->isVoidType() &&
5368 !FD->getReturnType()->getAs<AutoType>() &&
5369 !FD->getReturnType()->isInstantiationDependentType()) {
5370 SourceRange RTRange = FD->getReturnTypeSourceRange();
5371 S.Diag(Loc: FD->getTypeSpecStartLoc(), DiagID: diag::err_kern_type_not_void_return)
5372 << FD->getType()
5373 << (RTRange.isValid() ? FixItHint::CreateReplacement(RemoveRange: RTRange, Code: "void")
5374 : FixItHint());
5375 return;
5376 }
5377 if (const auto *Method = dyn_cast<CXXMethodDecl>(Val: FD)) {
5378 if (Method->isInstance()) {
5379 S.Diag(Loc: Method->getBeginLoc(), DiagID: diag::err_kern_is_nonstatic_method)
5380 << Method;
5381 return;
5382 }
5383 S.Diag(Loc: Method->getBeginLoc(), DiagID: diag::warn_kern_is_method) << Method;
5384 }
5385 // Only warn for "inline" when compiling for host, to cut down on noise.
5386 if (FD->isInlineSpecified() && !S.getLangOpts().CUDAIsDevice)
5387 S.Diag(Loc: FD->getBeginLoc(), DiagID: diag::warn_kern_is_inline) << FD;
5388
5389 if (AL.getKind() == ParsedAttr::AT_DeviceKernel)
5390 D->addAttr(A: ::new (S.Context) DeviceKernelAttr(S.Context, AL));
5391 else
5392 D->addAttr(A: ::new (S.Context) CUDAGlobalAttr(S.Context, AL));
5393 // In host compilation the kernel is emitted as a stub function, which is
5394 // a helper function for launching the kernel. The instructions in the helper
5395 // function has nothing to do with the source code of the kernel. Do not emit
5396 // debug info for the stub function to avoid confusing the debugger.
5397 if (S.LangOpts.HIP && !S.LangOpts.CUDAIsDevice)
5398 D->addAttr(A: NoDebugAttr::CreateImplicit(Ctx&: S.Context));
5399}
5400
5401static void handleDeviceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5402 if (const auto *VD = dyn_cast<VarDecl>(Val: D)) {
5403 if (VD->hasLocalStorage()) {
5404 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_cuda_nonstatic_constdev);
5405 return;
5406 }
5407 if (!S.CheckVarDeclSizeAddressSpace(VD, AS: LangAS::cuda_device))
5408 return;
5409 }
5410
5411 if (auto *A = D->getAttr<CUDADeviceAttr>()) {
5412 if (!A->isImplicit())
5413 return;
5414 D->dropAttr<CUDADeviceAttr>();
5415 }
5416 D->addAttr(A: ::new (S.Context) CUDADeviceAttr(S.Context, AL));
5417}
5418
5419static void handleManagedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5420 if (const auto *VD = dyn_cast<VarDecl>(Val: D)) {
5421 if (VD->hasLocalStorage()) {
5422 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_cuda_nonstatic_constdev);
5423 return;
5424 }
5425 if (!S.CheckVarDeclSizeAddressSpace(VD, AS: LangAS::cuda_device))
5426 return;
5427 }
5428 if (!D->hasAttr<HIPManagedAttr>())
5429 D->addAttr(A: ::new (S.Context) HIPManagedAttr(S.Context, AL));
5430 if (!D->hasAttr<CUDADeviceAttr>())
5431 D->addAttr(A: CUDADeviceAttr::CreateImplicit(Ctx&: S.Context));
5432}
5433
5434static void handleGridConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5435 if (D->isInvalidDecl())
5436 return;
5437 // Whether __grid_constant__ is allowed to be used will be checked in
5438 // Sema::CheckFunctionDeclaration as we need complete function decl to make
5439 // the call.
5440 D->addAttr(A: ::new (S.Context) CUDAGridConstantAttr(S.Context, AL));
5441}
5442
5443static void handleGNUInlineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5444 const auto *Fn = cast<FunctionDecl>(Val: D);
5445 if (!Fn->isInlineSpecified()) {
5446 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_gnu_inline_attribute_requires_inline);
5447 return;
5448 }
5449
5450 if (S.LangOpts.CPlusPlus && Fn->getStorageClass() != SC_Extern)
5451 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_gnu_inline_cplusplus_without_extern);
5452
5453 D->addAttr(A: ::new (S.Context) GNUInlineAttr(S.Context, AL));
5454}
5455
5456static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5457 if (hasDeclarator(D)) return;
5458
5459 // Diagnostic is emitted elsewhere: here we store the (valid) AL
5460 // in the Decl node for syntactic reasoning, e.g., pretty-printing.
5461 CallingConv CC;
5462 if (S.CheckCallingConvAttr(
5463 attr: AL, CC, /*FD*/ nullptr,
5464 CFT: S.CUDA().IdentifyTarget(D: dyn_cast<FunctionDecl>(Val: D))))
5465 return;
5466
5467 if (!isa<ObjCMethodDecl>(Val: D)) {
5468 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_wrong_decl_type)
5469 << AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod;
5470 return;
5471 }
5472
5473 switch (AL.getKind()) {
5474 case ParsedAttr::AT_FastCall:
5475 D->addAttr(A: ::new (S.Context) FastCallAttr(S.Context, AL));
5476 return;
5477 case ParsedAttr::AT_StdCall:
5478 D->addAttr(A: ::new (S.Context) StdCallAttr(S.Context, AL));
5479 return;
5480 case ParsedAttr::AT_ThisCall:
5481 D->addAttr(A: ::new (S.Context) ThisCallAttr(S.Context, AL));
5482 return;
5483 case ParsedAttr::AT_CDecl:
5484 D->addAttr(A: ::new (S.Context) CDeclAttr(S.Context, AL));
5485 return;
5486 case ParsedAttr::AT_Pascal:
5487 D->addAttr(A: ::new (S.Context) PascalAttr(S.Context, AL));
5488 return;
5489 case ParsedAttr::AT_SwiftCall:
5490 D->addAttr(A: ::new (S.Context) SwiftCallAttr(S.Context, AL));
5491 return;
5492 case ParsedAttr::AT_SwiftAsyncCall:
5493 D->addAttr(A: ::new (S.Context) SwiftAsyncCallAttr(S.Context, AL));
5494 return;
5495 case ParsedAttr::AT_VectorCall:
5496 D->addAttr(A: ::new (S.Context) VectorCallAttr(S.Context, AL));
5497 return;
5498 case ParsedAttr::AT_MSABI:
5499 D->addAttr(A: ::new (S.Context) MSABIAttr(S.Context, AL));
5500 return;
5501 case ParsedAttr::AT_SysVABI:
5502 D->addAttr(A: ::new (S.Context) SysVABIAttr(S.Context, AL));
5503 return;
5504 case ParsedAttr::AT_RegCall:
5505 D->addAttr(A: ::new (S.Context) RegCallAttr(S.Context, AL));
5506 return;
5507 case ParsedAttr::AT_Pcs: {
5508 PcsAttr::PCSType PCS;
5509 switch (CC) {
5510 case CC_AAPCS:
5511 PCS = PcsAttr::AAPCS;
5512 break;
5513 case CC_AAPCS_VFP:
5514 PCS = PcsAttr::AAPCS_VFP;
5515 break;
5516 default:
5517 llvm_unreachable("unexpected calling convention in pcs attribute");
5518 }
5519
5520 D->addAttr(A: ::new (S.Context) PcsAttr(S.Context, AL, PCS));
5521 return;
5522 }
5523 case ParsedAttr::AT_AArch64VectorPcs:
5524 D->addAttr(A: ::new (S.Context) AArch64VectorPcsAttr(S.Context, AL));
5525 return;
5526 case ParsedAttr::AT_AArch64SVEPcs:
5527 D->addAttr(A: ::new (S.Context) AArch64SVEPcsAttr(S.Context, AL));
5528 return;
5529 case ParsedAttr::AT_DeviceKernel: {
5530 // The attribute should already be applied.
5531 assert(D->hasAttr<DeviceKernelAttr>() && "Expected attribute");
5532 return;
5533 }
5534 case ParsedAttr::AT_IntelOclBicc:
5535 D->addAttr(A: ::new (S.Context) IntelOclBiccAttr(S.Context, AL));
5536 return;
5537 case ParsedAttr::AT_PreserveMost:
5538 D->addAttr(A: ::new (S.Context) PreserveMostAttr(S.Context, AL));
5539 return;
5540 case ParsedAttr::AT_PreserveAll:
5541 D->addAttr(A: ::new (S.Context) PreserveAllAttr(S.Context, AL));
5542 return;
5543 case ParsedAttr::AT_M68kRTD:
5544 D->addAttr(A: ::new (S.Context) M68kRTDAttr(S.Context, AL));
5545 return;
5546 case ParsedAttr::AT_PreserveNone:
5547 D->addAttr(A: ::new (S.Context) PreserveNoneAttr(S.Context, AL));
5548 return;
5549 case ParsedAttr::AT_RISCVVectorCC:
5550 D->addAttr(A: ::new (S.Context) RISCVVectorCCAttr(S.Context, AL));
5551 return;
5552 case ParsedAttr::AT_RISCVVLSCC: {
5553 // If the riscv_abi_vlen doesn't have any argument, default ABI_VLEN is 128.
5554 unsigned VectorLength = 128;
5555 if (AL.getNumArgs() &&
5556 !S.checkUInt32Argument(AI: AL, Expr: AL.getArgAsExpr(Arg: 0), Val&: VectorLength))
5557 return;
5558 if (VectorLength < 32 || VectorLength > 65536) {
5559 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_argument_invalid_range)
5560 << VectorLength << 32 << 65536;
5561 return;
5562 }
5563 if (!llvm::isPowerOf2_64(Value: VectorLength)) {
5564 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_argument_not_power_of_2);
5565 return;
5566 }
5567
5568 D->addAttr(A: ::new (S.Context) RISCVVLSCCAttr(S.Context, AL, VectorLength));
5569 return;
5570 }
5571 default:
5572 llvm_unreachable("unexpected attribute kind");
5573 }
5574}
5575
5576static void handleDeviceKernelAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5577 const auto *FD = dyn_cast_or_null<FunctionDecl>(Val: D);
5578 bool IsFunctionTemplate = FD && FD->getDescribedFunctionTemplate();
5579 llvm::Triple Triple = S.getASTContext().getTargetInfo().getTriple();
5580 const LangOptions &LangOpts = S.getLangOpts();
5581 // OpenCL has its own error messages.
5582 if (!LangOpts.OpenCL && FD && !FD->isExternallyVisible()) {
5583 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_hidden_device_kernel) << FD;
5584 AL.setInvalid();
5585 return;
5586 }
5587 if (Triple.isNVPTX()) {
5588 handleGlobalAttr(S, D, AL);
5589 } else {
5590 // OpenCL C++ will throw a more specific error.
5591 if (!LangOpts.OpenCLCPlusPlus && (!FD || IsFunctionTemplate)) {
5592 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_wrong_decl_type_str)
5593 << AL << AL.isRegularKeywordAttribute() << "functions";
5594 AL.setInvalid();
5595 return;
5596 }
5597 handleSimpleAttribute<DeviceKernelAttr>(S, D, CI: AL);
5598 }
5599 // TODO: isGPU() should probably return true for SPIR.
5600 bool TargetDeviceEnvironment = Triple.isGPU() || Triple.isSPIR() ||
5601 LangOpts.isTargetDevice() || LangOpts.OpenCL;
5602 if (!TargetDeviceEnvironment) {
5603 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_cconv_unsupported)
5604 << AL << (int)Sema::CallingConventionIgnoredReason::ForThisTarget;
5605 AL.setInvalid();
5606 return;
5607 }
5608
5609 // Make sure we validate the CC with the target
5610 // and warn/error if necessary.
5611 handleCallConvAttr(S, D, AL);
5612}
5613
5614static void handleSuppressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5615 if (AL.getAttributeSpellingListIndex() == SuppressAttr::CXX11_gsl_suppress) {
5616 // Suppression attribute with GSL spelling requires at least 1 argument.
5617 if (!AL.checkAtLeastNumArgs(S, Num: 1))
5618 return;
5619 }
5620
5621 std::vector<StringRef> DiagnosticIdentifiers;
5622 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
5623 StringRef RuleName;
5624
5625 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: RuleName, ArgLocation: nullptr))
5626 return;
5627
5628 DiagnosticIdentifiers.push_back(x: RuleName);
5629 }
5630 D->addAttr(A: ::new (S.Context)
5631 SuppressAttr(S.Context, AL, DiagnosticIdentifiers.data(),
5632 DiagnosticIdentifiers.size()));
5633}
5634
5635static void handleLifetimeCategoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5636 TypeSourceInfo *DerefTypeLoc = nullptr;
5637 QualType ParmType;
5638 if (AL.hasParsedType()) {
5639 ParmType = S.GetTypeFromParser(Ty: AL.getTypeArg(), TInfo: &DerefTypeLoc);
5640
5641 unsigned SelectIdx = ~0U;
5642 if (ParmType->isReferenceType())
5643 SelectIdx = 0;
5644 else if (ParmType->isArrayType())
5645 SelectIdx = 1;
5646
5647 if (SelectIdx != ~0U) {
5648 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_invalid_argument)
5649 << SelectIdx << AL;
5650 return;
5651 }
5652 }
5653
5654 // To check if earlier decl attributes do not conflict the newly parsed ones
5655 // we always add (and check) the attribute to the canonical decl. We need
5656 // to repeat the check for attribute mutual exclusion because we're attaching
5657 // all of the attributes to the canonical declaration rather than the current
5658 // declaration.
5659 D = D->getCanonicalDecl();
5660 if (AL.getKind() == ParsedAttr::AT_Owner) {
5661 if (checkAttrMutualExclusion<PointerAttr>(S, D, AL))
5662 return;
5663 if (const auto *OAttr = D->getAttr<OwnerAttr>()) {
5664 const Type *ExistingDerefType = OAttr->getDerefTypeLoc()
5665 ? OAttr->getDerefType().getTypePtr()
5666 : nullptr;
5667 if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
5668 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attributes_are_not_compatible)
5669 << AL << OAttr
5670 << (AL.isRegularKeywordAttribute() ||
5671 OAttr->isRegularKeywordAttribute());
5672 S.Diag(Loc: OAttr->getLocation(), DiagID: diag::note_conflicting_attribute);
5673 }
5674 return;
5675 }
5676 for (Decl *Redecl : D->redecls()) {
5677 Redecl->addAttr(A: ::new (S.Context) OwnerAttr(S.Context, AL, DerefTypeLoc));
5678 }
5679 } else {
5680 if (checkAttrMutualExclusion<OwnerAttr>(S, D, AL))
5681 return;
5682 if (const auto *PAttr = D->getAttr<PointerAttr>()) {
5683 const Type *ExistingDerefType = PAttr->getDerefTypeLoc()
5684 ? PAttr->getDerefType().getTypePtr()
5685 : nullptr;
5686 if (ExistingDerefType != ParmType.getTypePtrOrNull()) {
5687 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attributes_are_not_compatible)
5688 << AL << PAttr
5689 << (AL.isRegularKeywordAttribute() ||
5690 PAttr->isRegularKeywordAttribute());
5691 S.Diag(Loc: PAttr->getLocation(), DiagID: diag::note_conflicting_attribute);
5692 }
5693 return;
5694 }
5695 for (Decl *Redecl : D->redecls()) {
5696 Redecl->addAttr(A: ::new (S.Context)
5697 PointerAttr(S.Context, AL, DerefTypeLoc));
5698 }
5699 }
5700}
5701
5702static void handleRandomizeLayoutAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
5703 if (checkAttrMutualExclusion<NoRandomizeLayoutAttr>(S, D, AL))
5704 return;
5705 if (!D->hasAttr<RandomizeLayoutAttr>())
5706 D->addAttr(A: ::new (S.Context) RandomizeLayoutAttr(S.Context, AL));
5707}
5708
5709static void handleNoRandomizeLayoutAttr(Sema &S, Decl *D,
5710 const ParsedAttr &AL) {
5711 if (checkAttrMutualExclusion<RandomizeLayoutAttr>(S, D, AL))
5712 return;
5713 if (!D->hasAttr<NoRandomizeLayoutAttr>())
5714 D->addAttr(A: ::new (S.Context) NoRandomizeLayoutAttr(S.Context, AL));
5715}
5716
5717bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
5718 const FunctionDecl *FD,
5719 CUDAFunctionTarget CFT) {
5720 if (Attrs.isInvalid())
5721 return true;
5722
5723 if (Attrs.hasProcessingCache()) {
5724 CC = (CallingConv) Attrs.getProcessingCache();
5725 return false;
5726 }
5727
5728 if (Attrs.getKind() == ParsedAttr::AT_RISCVVLSCC) {
5729 // riscv_vls_cc only accepts 0 or 1 argument.
5730 if (!Attrs.checkAtLeastNumArgs(S&: *this, Num: 0) ||
5731 !Attrs.checkAtMostNumArgs(S&: *this, Num: 1)) {
5732 Attrs.setInvalid();
5733 return true;
5734 }
5735 } else {
5736 unsigned ReqArgs = Attrs.getKind() == ParsedAttr::AT_Pcs ? 1 : 0;
5737 if (!Attrs.checkExactlyNumArgs(S&: *this, Num: ReqArgs)) {
5738 Attrs.setInvalid();
5739 return true;
5740 }
5741 }
5742
5743 bool IsTargetDefaultMSABI =
5744 Context.getTargetInfo().getTriple().isOSWindows() ||
5745 Context.getTargetInfo().getTriple().isUEFI();
5746 // TODO: diagnose uses of these conventions on the wrong target.
5747 switch (Attrs.getKind()) {
5748 case ParsedAttr::AT_CDecl:
5749 CC = CC_C;
5750 break;
5751 case ParsedAttr::AT_FastCall:
5752 CC = CC_X86FastCall;
5753 break;
5754 case ParsedAttr::AT_StdCall:
5755 CC = CC_X86StdCall;
5756 break;
5757 case ParsedAttr::AT_ThisCall:
5758 CC = CC_X86ThisCall;
5759 break;
5760 case ParsedAttr::AT_Pascal:
5761 CC = CC_X86Pascal;
5762 break;
5763 case ParsedAttr::AT_SwiftCall:
5764 CC = CC_Swift;
5765 break;
5766 case ParsedAttr::AT_SwiftAsyncCall:
5767 CC = CC_SwiftAsync;
5768 break;
5769 case ParsedAttr::AT_VectorCall:
5770 CC = CC_X86VectorCall;
5771 break;
5772 case ParsedAttr::AT_AArch64VectorPcs:
5773 CC = CC_AArch64VectorCall;
5774 break;
5775 case ParsedAttr::AT_AArch64SVEPcs:
5776 CC = CC_AArch64SVEPCS;
5777 break;
5778 case ParsedAttr::AT_RegCall:
5779 CC = CC_X86RegCall;
5780 break;
5781 case ParsedAttr::AT_MSABI:
5782 CC = IsTargetDefaultMSABI ? CC_C : CC_Win64;
5783 break;
5784 case ParsedAttr::AT_SysVABI:
5785 CC = IsTargetDefaultMSABI ? CC_X86_64SysV : CC_C;
5786 break;
5787 case ParsedAttr::AT_Pcs: {
5788 StringRef StrRef;
5789 if (!checkStringLiteralArgumentAttr(AL: Attrs, ArgNum: 0, Str&: StrRef)) {
5790 Attrs.setInvalid();
5791 return true;
5792 }
5793 if (StrRef == "aapcs") {
5794 CC = CC_AAPCS;
5795 break;
5796 } else if (StrRef == "aapcs-vfp") {
5797 CC = CC_AAPCS_VFP;
5798 break;
5799 }
5800
5801 Attrs.setInvalid();
5802 Diag(Loc: Attrs.getLoc(), DiagID: diag::err_invalid_pcs);
5803 return true;
5804 }
5805 case ParsedAttr::AT_IntelOclBicc:
5806 CC = CC_IntelOclBicc;
5807 break;
5808 case ParsedAttr::AT_PreserveMost:
5809 CC = CC_PreserveMost;
5810 break;
5811 case ParsedAttr::AT_PreserveAll:
5812 CC = CC_PreserveAll;
5813 break;
5814 case ParsedAttr::AT_M68kRTD:
5815 CC = CC_M68kRTD;
5816 break;
5817 case ParsedAttr::AT_PreserveNone:
5818 CC = CC_PreserveNone;
5819 break;
5820 case ParsedAttr::AT_RISCVVectorCC:
5821 CC = CC_RISCVVectorCall;
5822 break;
5823 case ParsedAttr::AT_RISCVVLSCC: {
5824 // If the riscv_abi_vlen doesn't have any argument, we set set it to default
5825 // value 128.
5826 unsigned ABIVLen = 128;
5827 if (Attrs.getNumArgs() &&
5828 !checkUInt32Argument(AI: Attrs, Expr: Attrs.getArgAsExpr(Arg: 0), Val&: ABIVLen)) {
5829 Attrs.setInvalid();
5830 return true;
5831 }
5832 if (Attrs.getNumArgs() && (ABIVLen < 32 || ABIVLen > 65536)) {
5833 Attrs.setInvalid();
5834 Diag(Loc: Attrs.getLoc(), DiagID: diag::err_argument_invalid_range)
5835 << ABIVLen << 32 << 65536;
5836 return true;
5837 }
5838 if (!llvm::isPowerOf2_64(Value: ABIVLen)) {
5839 Attrs.setInvalid();
5840 Diag(Loc: Attrs.getLoc(), DiagID: diag::err_argument_not_power_of_2);
5841 return true;
5842 }
5843 CC = static_cast<CallingConv>(CallingConv::CC_RISCVVLSCall_32 +
5844 llvm::Log2_64(Value: ABIVLen) - 5);
5845 break;
5846 }
5847 case ParsedAttr::AT_DeviceKernel: {
5848 // Validation was handled in handleDeviceKernelAttr.
5849 CC = CC_DeviceKernel;
5850 break;
5851 }
5852 default: llvm_unreachable("unexpected attribute kind");
5853 }
5854
5855 TargetInfo::CallingConvCheckResult A = TargetInfo::CCCR_OK;
5856 const TargetInfo &TI = Context.getTargetInfo();
5857 auto *Aux = Context.getAuxTargetInfo();
5858 // CUDA functions may have host and/or device attributes which indicate
5859 // their targeted execution environment, therefore the calling convention
5860 // of functions in CUDA should be checked against the target deduced based
5861 // on their host/device attributes.
5862 if (LangOpts.CUDA) {
5863 assert(FD || CFT != CUDAFunctionTarget::InvalidTarget);
5864 auto CudaTarget = FD ? CUDA().IdentifyTarget(D: FD) : CFT;
5865 bool CheckHost = false, CheckDevice = false;
5866 switch (CudaTarget) {
5867 case CUDAFunctionTarget::HostDevice:
5868 CheckHost = true;
5869 CheckDevice = true;
5870 break;
5871 case CUDAFunctionTarget::Host:
5872 CheckHost = true;
5873 break;
5874 case CUDAFunctionTarget::Device:
5875 case CUDAFunctionTarget::Global:
5876 CheckDevice = true;
5877 break;
5878 case CUDAFunctionTarget::InvalidTarget:
5879 llvm_unreachable("unexpected cuda target");
5880 }
5881 auto *HostTI = LangOpts.CUDAIsDevice ? Aux : &TI;
5882 auto *DeviceTI = LangOpts.CUDAIsDevice ? &TI : Aux;
5883 if (CheckHost && HostTI)
5884 A = HostTI->checkCallingConvention(CC);
5885 if (A == TargetInfo::CCCR_OK && CheckDevice && DeviceTI)
5886 A = DeviceTI->checkCallingConvention(CC);
5887 } else if (LangOpts.SYCLIsDevice) {
5888 // During device compilation, calling conventions that are valid for the
5889 // host, for the device, and for both the host and the device may be
5890 // encountered. Diagnostics are desired for cases where the calling
5891 // convention is not supported by either the host or the device. If Aux is
5892 // null (which should rarely be the case), it isn't possible to check
5893 // whether the calling convention is supported by the host, so just assume
5894 // that it is. If the calling convention is supported for the device, there
5895 // is no need to check the host; the device target gets priority since this
5896 // check is only performed during device compilation.
5897 A = TI.checkCallingConvention(CC);
5898 if (Aux && A == TargetInfo::CCCR_Warning) {
5899 // If the calling convention would provoke a warning for the device, check
5900 // the host and preserve the warning only if the calling convention would
5901 // provoke an error for the host. Otherwise, assume this calling
5902 // convention is only used for host only functions.
5903 A = Aux->checkCallingConvention(CC);
5904 if (A == TargetInfo::CCCR_Error)
5905 A = TargetInfo::CCCR_Warning;
5906 } else if (Aux && A == TargetInfo::CCCR_Error) {
5907 // Assume this calling convention is only used for host only functions.
5908 A = Aux->checkCallingConvention(CC);
5909 }
5910 } else {
5911 A = TI.checkCallingConvention(CC);
5912 }
5913
5914 switch (A) {
5915 case TargetInfo::CCCR_OK:
5916 break;
5917
5918 case TargetInfo::CCCR_Ignore:
5919 // Treat an ignored convention as if it was an explicit C calling convention
5920 // attribute. For example, __stdcall on Win x64 functions as __cdecl, so
5921 // that command line flags that change the default convention to
5922 // __vectorcall don't affect declarations marked __stdcall.
5923 CC = CC_C;
5924 break;
5925
5926 case TargetInfo::CCCR_Error:
5927 Diag(Loc: Attrs.getLoc(), DiagID: diag::error_cconv_unsupported)
5928 << Attrs << (int)CallingConventionIgnoredReason::ForThisTarget;
5929 break;
5930
5931 case TargetInfo::CCCR_Warning: {
5932 Diag(Loc: Attrs.getLoc(), DiagID: diag::warn_cconv_unsupported)
5933 << Attrs << (int)CallingConventionIgnoredReason::ForThisTarget;
5934
5935 // This convention is not valid for the target. Use the default function or
5936 // method calling convention.
5937 bool IsCXXMethod = false, IsVariadic = false;
5938 if (FD) {
5939 IsCXXMethod = FD->isCXXInstanceMember();
5940 IsVariadic = FD->isVariadic();
5941 }
5942 CC = Context.getDefaultCallingConvention(IsVariadic, IsCXXMethod);
5943 break;
5944 }
5945 }
5946
5947 Attrs.setProcessingCache((unsigned) CC);
5948 return false;
5949}
5950
5951bool Sema::CheckRegparmAttr(const ParsedAttr &AL, unsigned &numParams) {
5952 if (AL.isInvalid())
5953 return true;
5954
5955 if (!AL.checkExactlyNumArgs(S&: *this, Num: 1)) {
5956 AL.setInvalid();
5957 return true;
5958 }
5959
5960 uint32_t NP;
5961 Expr *NumParamsExpr = AL.getArgAsExpr(Arg: 0);
5962 if (!checkUInt32Argument(AI: AL, Expr: NumParamsExpr, Val&: NP)) {
5963 AL.setInvalid();
5964 return true;
5965 }
5966
5967 if (Context.getTargetInfo().getRegParmMax() == 0) {
5968 Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_regparm_wrong_platform)
5969 << NumParamsExpr->getSourceRange();
5970 AL.setInvalid();
5971 return true;
5972 }
5973
5974 numParams = NP;
5975 if (numParams > Context.getTargetInfo().getRegParmMax()) {
5976 Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_regparm_invalid_number)
5977 << Context.getTargetInfo().getRegParmMax() << NumParamsExpr->getSourceRange();
5978 AL.setInvalid();
5979 return true;
5980 }
5981
5982 return false;
5983}
5984
5985// Helper to get OffloadArch.
5986static OffloadArch getOffloadArch(const TargetInfo &TI) {
5987 if (!TI.getTriple().isNVPTX())
5988 llvm_unreachable("getOffloadArch is only valid for NVPTX triple");
5989 auto &TO = TI.getTargetOpts();
5990 return StringToOffloadArch(S: TO.CPU);
5991}
5992
5993// Checks whether an argument of launch_bounds attribute is
5994// acceptable, performs implicit conversion to Rvalue, and returns
5995// non-nullptr Expr result on success. Otherwise, it returns nullptr
5996// and may output an error.
5997static Expr *makeLaunchBoundsArgExpr(Sema &S, Expr *E,
5998 const CUDALaunchBoundsAttr &AL,
5999 const unsigned Idx) {
6000 if (S.DiagnoseUnexpandedParameterPack(E))
6001 return nullptr;
6002
6003 // Accept template arguments for now as they depend on something else.
6004 // We'll get to check them when they eventually get instantiated.
6005 if (E->isValueDependent())
6006 return E;
6007
6008 std::optional<llvm::APSInt> I = llvm::APSInt(64);
6009 if (!(I = E->getIntegerConstantExpr(Ctx: S.Context))) {
6010 S.Diag(Loc: E->getExprLoc(), DiagID: diag::err_attribute_argument_n_type)
6011 << &AL << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
6012 return nullptr;
6013 }
6014 // Make sure we can fit it in 32 bits.
6015 if (!I->isIntN(N: 32)) {
6016 S.Diag(Loc: E->getExprLoc(), DiagID: diag::err_ice_too_large)
6017 << toString(I: *I, Radix: 10, Signed: false) << 32 << /* Unsigned */ 1;
6018 return nullptr;
6019 }
6020 if (*I < 0)
6021 S.Diag(Loc: E->getExprLoc(), DiagID: diag::warn_attribute_argument_n_negative)
6022 << &AL << Idx << E->getSourceRange();
6023
6024 // We may need to perform implicit conversion of the argument.
6025 InitializedEntity Entity = InitializedEntity::InitializeParameter(
6026 Context&: S.Context, Type: S.Context.getConstType(T: S.Context.IntTy), /*consume*/ Consumed: false);
6027 ExprResult ValArg = S.PerformCopyInitialization(Entity, EqualLoc: SourceLocation(), Init: E);
6028 assert(!ValArg.isInvalid() &&
6029 "Unexpected PerformCopyInitialization() failure.");
6030
6031 return ValArg.getAs<Expr>();
6032}
6033
6034CUDALaunchBoundsAttr *
6035Sema::CreateLaunchBoundsAttr(const AttributeCommonInfo &CI, Expr *MaxThreads,
6036 Expr *MinBlocks, Expr *MaxBlocks,
6037 bool IgnoreArch) {
6038 CUDALaunchBoundsAttr TmpAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);
6039 MaxThreads = makeLaunchBoundsArgExpr(S&: *this, E: MaxThreads, AL: TmpAttr, Idx: 0);
6040 if (!MaxThreads)
6041 return nullptr;
6042
6043 if (MinBlocks) {
6044 MinBlocks = makeLaunchBoundsArgExpr(S&: *this, E: MinBlocks, AL: TmpAttr, Idx: 1);
6045 if (!MinBlocks)
6046 return nullptr;
6047 }
6048
6049 if (MaxBlocks) {
6050 // We might want to ignore the nvptx arch check, e.g., when processing the
6051 // launch bounds attribute within ompx_attribute to support other archs.
6052 if (!IgnoreArch) {
6053 // '.maxclusterrank' ptx directive requires .target sm_90 or higher.
6054 auto SM = getOffloadArch(TI: Context.getTargetInfo());
6055 if (SM == OffloadArch::Unknown || SM < OffloadArch::SM_90) {
6056 Diag(Loc: MaxBlocks->getBeginLoc(), DiagID: diag::warn_cuda_maxclusterrank_sm_90)
6057 << OffloadArchToString(A: SM) << CI << MaxBlocks->getSourceRange();
6058 // Ignore it by setting MaxBlocks to null;
6059 MaxBlocks = nullptr;
6060 }
6061 }
6062
6063 if (MaxBlocks) {
6064 MaxBlocks = makeLaunchBoundsArgExpr(S&: *this, E: MaxBlocks, AL: TmpAttr, Idx: 2);
6065 if (!MaxBlocks)
6066 return nullptr;
6067 }
6068 }
6069
6070 return ::new (Context)
6071 CUDALaunchBoundsAttr(Context, CI, MaxThreads, MinBlocks, MaxBlocks);
6072}
6073
6074void Sema::AddLaunchBoundsAttr(Decl *D, const AttributeCommonInfo &CI,
6075 Expr *MaxThreads, Expr *MinBlocks,
6076 Expr *MaxBlocks) {
6077 if (auto *Attr = CreateLaunchBoundsAttr(CI, MaxThreads, MinBlocks, MaxBlocks))
6078 D->addAttr(A: Attr);
6079}
6080
6081static void handleLaunchBoundsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6082 if (!AL.checkAtLeastNumArgs(S, Num: 1) || !AL.checkAtMostNumArgs(S, Num: 3))
6083 return;
6084
6085 S.AddLaunchBoundsAttr(D, CI: AL, MaxThreads: AL.getArgAsExpr(Arg: 0),
6086 MinBlocks: AL.getNumArgs() > 1 ? AL.getArgAsExpr(Arg: 1) : nullptr,
6087 MaxBlocks: AL.getNumArgs() > 2 ? AL.getArgAsExpr(Arg: 2) : nullptr);
6088}
6089
6090static std::pair<Expr *, int>
6091makeClusterDimsArgExpr(Sema &S, Expr *E, const CUDAClusterDimsAttr &AL,
6092 const unsigned Idx) {
6093 if (!E || S.DiagnoseUnexpandedParameterPack(E))
6094 return {};
6095
6096 // Accept template arguments for now as they depend on something else.
6097 // We'll get to check them when they eventually get instantiated.
6098 if (E->isInstantiationDependent())
6099 return {E, 1};
6100
6101 std::optional<llvm::APSInt> I = E->getIntegerConstantExpr(Ctx: S.Context);
6102 if (!I) {
6103 S.Diag(Loc: E->getExprLoc(), DiagID: diag::err_attribute_argument_n_type)
6104 << &AL << Idx << AANT_ArgumentIntegerConstant << E->getSourceRange();
6105 return {};
6106 }
6107 // Make sure we can fit it in 4 bits.
6108 if (!I->isIntN(N: 4)) {
6109 S.Diag(Loc: E->getExprLoc(), DiagID: diag::err_ice_too_large)
6110 << toString(I: *I, Radix: 10, Signed: false) << 4 << /*Unsigned=*/1;
6111 return {};
6112 }
6113 if (*I < 0) {
6114 S.Diag(Loc: E->getExprLoc(), DiagID: diag::warn_attribute_argument_n_negative)
6115 << &AL << Idx << E->getSourceRange();
6116 }
6117
6118 return {ConstantExpr::Create(Context: S.getASTContext(), E, Result: APValue(*I)),
6119 I->getZExtValue()};
6120}
6121
6122CUDAClusterDimsAttr *Sema::createClusterDimsAttr(const AttributeCommonInfo &CI,
6123 Expr *X, Expr *Y, Expr *Z) {
6124 CUDAClusterDimsAttr TmpAttr(Context, CI, X, Y, Z);
6125
6126 auto [NewX, ValX] = makeClusterDimsArgExpr(S&: *this, E: X, AL: TmpAttr, /*Idx=*/0);
6127 auto [NewY, ValY] = makeClusterDimsArgExpr(S&: *this, E: Y, AL: TmpAttr, /*Idx=*/1);
6128 auto [NewZ, ValZ] = makeClusterDimsArgExpr(S&: *this, E: Z, AL: TmpAttr, /*Idx=*/2);
6129
6130 if (!NewX || (Y && !NewY) || (Z && !NewZ))
6131 return nullptr;
6132
6133 int FlatDim = ValX * ValY * ValZ;
6134 const llvm::Triple TT =
6135 (!Context.getLangOpts().CUDAIsDevice && Context.getAuxTargetInfo())
6136 ? Context.getAuxTargetInfo()->getTriple()
6137 : Context.getTargetInfo().getTriple();
6138 int MaxDim = 1;
6139 if (TT.isNVPTX())
6140 MaxDim = 8;
6141 else if (TT.isAMDGPU())
6142 MaxDim = 16;
6143 else
6144 return nullptr;
6145
6146 // A maximum of 8 thread blocks in a cluster is supported as a portable
6147 // cluster size in CUDA. The number is 16 for AMDGPU.
6148 if (FlatDim > MaxDim) {
6149 Diag(Loc: CI.getLoc(), DiagID: diag::err_cluster_dims_too_large) << MaxDim << FlatDim;
6150 return nullptr;
6151 }
6152
6153 return CUDAClusterDimsAttr::Create(Ctx&: Context, X: NewX, Y: NewY, Z: NewZ, CommonInfo: CI);
6154}
6155
6156void Sema::addClusterDimsAttr(Decl *D, const AttributeCommonInfo &CI, Expr *X,
6157 Expr *Y, Expr *Z) {
6158 if (auto *Attr = createClusterDimsAttr(CI, X, Y, Z))
6159 D->addAttr(A: Attr);
6160}
6161
6162void Sema::addNoClusterAttr(Decl *D, const AttributeCommonInfo &CI) {
6163 D->addAttr(A: CUDANoClusterAttr::Create(Ctx&: Context, CommonInfo: CI));
6164}
6165
6166static void handleClusterDimsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6167 const TargetInfo &TTI = S.Context.getTargetInfo();
6168 OffloadArch Arch = StringToOffloadArch(S: TTI.getTargetOpts().CPU);
6169 if ((TTI.getTriple().isNVPTX() && Arch < clang::OffloadArch::SM_90) ||
6170 (TTI.getTriple().isAMDGPU() &&
6171 !TTI.hasFeatureEnabled(Features: TTI.getTargetOpts().FeatureMap, Name: "clusters"))) {
6172 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_cluster_attr_not_supported) << AL;
6173 return;
6174 }
6175
6176 if (!AL.checkAtLeastNumArgs(S, /*Num=*/1) ||
6177 !AL.checkAtMostNumArgs(S, /*Num=*/3))
6178 return;
6179
6180 S.addClusterDimsAttr(D, CI: AL, X: AL.getArgAsExpr(Arg: 0),
6181 Y: AL.getNumArgs() > 1 ? AL.getArgAsExpr(Arg: 1) : nullptr,
6182 Z: AL.getNumArgs() > 2 ? AL.getArgAsExpr(Arg: 2) : nullptr);
6183}
6184
6185static void handleNoClusterAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6186 const TargetInfo &TTI = S.Context.getTargetInfo();
6187 OffloadArch Arch = StringToOffloadArch(S: TTI.getTargetOpts().CPU);
6188 if ((TTI.getTriple().isNVPTX() && Arch < clang::OffloadArch::SM_90) ||
6189 (TTI.getTriple().isAMDGPU() &&
6190 !TTI.hasFeatureEnabled(Features: TTI.getTargetOpts().FeatureMap, Name: "clusters"))) {
6191 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_cluster_attr_not_supported) << AL;
6192 return;
6193 }
6194
6195 S.addNoClusterAttr(D, CI: AL);
6196}
6197
6198static void handleArgumentWithTypeTagAttr(Sema &S, Decl *D,
6199 const ParsedAttr &AL) {
6200 if (!AL.isArgIdent(Arg: 0)) {
6201 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
6202 << AL << /* arg num = */ 1 << AANT_ArgumentIdentifier;
6203 return;
6204 }
6205
6206 ParamIdx ArgumentIdx;
6207 if (!S.checkFunctionOrMethodParameterIndex(
6208 D, AI: AL, AttrArgNum: 2, IdxExpr: AL.getArgAsExpr(Arg: 1), Idx&: ArgumentIdx,
6209 /*CanIndexImplicitThis=*/false,
6210 /*CanIndexVariadicArguments=*/true))
6211 return;
6212
6213 ParamIdx TypeTagIdx;
6214 if (!S.checkFunctionOrMethodParameterIndex(
6215 D, AI: AL, AttrArgNum: 3, IdxExpr: AL.getArgAsExpr(Arg: 2), Idx&: TypeTagIdx,
6216 /*CanIndexImplicitThis=*/false,
6217 /*CanIndexVariadicArguments=*/true))
6218 return;
6219
6220 bool IsPointer = AL.getAttrName()->getName() == "pointer_with_type_tag";
6221 if (IsPointer) {
6222 // Ensure that buffer has a pointer type.
6223 unsigned ArgumentIdxAST = ArgumentIdx.getASTIndex();
6224 if (ArgumentIdxAST >= getFunctionOrMethodNumParams(D) ||
6225 !getFunctionOrMethodParamType(D, Idx: ArgumentIdxAST)->isPointerType())
6226 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_pointers_only) << AL << 0;
6227 }
6228
6229 D->addAttr(A: ::new (S.Context) ArgumentWithTypeTagAttr(
6230 S.Context, AL, AL.getArgAsIdent(Arg: 0)->getIdentifierInfo(), ArgumentIdx,
6231 TypeTagIdx, IsPointer));
6232}
6233
6234static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
6235 const ParsedAttr &AL) {
6236 if (!AL.isArgIdent(Arg: 0)) {
6237 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
6238 << AL << 1 << AANT_ArgumentIdentifier;
6239 return;
6240 }
6241
6242 if (!AL.checkExactlyNumArgs(S, Num: 1))
6243 return;
6244
6245 if (!isa<VarDecl>(Val: D)) {
6246 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_wrong_decl_type)
6247 << AL << AL.isRegularKeywordAttribute() << ExpectedVariable;
6248 return;
6249 }
6250
6251 IdentifierInfo *PointerKind = AL.getArgAsIdent(Arg: 0)->getIdentifierInfo();
6252 TypeSourceInfo *MatchingCTypeLoc = nullptr;
6253 S.GetTypeFromParser(Ty: AL.getMatchingCType(), TInfo: &MatchingCTypeLoc);
6254 assert(MatchingCTypeLoc && "no type source info for attribute argument");
6255
6256 D->addAttr(A: ::new (S.Context) TypeTagForDatatypeAttr(
6257 S.Context, AL, PointerKind, MatchingCTypeLoc, AL.getLayoutCompatible(),
6258 AL.getMustBeNull()));
6259}
6260
6261static void handleXRayLogArgsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6262 ParamIdx ArgCount;
6263
6264 if (!S.checkFunctionOrMethodParameterIndex(D, AI: AL, AttrArgNum: 1, IdxExpr: AL.getArgAsExpr(Arg: 0),
6265 Idx&: ArgCount,
6266 CanIndexImplicitThis: true /* CanIndexImplicitThis */))
6267 return;
6268
6269 // ArgCount isn't a parameter index [0;n), it's a count [1;n]
6270 D->addAttr(A: ::new (S.Context)
6271 XRayLogArgsAttr(S.Context, AL, ArgCount.getSourceIndex()));
6272}
6273
6274static void handlePatchableFunctionEntryAttr(Sema &S, Decl *D,
6275 const ParsedAttr &AL) {
6276 if (S.Context.getTargetInfo().getTriple().isOSAIX()) {
6277 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_aix_attr_unsupported) << AL;
6278 return;
6279 }
6280 uint32_t Count = 0, Offset = 0;
6281 StringRef Section;
6282 if (!S.checkUInt32Argument(AI: AL, Expr: AL.getArgAsExpr(Arg: 0), Val&: Count, Idx: 0, StrictlyUnsigned: true))
6283 return;
6284 if (AL.getNumArgs() >= 2) {
6285 Expr *Arg = AL.getArgAsExpr(Arg: 1);
6286 if (!S.checkUInt32Argument(AI: AL, Expr: Arg, Val&: Offset, Idx: 1, StrictlyUnsigned: true))
6287 return;
6288 if (Count < Offset) {
6289 S.Diag(Loc: S.getAttrLoc(CI: AL), DiagID: diag::err_attribute_argument_out_of_range)
6290 << &AL << 0 << Count << Arg->getBeginLoc();
6291 return;
6292 }
6293 }
6294 if (AL.getNumArgs() == 3) {
6295 SourceLocation LiteralLoc;
6296 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 2, Str&: Section, ArgLocation: &LiteralLoc))
6297 return;
6298 if (llvm::Error E = S.isValidSectionSpecifier(SecName: Section)) {
6299 S.Diag(Loc: LiteralLoc,
6300 DiagID: diag::err_attribute_patchable_function_entry_invalid_section)
6301 << toString(E: std::move(E));
6302 return;
6303 }
6304 if (Section.empty()) {
6305 S.Diag(Loc: LiteralLoc,
6306 DiagID: diag::err_attribute_patchable_function_entry_invalid_section)
6307 << "section must not be empty";
6308 return;
6309 }
6310 }
6311 D->addAttr(A: ::new (S.Context) PatchableFunctionEntryAttr(S.Context, AL, Count,
6312 Offset, Section));
6313}
6314
6315static void handleBuiltinAliasAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6316 if (!AL.isArgIdent(Arg: 0)) {
6317 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
6318 << AL << 1 << AANT_ArgumentIdentifier;
6319 return;
6320 }
6321
6322 IdentifierInfo *Ident = AL.getArgAsIdent(Arg: 0)->getIdentifierInfo();
6323 unsigned BuiltinID = Ident->getBuiltinID();
6324 StringRef AliasName = cast<FunctionDecl>(Val: D)->getIdentifier()->getName();
6325
6326 bool IsAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
6327 bool IsARM = S.Context.getTargetInfo().getTriple().isARM();
6328 bool IsRISCV = S.Context.getTargetInfo().getTriple().isRISCV();
6329 bool IsSPIRV = S.Context.getTargetInfo().getTriple().isSPIRV();
6330 bool IsHLSL = S.Context.getLangOpts().HLSL;
6331 if ((IsAArch64 && !S.ARM().SveAliasValid(BuiltinID, AliasName)) ||
6332 (IsARM && !S.ARM().MveAliasValid(BuiltinID, AliasName) &&
6333 !S.ARM().CdeAliasValid(BuiltinID, AliasName)) ||
6334 (IsRISCV && !S.RISCV().isAliasValid(BuiltinID, AliasName)) ||
6335 (!IsAArch64 && !IsARM && !IsRISCV && !IsHLSL && !IsSPIRV)) {
6336 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_builtin_alias) << AL;
6337 return;
6338 }
6339
6340 D->addAttr(A: ::new (S.Context) BuiltinAliasAttr(S.Context, AL, Ident));
6341}
6342
6343static void handleNullableTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6344 if (AL.isUsedAsTypeAttr())
6345 return;
6346
6347 if (auto *CRD = dyn_cast<CXXRecordDecl>(Val: D);
6348 !CRD || !(CRD->isClass() || CRD->isStruct())) {
6349 S.Diag(Loc: AL.getRange().getBegin(), DiagID: diag::err_attribute_wrong_decl_type)
6350 << AL << AL.isRegularKeywordAttribute() << ExpectedClass;
6351 return;
6352 }
6353
6354 handleSimpleAttribute<TypeNullableAttr>(S, D, CI: AL);
6355}
6356
6357static void handlePreferredTypeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6358 if (!AL.hasParsedType()) {
6359 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_wrong_number_arguments) << AL << 1;
6360 return;
6361 }
6362
6363 TypeSourceInfo *ParmTSI = nullptr;
6364 QualType QT = S.GetTypeFromParser(Ty: AL.getTypeArg(), TInfo: &ParmTSI);
6365 assert(ParmTSI && "no type source info for attribute argument");
6366 S.RequireCompleteType(Loc: ParmTSI->getTypeLoc().getBeginLoc(), T: QT,
6367 DiagID: diag::err_incomplete_type);
6368
6369 D->addAttr(A: ::new (S.Context) PreferredTypeAttr(S.Context, AL, ParmTSI));
6370}
6371
6372//===----------------------------------------------------------------------===//
6373// Microsoft specific attribute handlers.
6374//===----------------------------------------------------------------------===//
6375
6376UuidAttr *Sema::mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI,
6377 StringRef UuidAsWritten, MSGuidDecl *GuidDecl) {
6378 if (const auto *UA = D->getAttr<UuidAttr>()) {
6379 if (declaresSameEntity(D1: UA->getGuidDecl(), D2: GuidDecl))
6380 return nullptr;
6381 if (!UA->getGuid().empty()) {
6382 Diag(Loc: UA->getLocation(), DiagID: diag::err_mismatched_uuid);
6383 Diag(Loc: CI.getLoc(), DiagID: diag::note_previous_uuid);
6384 D->dropAttr<UuidAttr>();
6385 }
6386 }
6387
6388 return ::new (Context) UuidAttr(Context, CI, UuidAsWritten, GuidDecl);
6389}
6390
6391static void handleUuidAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6392 if (!S.LangOpts.CPlusPlus) {
6393 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_not_supported_in_lang)
6394 << AL << AttributeLangSupport::C;
6395 return;
6396 }
6397
6398 StringRef OrigStrRef;
6399 SourceLocation LiteralLoc;
6400 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: OrigStrRef, ArgLocation: &LiteralLoc))
6401 return;
6402
6403 // GUID format is "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" or
6404 // "{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}", normalize to the former.
6405 StringRef StrRef = OrigStrRef;
6406 if (StrRef.size() == 38 && StrRef.front() == '{' && StrRef.back() == '}')
6407 StrRef = StrRef.drop_front().drop_back();
6408
6409 // Validate GUID length.
6410 if (StrRef.size() != 36) {
6411 S.Diag(Loc: LiteralLoc, DiagID: diag::err_attribute_uuid_malformed_guid);
6412 return;
6413 }
6414
6415 for (unsigned i = 0; i < 36; ++i) {
6416 if (i == 8 || i == 13 || i == 18 || i == 23) {
6417 if (StrRef[i] != '-') {
6418 S.Diag(Loc: LiteralLoc, DiagID: diag::err_attribute_uuid_malformed_guid);
6419 return;
6420 }
6421 } else if (!isHexDigit(c: StrRef[i])) {
6422 S.Diag(Loc: LiteralLoc, DiagID: diag::err_attribute_uuid_malformed_guid);
6423 return;
6424 }
6425 }
6426
6427 // Convert to our parsed format and canonicalize.
6428 MSGuidDecl::Parts Parsed;
6429 StrRef.substr(Start: 0, N: 8).getAsInteger(Radix: 16, Result&: Parsed.Part1);
6430 StrRef.substr(Start: 9, N: 4).getAsInteger(Radix: 16, Result&: Parsed.Part2);
6431 StrRef.substr(Start: 14, N: 4).getAsInteger(Radix: 16, Result&: Parsed.Part3);
6432 for (unsigned i = 0; i != 8; ++i)
6433 StrRef.substr(Start: 19 + 2 * i + (i >= 2 ? 1 : 0), N: 2)
6434 .getAsInteger(Radix: 16, Result&: Parsed.Part4And5[i]);
6435 MSGuidDecl *Guid = S.Context.getMSGuidDecl(Parts: Parsed);
6436
6437 // FIXME: It'd be nice to also emit a fixit removing uuid(...) (and, if it's
6438 // the only thing in the [] list, the [] too), and add an insertion of
6439 // __declspec(uuid(...)). But sadly, neither the SourceLocs of the commas
6440 // separating attributes nor of the [ and the ] are in the AST.
6441 // Cf "SourceLocations of attribute list delimiters - [[ ... , ... ]] etc"
6442 // on cfe-dev.
6443 if (AL.isMicrosoftAttribute()) // Check for [uuid(...)] spelling.
6444 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_atl_uuid_deprecated);
6445
6446 UuidAttr *UA = S.mergeUuidAttr(D, CI: AL, UuidAsWritten: OrigStrRef, GuidDecl: Guid);
6447 if (UA)
6448 D->addAttr(A: UA);
6449}
6450
6451static void handleMSInheritanceAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6452 if (!S.LangOpts.CPlusPlus) {
6453 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_not_supported_in_lang)
6454 << AL << AttributeLangSupport::C;
6455 return;
6456 }
6457 MSInheritanceAttr *IA = S.mergeMSInheritanceAttr(
6458 D, CI: AL, /*BestCase=*/true, Model: (MSInheritanceModel)AL.getSemanticSpelling());
6459 if (IA) {
6460 D->addAttr(A: IA);
6461 S.Consumer.AssignInheritanceModel(RD: cast<CXXRecordDecl>(Val: D));
6462 }
6463}
6464
6465static void handleDeclspecThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6466 const auto *VD = cast<VarDecl>(Val: D);
6467 if (!S.Context.getTargetInfo().isTLSSupported()) {
6468 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_thread_unsupported);
6469 return;
6470 }
6471 if (VD->getTSCSpec() != TSCS_unspecified) {
6472 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_declspec_thread_on_thread_variable);
6473 return;
6474 }
6475 if (VD->hasLocalStorage()) {
6476 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_thread_non_global) << "__declspec(thread)";
6477 return;
6478 }
6479 D->addAttr(A: ::new (S.Context) ThreadAttr(S.Context, AL));
6480}
6481
6482static void handleMSConstexprAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6483 if (!S.getLangOpts().isCompatibleWithMSVC(MajorVersion: LangOptions::MSVC2022_3)) {
6484 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_unknown_attribute_ignored)
6485 << AL << AL.getRange();
6486 return;
6487 }
6488 auto *FD = cast<FunctionDecl>(Val: D);
6489 if (FD->isConstexprSpecified() || FD->isConsteval()) {
6490 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_ms_constexpr_cannot_be_applied)
6491 << FD->isConsteval() << FD;
6492 return;
6493 }
6494 if (auto *MD = dyn_cast<CXXMethodDecl>(Val: FD)) {
6495 if (!S.getLangOpts().CPlusPlus20 && MD->isVirtual()) {
6496 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_ms_constexpr_cannot_be_applied)
6497 << /*virtual*/ 2 << MD;
6498 return;
6499 }
6500 }
6501 D->addAttr(A: ::new (S.Context) MSConstexprAttr(S.Context, AL));
6502}
6503
6504static void handleMSStructAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6505 if (const auto *First = D->getAttr<GCCStructAttr>()) {
6506 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attributes_are_not_compatible)
6507 << AL << First << 0;
6508 S.Diag(Loc: First->getLocation(), DiagID: diag::note_conflicting_attribute);
6509 return;
6510 }
6511 if (const auto *Preexisting = D->getAttr<MSStructAttr>()) {
6512 if (Preexisting->isImplicit())
6513 D->dropAttr<MSStructAttr>();
6514 }
6515
6516 D->addAttr(A: ::new (S.Context) MSStructAttr(S.Context, AL));
6517}
6518
6519static void handleGCCStructAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6520 if (const auto *First = D->getAttr<MSStructAttr>()) {
6521 if (First->isImplicit()) {
6522 D->dropAttr<MSStructAttr>();
6523 } else {
6524 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attributes_are_not_compatible)
6525 << AL << First << 0;
6526 S.Diag(Loc: First->getLocation(), DiagID: diag::note_conflicting_attribute);
6527 return;
6528 }
6529 }
6530
6531 D->addAttr(A: ::new (S.Context) GCCStructAttr(S.Context, AL));
6532}
6533
6534static void handleAbiTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6535 SmallVector<StringRef, 4> Tags;
6536 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
6537 StringRef Tag;
6538 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: Tag))
6539 return;
6540 Tags.push_back(Elt: Tag);
6541 }
6542
6543 if (const auto *NS = dyn_cast<NamespaceDecl>(Val: D)) {
6544 if (!NS->isInline()) {
6545 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attr_abi_tag_namespace) << 0;
6546 return;
6547 }
6548 if (NS->isAnonymousNamespace()) {
6549 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attr_abi_tag_namespace) << 1;
6550 return;
6551 }
6552 if (AL.getNumArgs() == 0)
6553 Tags.push_back(Elt: NS->getName());
6554 } else if (!AL.checkAtLeastNumArgs(S, Num: 1))
6555 return;
6556
6557 // Store tags sorted and without duplicates.
6558 llvm::sort(C&: Tags);
6559 Tags.erase(CS: llvm::unique(R&: Tags), CE: Tags.end());
6560
6561 D->addAttr(A: ::new (S.Context)
6562 AbiTagAttr(S.Context, AL, Tags.data(), Tags.size()));
6563}
6564
6565static bool hasBTFDeclTagAttr(Decl *D, StringRef Tag) {
6566 for (const auto *I : D->specific_attrs<BTFDeclTagAttr>()) {
6567 if (I->getBTFDeclTag() == Tag)
6568 return true;
6569 }
6570 return false;
6571}
6572
6573static void handleBTFDeclTagAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6574 StringRef Str;
6575 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str))
6576 return;
6577 if (hasBTFDeclTagAttr(D, Tag: Str))
6578 return;
6579
6580 D->addAttr(A: ::new (S.Context) BTFDeclTagAttr(S.Context, AL, Str));
6581}
6582
6583BTFDeclTagAttr *Sema::mergeBTFDeclTagAttr(Decl *D, const BTFDeclTagAttr &AL) {
6584 if (hasBTFDeclTagAttr(D, Tag: AL.getBTFDeclTag()))
6585 return nullptr;
6586 return ::new (Context) BTFDeclTagAttr(Context, AL, AL.getBTFDeclTag());
6587}
6588
6589static void handleInterruptAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6590 // Dispatch the interrupt attribute based on the current target.
6591 switch (S.Context.getTargetInfo().getTriple().getArch()) {
6592 case llvm::Triple::msp430:
6593 S.MSP430().handleInterruptAttr(D, AL);
6594 break;
6595 case llvm::Triple::mipsel:
6596 case llvm::Triple::mips:
6597 S.MIPS().handleInterruptAttr(D, AL);
6598 break;
6599 case llvm::Triple::m68k:
6600 S.M68k().handleInterruptAttr(D, AL);
6601 break;
6602 case llvm::Triple::x86:
6603 case llvm::Triple::x86_64:
6604 S.X86().handleAnyInterruptAttr(D, AL);
6605 break;
6606 case llvm::Triple::avr:
6607 S.AVR().handleInterruptAttr(D, AL);
6608 break;
6609 case llvm::Triple::riscv32:
6610 case llvm::Triple::riscv64:
6611 case llvm::Triple::riscv32be:
6612 case llvm::Triple::riscv64be:
6613 S.RISCV().handleInterruptAttr(D, AL);
6614 break;
6615 default:
6616 S.ARM().handleInterruptAttr(D, AL);
6617 break;
6618 }
6619}
6620
6621static void handleLayoutVersion(Sema &S, Decl *D, const ParsedAttr &AL) {
6622 uint32_t Version;
6623 Expr *VersionExpr = AL.getArgAsExpr(Arg: 0);
6624 if (!S.checkUInt32Argument(AI: AL, Expr: AL.getArgAsExpr(Arg: 0), Val&: Version))
6625 return;
6626
6627 // TODO: Investigate what happens with the next major version of MSVC.
6628 if (Version != LangOptions::MSVC2015 / 100) {
6629 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_out_of_bounds)
6630 << AL << Version << VersionExpr->getSourceRange();
6631 return;
6632 }
6633
6634 // The attribute expects a "major" version number like 19, but new versions of
6635 // MSVC have moved to updating the "minor", or less significant numbers, so we
6636 // have to multiply by 100 now.
6637 Version *= 100;
6638
6639 D->addAttr(A: ::new (S.Context) LayoutVersionAttr(S.Context, AL, Version));
6640}
6641
6642DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D,
6643 const AttributeCommonInfo &CI) {
6644 if (D->hasAttr<DLLExportAttr>()) {
6645 Diag(Loc: CI.getLoc(), DiagID: diag::warn_attribute_ignored) << "'dllimport'";
6646 return nullptr;
6647 }
6648
6649 if (D->hasAttr<DLLImportAttr>())
6650 return nullptr;
6651
6652 return ::new (Context) DLLImportAttr(Context, CI);
6653}
6654
6655DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D,
6656 const AttributeCommonInfo &CI) {
6657 if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
6658 Diag(Loc: Import->getLocation(), DiagID: diag::warn_attribute_ignored) << Import;
6659 D->dropAttr<DLLImportAttr>();
6660 }
6661
6662 if (D->hasAttr<DLLExportAttr>())
6663 return nullptr;
6664
6665 return ::new (Context) DLLExportAttr(Context, CI);
6666}
6667
6668static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) {
6669 if (isa<ClassTemplatePartialSpecializationDecl>(Val: D) &&
6670 (S.Context.getTargetInfo().shouldDLLImportComdatSymbols())) {
6671 S.Diag(Loc: A.getRange().getBegin(), DiagID: diag::warn_attribute_ignored) << A;
6672 return;
6673 }
6674
6675 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
6676 if (FD->isInlined() && A.getKind() == ParsedAttr::AT_DLLImport &&
6677 !(S.Context.getTargetInfo().shouldDLLImportComdatSymbols())) {
6678 // MinGW doesn't allow dllimport on inline functions.
6679 S.Diag(Loc: A.getRange().getBegin(), DiagID: diag::warn_attribute_ignored_on_inline)
6680 << A;
6681 return;
6682 }
6683 }
6684
6685 if (const auto *MD = dyn_cast<CXXMethodDecl>(Val: D)) {
6686 if ((S.Context.getTargetInfo().shouldDLLImportComdatSymbols()) &&
6687 MD->getParent()->isLambda()) {
6688 S.Diag(Loc: A.getRange().getBegin(), DiagID: diag::err_attribute_dll_lambda) << A;
6689 return;
6690 }
6691 }
6692
6693 if (auto *EA = D->getAttr<ExcludeFromExplicitInstantiationAttr>()) {
6694 S.Diag(Loc: A.getRange().getBegin(),
6695 DiagID: diag::warn_dllattr_ignored_exclusion_takes_precedence)
6696 << A << EA;
6697 return;
6698 }
6699
6700 Attr *NewAttr = A.getKind() == ParsedAttr::AT_DLLExport
6701 ? (Attr *)S.mergeDLLExportAttr(D, CI: A)
6702 : (Attr *)S.mergeDLLImportAttr(D, CI: A);
6703 if (NewAttr)
6704 D->addAttr(A: NewAttr);
6705}
6706
6707MSInheritanceAttr *
6708Sema::mergeMSInheritanceAttr(Decl *D, const AttributeCommonInfo &CI,
6709 bool BestCase,
6710 MSInheritanceModel Model) {
6711 if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) {
6712 if (IA->getInheritanceModel() == Model)
6713 return nullptr;
6714 Diag(Loc: IA->getLocation(), DiagID: diag::err_mismatched_ms_inheritance)
6715 << 1 /*previous declaration*/;
6716 Diag(Loc: CI.getLoc(), DiagID: diag::note_previous_ms_inheritance);
6717 D->dropAttr<MSInheritanceAttr>();
6718 }
6719
6720 auto *RD = cast<CXXRecordDecl>(Val: D);
6721 if (RD->hasDefinition()) {
6722 if (checkMSInheritanceAttrOnDefinition(RD, Range: CI.getRange(), BestCase,
6723 ExplicitModel: Model)) {
6724 return nullptr;
6725 }
6726 } else {
6727 if (isa<ClassTemplatePartialSpecializationDecl>(Val: RD)) {
6728 Diag(Loc: CI.getLoc(), DiagID: diag::warn_ignored_ms_inheritance)
6729 << 1 /*partial specialization*/;
6730 return nullptr;
6731 }
6732 if (RD->getDescribedClassTemplate()) {
6733 Diag(Loc: CI.getLoc(), DiagID: diag::warn_ignored_ms_inheritance)
6734 << 0 /*primary template*/;
6735 return nullptr;
6736 }
6737 }
6738
6739 return ::new (Context) MSInheritanceAttr(Context, CI, BestCase);
6740}
6741
6742static void handleCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6743 // The capability attributes take a single string parameter for the name of
6744 // the capability they represent. The lockable attribute does not take any
6745 // parameters. However, semantically, both attributes represent the same
6746 // concept, and so they use the same semantic attribute. Eventually, the
6747 // lockable attribute will be removed.
6748 //
6749 // For backward compatibility, any capability which has no specified string
6750 // literal will be considered a "mutex."
6751 StringRef N("mutex");
6752 SourceLocation LiteralLoc;
6753 if (AL.getKind() == ParsedAttr::AT_Capability &&
6754 !S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: N, ArgLocation: &LiteralLoc))
6755 return;
6756
6757 D->addAttr(A: ::new (S.Context) CapabilityAttr(S.Context, AL, N));
6758}
6759
6760static void handleReentrantCapabilityAttr(Sema &S, Decl *D,
6761 const ParsedAttr &AL) {
6762 // Do not permit 'reentrant_capability' without 'capability(..)'. Note that
6763 // the check here requires 'capability' to be before 'reentrant_capability'.
6764 // This helps enforce a canonical style. Also avoids placing an additional
6765 // branch into ProcessDeclAttributeList().
6766 if (!D->hasAttr<CapabilityAttr>()) {
6767 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_thread_attribute_requires_preceded)
6768 << AL << cast<NamedDecl>(Val: D) << "'capability'";
6769 return;
6770 }
6771
6772 D->addAttr(A: ::new (S.Context) ReentrantCapabilityAttr(S.Context, AL));
6773}
6774
6775static void handleAssertCapabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6776 if (!checkThreadSafetyAttrSubject(S, D, AL))
6777 return;
6778
6779 SmallVector<Expr*, 1> Args;
6780 if (!checkLockFunAttrCommon(S, D, AL, Args))
6781 return;
6782
6783 D->addAttr(A: ::new (S.Context)
6784 AssertCapabilityAttr(S.Context, AL, Args.data(), Args.size()));
6785}
6786
6787static void handleAcquireCapabilityAttr(Sema &S, Decl *D,
6788 const ParsedAttr &AL) {
6789 if (!checkThreadSafetyAttrSubject(S, D, AL, /*CheckParmVar=*/true))
6790 return;
6791
6792 SmallVector<Expr*, 1> Args;
6793 if (!checkLockFunAttrCommon(S, D, AL, Args))
6794 return;
6795
6796 D->addAttr(A: ::new (S.Context) AcquireCapabilityAttr(S.Context, AL, Args.data(),
6797 Args.size()));
6798}
6799
6800static void handleTryAcquireCapabilityAttr(Sema &S, Decl *D,
6801 const ParsedAttr &AL) {
6802 if (!checkThreadSafetyAttrSubject(S, D, AL))
6803 return;
6804
6805 SmallVector<Expr*, 2> Args;
6806 if (!checkTryLockFunAttrCommon(S, D, AL, Args))
6807 return;
6808
6809 D->addAttr(A: ::new (S.Context) TryAcquireCapabilityAttr(
6810 S.Context, AL, AL.getArgAsExpr(Arg: 0), Args.data(), Args.size()));
6811}
6812
6813static void handleReleaseCapabilityAttr(Sema &S, Decl *D,
6814 const ParsedAttr &AL) {
6815 if (!checkThreadSafetyAttrSubject(S, D, AL, /*CheckParmVar=*/true))
6816 return;
6817
6818 // Check that all arguments are lockable objects.
6819 SmallVector<Expr *, 1> Args;
6820 checkAttrArgsAreCapabilityObjs(S, D, AL, Args, Sidx: 0, ParamIdxOk: true);
6821
6822 D->addAttr(A: ::new (S.Context) ReleaseCapabilityAttr(S.Context, AL, Args.data(),
6823 Args.size()));
6824}
6825
6826static void handleRequiresCapabilityAttr(Sema &S, Decl *D,
6827 const ParsedAttr &AL) {
6828 if (!checkThreadSafetyAttrSubject(S, D, AL, /*CheckParmVar=*/true))
6829 return;
6830
6831 if (!AL.checkAtLeastNumArgs(S, Num: 1))
6832 return;
6833
6834 // check that all arguments are lockable objects
6835 SmallVector<Expr*, 1> Args;
6836 checkAttrArgsAreCapabilityObjs(S, D, AL, Args);
6837 if (Args.empty())
6838 return;
6839
6840 RequiresCapabilityAttr *RCA = ::new (S.Context)
6841 RequiresCapabilityAttr(S.Context, AL, Args.data(), Args.size());
6842
6843 D->addAttr(A: RCA);
6844}
6845
6846static void handleDeprecatedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6847 if (const auto *NSD = dyn_cast<NamespaceDecl>(Val: D)) {
6848 if (NSD->isAnonymousNamespace()) {
6849 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_deprecated_anonymous_namespace);
6850 // Do not want to attach the attribute to the namespace because that will
6851 // cause confusing diagnostic reports for uses of declarations within the
6852 // namespace.
6853 return;
6854 }
6855 } else if (isa<UsingDecl, UnresolvedUsingTypenameDecl,
6856 UnresolvedUsingValueDecl>(Val: D)) {
6857 S.Diag(Loc: AL.getRange().getBegin(), DiagID: diag::warn_deprecated_ignored_on_using)
6858 << AL;
6859 return;
6860 }
6861
6862 // Handle the cases where the attribute has a text message.
6863 StringRef Str, Replacement;
6864 if (AL.isArgExpr(Arg: 0) && AL.getArgAsExpr(Arg: 0) &&
6865 !S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str))
6866 return;
6867
6868 // Support a single optional message only for Declspec and [[]] spellings.
6869 if (AL.isDeclspecAttribute() || AL.isStandardAttributeSyntax())
6870 AL.checkAtMostNumArgs(S, Num: 1);
6871 else if (AL.isArgExpr(Arg: 1) && AL.getArgAsExpr(Arg: 1) &&
6872 !S.checkStringLiteralArgumentAttr(AL, ArgNum: 1, Str&: Replacement))
6873 return;
6874
6875 if (!S.getLangOpts().CPlusPlus14 && AL.isCXX11Attribute() && !AL.isGNUScope())
6876 S.Diag(Loc: AL.getLoc(), DiagID: diag::ext_cxx14_attr) << AL;
6877
6878 D->addAttr(A: ::new (S.Context) DeprecatedAttr(S.Context, AL, Str, Replacement));
6879}
6880
6881static bool isGlobalVar(const Decl *D) {
6882 if (const auto *S = dyn_cast<VarDecl>(Val: D))
6883 return S->hasGlobalStorage();
6884 return false;
6885}
6886
6887static bool isSanitizerAttributeAllowedOnGlobals(StringRef Sanitizer) {
6888 return Sanitizer == "address" || Sanitizer == "hwaddress" ||
6889 Sanitizer == "memtag";
6890}
6891
6892static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6893 if (!AL.checkAtLeastNumArgs(S, Num: 1))
6894 return;
6895
6896 std::vector<StringRef> Sanitizers;
6897
6898 for (unsigned I = 0, E = AL.getNumArgs(); I != E; ++I) {
6899 StringRef SanitizerName;
6900 SourceLocation LiteralLoc;
6901
6902 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: SanitizerName, ArgLocation: &LiteralLoc))
6903 return;
6904
6905 if (parseSanitizerValue(Value: SanitizerName, /*AllowGroups=*/true) ==
6906 SanitizerMask() &&
6907 SanitizerName != "coverage")
6908 S.Diag(Loc: LiteralLoc, DiagID: diag::warn_unknown_sanitizer_ignored) << SanitizerName;
6909 else if (isGlobalVar(D) && !isSanitizerAttributeAllowedOnGlobals(Sanitizer: SanitizerName))
6910 S.Diag(Loc: D->getLocation(), DiagID: diag::warn_attribute_type_not_supported_global)
6911 << AL << SanitizerName;
6912 Sanitizers.push_back(x: SanitizerName);
6913 }
6914
6915 D->addAttr(A: ::new (S.Context) NoSanitizeAttr(S.Context, AL, Sanitizers.data(),
6916 Sanitizers.size()));
6917}
6918
6919static AttributeCommonInfo
6920getNoSanitizeAttrInfo(const ParsedAttr &NoSanitizeSpecificAttr) {
6921 // FIXME: Rather than create a NoSanitizeSpecificAttr, this creates a
6922 // NoSanitizeAttr object; but we need to calculate the correct spelling list
6923 // index rather than incorrectly assume the index for NoSanitizeSpecificAttr
6924 // has the same spellings as the index for NoSanitizeAttr. We don't have a
6925 // general way to "translate" between the two, so this hack attempts to work
6926 // around the issue with hard-coded indices. This is critical for calling
6927 // getSpelling() or prettyPrint() on the resulting semantic attribute object
6928 // without failing assertions.
6929 unsigned TranslatedSpellingIndex = 0;
6930 if (NoSanitizeSpecificAttr.isStandardAttributeSyntax())
6931 TranslatedSpellingIndex = 1;
6932
6933 AttributeCommonInfo Info = NoSanitizeSpecificAttr;
6934 Info.setAttributeSpellingListIndex(TranslatedSpellingIndex);
6935 return Info;
6936}
6937
6938static void handleNoSanitizeAddressAttr(Sema &S, Decl *D,
6939 const ParsedAttr &AL) {
6940 StringRef SanitizerName = "address";
6941 AttributeCommonInfo Info = getNoSanitizeAttrInfo(NoSanitizeSpecificAttr: AL);
6942 D->addAttr(A: ::new (S.Context)
6943 NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
6944}
6945
6946static void handleNoSanitizeThreadAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6947 StringRef SanitizerName = "thread";
6948 AttributeCommonInfo Info = getNoSanitizeAttrInfo(NoSanitizeSpecificAttr: AL);
6949 D->addAttr(A: ::new (S.Context)
6950 NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
6951}
6952
6953static void handleNoSanitizeMemoryAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6954 StringRef SanitizerName = "memory";
6955 AttributeCommonInfo Info = getNoSanitizeAttrInfo(NoSanitizeSpecificAttr: AL);
6956 D->addAttr(A: ::new (S.Context)
6957 NoSanitizeAttr(S.Context, Info, &SanitizerName, 1));
6958}
6959
6960static void handleInternalLinkageAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6961 if (InternalLinkageAttr *Internal = S.mergeInternalLinkageAttr(D, AL))
6962 D->addAttr(A: Internal);
6963}
6964
6965static void handleZeroCallUsedRegsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
6966 // Check that the argument is a string literal.
6967 StringRef KindStr;
6968 SourceLocation LiteralLoc;
6969 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: KindStr, ArgLocation: &LiteralLoc))
6970 return;
6971
6972 ZeroCallUsedRegsAttr::ZeroCallUsedRegsKind Kind;
6973 if (!ZeroCallUsedRegsAttr::ConvertStrToZeroCallUsedRegsKind(Val: KindStr, Out&: Kind)) {
6974 S.Diag(Loc: LiteralLoc, DiagID: diag::warn_attribute_type_not_supported)
6975 << AL << KindStr;
6976 return;
6977 }
6978
6979 D->dropAttr<ZeroCallUsedRegsAttr>();
6980 D->addAttr(A: ZeroCallUsedRegsAttr::Create(Ctx&: S.Context, ZeroCallUsedRegs: Kind, CommonInfo: AL));
6981}
6982
6983static void handleNoPFPAttrField(Sema &S, Decl *D, const ParsedAttr &AL) {
6984 D->addAttr(A: NoFieldProtectionAttr::Create(Ctx&: S.Context, CommonInfo: AL));
6985}
6986
6987static void handleCountedByAttrField(Sema &S, Decl *D, const ParsedAttr &AL) {
6988 auto *CountExpr = AL.getArgAsExpr(Arg: 0);
6989 if (!CountExpr)
6990 return;
6991
6992 bool CountInBytes;
6993 bool OrNull;
6994 switch (AL.getKind()) {
6995 case ParsedAttr::AT_CountedBy:
6996 CountInBytes = false;
6997 OrNull = false;
6998 break;
6999 case ParsedAttr::AT_CountedByOrNull:
7000 CountInBytes = false;
7001 OrNull = true;
7002 break;
7003 case ParsedAttr::AT_SizedBy:
7004 CountInBytes = true;
7005 OrNull = false;
7006 break;
7007 case ParsedAttr::AT_SizedByOrNull:
7008 CountInBytes = true;
7009 OrNull = true;
7010 break;
7011 default:
7012 llvm_unreachable("unexpected counted_by family attribute");
7013 }
7014
7015 FieldDecl *FD = cast<FieldDecl>(Val: D);
7016 if (S.CheckCountedByAttrOnField(FD, E: CountExpr, CountInBytes, OrNull))
7017 return;
7018
7019 QualType CAT = S.BuildCountAttributedArrayOrPointerType(
7020 WrappedTy: FD->getType(), CountExpr, CountInBytes, OrNull);
7021 FD->setType(CAT);
7022}
7023
7024static void handleFunctionReturnThunksAttr(Sema &S, Decl *D,
7025 const ParsedAttr &AL) {
7026 StringRef KindStr;
7027 SourceLocation LiteralLoc;
7028 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: KindStr, ArgLocation: &LiteralLoc))
7029 return;
7030
7031 FunctionReturnThunksAttr::Kind Kind;
7032 if (!FunctionReturnThunksAttr::ConvertStrToKind(Val: KindStr, Out&: Kind)) {
7033 S.Diag(Loc: LiteralLoc, DiagID: diag::warn_attribute_type_not_supported)
7034 << AL << KindStr;
7035 return;
7036 }
7037 // FIXME: it would be good to better handle attribute merging rather than
7038 // silently replacing the existing attribute, so long as it does not break
7039 // the expected codegen tests.
7040 D->dropAttr<FunctionReturnThunksAttr>();
7041 D->addAttr(A: FunctionReturnThunksAttr::Create(Ctx&: S.Context, ThunkType: Kind, CommonInfo: AL));
7042}
7043
7044static void handleAvailableOnlyInDefaultEvalMethod(Sema &S, Decl *D,
7045 const ParsedAttr &AL) {
7046 assert(isa<TypedefNameDecl>(D) && "This attribute only applies to a typedef");
7047 handleSimpleAttribute<AvailableOnlyInDefaultEvalMethodAttr>(S, D, CI: AL);
7048}
7049
7050static void handleNoMergeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7051 auto *VDecl = dyn_cast<VarDecl>(Val: D);
7052 if (VDecl && !VDecl->isFunctionPointerType()) {
7053 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_ignored_non_function_pointer)
7054 << AL << VDecl;
7055 return;
7056 }
7057 D->addAttr(A: NoMergeAttr::Create(Ctx&: S.Context, CommonInfo: AL));
7058}
7059
7060static void handleNoUniqueAddressAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7061 D->addAttr(A: NoUniqueAddressAttr::Create(Ctx&: S.Context, CommonInfo: AL));
7062}
7063
7064static void handleDestroyAttr(Sema &S, Decl *D, const ParsedAttr &A) {
7065 if (!cast<VarDecl>(Val: D)->hasGlobalStorage()) {
7066 S.Diag(Loc: D->getLocation(), DiagID: diag::err_destroy_attr_on_non_static_var)
7067 << (A.getKind() == ParsedAttr::AT_AlwaysDestroy);
7068 return;
7069 }
7070
7071 if (A.getKind() == ParsedAttr::AT_AlwaysDestroy)
7072 handleSimpleAttribute<AlwaysDestroyAttr>(S, D, CI: A);
7073 else
7074 handleSimpleAttribute<NoDestroyAttr>(S, D, CI: A);
7075}
7076
7077static void handleUninitializedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7078 assert(cast<VarDecl>(D)->getStorageDuration() == SD_Automatic &&
7079 "uninitialized is only valid on automatic duration variables");
7080 D->addAttr(A: ::new (S.Context) UninitializedAttr(S.Context, AL));
7081}
7082
7083static void handleMIGServerRoutineAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7084 // Check that the return type is a `typedef int kern_return_t` or a typedef
7085 // around it, because otherwise MIG convention checks make no sense.
7086 // BlockDecl doesn't store a return type, so it's annoying to check,
7087 // so let's skip it for now.
7088 if (!isa<BlockDecl>(Val: D)) {
7089 QualType T = getFunctionOrMethodResultType(D);
7090 bool IsKernReturnT = false;
7091 while (const auto *TT = T->getAs<TypedefType>()) {
7092 IsKernReturnT = (TT->getDecl()->getName() == "kern_return_t");
7093 T = TT->desugar();
7094 }
7095 if (!IsKernReturnT || T.getCanonicalType() != S.getASTContext().IntTy) {
7096 S.Diag(Loc: D->getBeginLoc(),
7097 DiagID: diag::warn_mig_server_routine_does_not_return_kern_return_t);
7098 return;
7099 }
7100 }
7101
7102 handleSimpleAttribute<MIGServerRoutineAttr>(S, D, CI: AL);
7103}
7104
7105static void handleMSAllocatorAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7106 // Warn if the return type is not a pointer or reference type.
7107 if (auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
7108 QualType RetTy = FD->getReturnType();
7109 if (!RetTy->isPointerOrReferenceType()) {
7110 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_declspec_allocator_nonpointer)
7111 << AL.getRange() << RetTy;
7112 return;
7113 }
7114 }
7115
7116 handleSimpleAttribute<MSAllocatorAttr>(S, D, CI: AL);
7117}
7118
7119static void handleAcquireHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7120 if (AL.isUsedAsTypeAttr())
7121 return;
7122 // Warn if the parameter is definitely not an output parameter.
7123 if (const auto *PVD = dyn_cast<ParmVarDecl>(Val: D)) {
7124 if (PVD->getType()->isIntegerType()) {
7125 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_output_parameter)
7126 << AL.getRange();
7127 return;
7128 }
7129 }
7130 StringRef Argument;
7131 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: Argument))
7132 return;
7133 D->addAttr(A: AcquireHandleAttr::Create(Ctx&: S.Context, HandleType: Argument, CommonInfo: AL));
7134}
7135
7136template<typename Attr>
7137static void handleHandleAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7138 StringRef Argument;
7139 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: Argument))
7140 return;
7141 D->addAttr(A: Attr::Create(S.Context, Argument, AL));
7142}
7143
7144template<typename Attr>
7145static void handleUnsafeBufferUsage(Sema &S, Decl *D, const ParsedAttr &AL) {
7146 D->addAttr(A: Attr::Create(S.Context, AL));
7147}
7148
7149static void handleCFGuardAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7150 // The guard attribute takes a single identifier argument.
7151
7152 if (!AL.isArgIdent(Arg: 0)) {
7153 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
7154 << AL << AANT_ArgumentIdentifier;
7155 return;
7156 }
7157
7158 CFGuardAttr::GuardArg Arg;
7159 IdentifierInfo *II = AL.getArgAsIdent(Arg: 0)->getIdentifierInfo();
7160 if (!CFGuardAttr::ConvertStrToGuardArg(Val: II->getName(), Out&: Arg)) {
7161 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_type_not_supported) << AL << II;
7162 return;
7163 }
7164
7165 D->addAttr(A: ::new (S.Context) CFGuardAttr(S.Context, AL, Arg));
7166}
7167
7168
7169template <typename AttrTy>
7170static const AttrTy *findEnforceTCBAttrByName(Decl *D, StringRef Name) {
7171 auto Attrs = D->specific_attrs<AttrTy>();
7172 auto I = llvm::find_if(Attrs,
7173 [Name](const AttrTy *A) {
7174 return A->getTCBName() == Name;
7175 });
7176 return I == Attrs.end() ? nullptr : *I;
7177}
7178
7179template <typename AttrTy, typename ConflictingAttrTy>
7180static void handleEnforceTCBAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7181 StringRef Argument;
7182 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 0, Str&: Argument))
7183 return;
7184
7185 // A function cannot be have both regular and leaf membership in the same TCB.
7186 if (const ConflictingAttrTy *ConflictingAttr =
7187 findEnforceTCBAttrByName<ConflictingAttrTy>(D, Argument)) {
7188 // We could attach a note to the other attribute but in this case
7189 // there's no need given how the two are very close to each other.
7190 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_tcb_conflicting_attributes)
7191 << AL.getAttrName()->getName() << ConflictingAttr->getAttrName()->getName()
7192 << Argument;
7193
7194 // Error recovery: drop the non-leaf attribute so that to suppress
7195 // all future warnings caused by erroneous attributes. The leaf attribute
7196 // needs to be kept because it can only suppresses warnings, not cause them.
7197 D->dropAttr<EnforceTCBAttr>();
7198 return;
7199 }
7200
7201 D->addAttr(A: AttrTy::Create(S.Context, Argument, AL));
7202}
7203
7204template <typename AttrTy, typename ConflictingAttrTy>
7205static AttrTy *mergeEnforceTCBAttrImpl(Sema &S, Decl *D, const AttrTy &AL) {
7206 // Check if the new redeclaration has different leaf-ness in the same TCB.
7207 StringRef TCBName = AL.getTCBName();
7208 if (const ConflictingAttrTy *ConflictingAttr =
7209 findEnforceTCBAttrByName<ConflictingAttrTy>(D, TCBName)) {
7210 S.Diag(ConflictingAttr->getLoc(), diag::err_tcb_conflicting_attributes)
7211 << ConflictingAttr->getAttrName()->getName()
7212 << AL.getAttrName()->getName() << TCBName;
7213
7214 // Add a note so that the user could easily find the conflicting attribute.
7215 S.Diag(AL.getLoc(), diag::note_conflicting_attribute);
7216
7217 // More error recovery.
7218 D->dropAttr<EnforceTCBAttr>();
7219 return nullptr;
7220 }
7221
7222 ASTContext &Context = S.getASTContext();
7223 return ::new(Context) AttrTy(Context, AL, AL.getTCBName());
7224}
7225
7226EnforceTCBAttr *Sema::mergeEnforceTCBAttr(Decl *D, const EnforceTCBAttr &AL) {
7227 return mergeEnforceTCBAttrImpl<EnforceTCBAttr, EnforceTCBLeafAttr>(
7228 S&: *this, D, AL);
7229}
7230
7231EnforceTCBLeafAttr *Sema::mergeEnforceTCBLeafAttr(
7232 Decl *D, const EnforceTCBLeafAttr &AL) {
7233 return mergeEnforceTCBAttrImpl<EnforceTCBLeafAttr, EnforceTCBAttr>(
7234 S&: *this, D, AL);
7235}
7236
7237static void handleVTablePointerAuthentication(Sema &S, Decl *D,
7238 const ParsedAttr &AL) {
7239 CXXRecordDecl *Decl = cast<CXXRecordDecl>(Val: D);
7240 const uint32_t NumArgs = AL.getNumArgs();
7241 if (NumArgs > 4) {
7242 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_too_many_arguments) << AL << 4;
7243 AL.setInvalid();
7244 }
7245
7246 if (NumArgs == 0) {
7247 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_too_few_arguments) << AL;
7248 AL.setInvalid();
7249 return;
7250 }
7251
7252 if (D->getAttr<VTablePointerAuthenticationAttr>()) {
7253 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_duplicated_vtable_pointer_auth) << Decl;
7254 AL.setInvalid();
7255 }
7256
7257 auto KeyType = VTablePointerAuthenticationAttr::VPtrAuthKeyType::DefaultKey;
7258 if (AL.isArgIdent(Arg: 0)) {
7259 IdentifierLoc *IL = AL.getArgAsIdent(Arg: 0);
7260 if (!VTablePointerAuthenticationAttr::ConvertStrToVPtrAuthKeyType(
7261 Val: IL->getIdentifierInfo()->getName(), Out&: KeyType)) {
7262 S.Diag(Loc: IL->getLoc(), DiagID: diag::err_invalid_authentication_key)
7263 << IL->getIdentifierInfo();
7264 AL.setInvalid();
7265 }
7266 if (KeyType == VTablePointerAuthenticationAttr::DefaultKey &&
7267 !S.getLangOpts().PointerAuthCalls) {
7268 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_no_default_vtable_pointer_auth) << 0;
7269 AL.setInvalid();
7270 }
7271 } else {
7272 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
7273 << AL << AANT_ArgumentIdentifier;
7274 return;
7275 }
7276
7277 auto AddressDiversityMode = VTablePointerAuthenticationAttr::
7278 AddressDiscriminationMode::DefaultAddressDiscrimination;
7279 if (AL.getNumArgs() > 1) {
7280 if (AL.isArgIdent(Arg: 1)) {
7281 IdentifierLoc *IL = AL.getArgAsIdent(Arg: 1);
7282 if (!VTablePointerAuthenticationAttr::
7283 ConvertStrToAddressDiscriminationMode(
7284 Val: IL->getIdentifierInfo()->getName(), Out&: AddressDiversityMode)) {
7285 S.Diag(Loc: IL->getLoc(), DiagID: diag::err_invalid_address_discrimination)
7286 << IL->getIdentifierInfo();
7287 AL.setInvalid();
7288 }
7289 if (AddressDiversityMode ==
7290 VTablePointerAuthenticationAttr::DefaultAddressDiscrimination &&
7291 !S.getLangOpts().PointerAuthCalls) {
7292 S.Diag(Loc: IL->getLoc(), DiagID: diag::err_no_default_vtable_pointer_auth) << 1;
7293 AL.setInvalid();
7294 }
7295 } else {
7296 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
7297 << AL << AANT_ArgumentIdentifier;
7298 }
7299 }
7300
7301 auto ED = VTablePointerAuthenticationAttr::ExtraDiscrimination::
7302 DefaultExtraDiscrimination;
7303 if (AL.getNumArgs() > 2) {
7304 if (AL.isArgIdent(Arg: 2)) {
7305 IdentifierLoc *IL = AL.getArgAsIdent(Arg: 2);
7306 if (!VTablePointerAuthenticationAttr::ConvertStrToExtraDiscrimination(
7307 Val: IL->getIdentifierInfo()->getName(), Out&: ED)) {
7308 S.Diag(Loc: IL->getLoc(), DiagID: diag::err_invalid_extra_discrimination)
7309 << IL->getIdentifierInfo();
7310 AL.setInvalid();
7311 }
7312 if (ED == VTablePointerAuthenticationAttr::DefaultExtraDiscrimination &&
7313 !S.getLangOpts().PointerAuthCalls) {
7314 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_no_default_vtable_pointer_auth) << 2;
7315 AL.setInvalid();
7316 }
7317 } else {
7318 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_type)
7319 << AL << AANT_ArgumentIdentifier;
7320 }
7321 }
7322
7323 uint32_t CustomDiscriminationValue = 0;
7324 if (ED == VTablePointerAuthenticationAttr::CustomDiscrimination) {
7325 if (NumArgs < 4) {
7326 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_missing_custom_discrimination) << AL << 4;
7327 AL.setInvalid();
7328 return;
7329 }
7330 if (NumArgs > 4) {
7331 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_too_many_arguments) << AL << 4;
7332 AL.setInvalid();
7333 }
7334
7335 if (!AL.isArgExpr(Arg: 3) || !S.checkUInt32Argument(AI: AL, Expr: AL.getArgAsExpr(Arg: 3),
7336 Val&: CustomDiscriminationValue)) {
7337 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_invalid_custom_discrimination);
7338 AL.setInvalid();
7339 }
7340 } else if (NumArgs > 3) {
7341 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_too_many_arguments) << AL << 3;
7342 AL.setInvalid();
7343 }
7344
7345 Decl->addAttr(A: ::new (S.Context) VTablePointerAuthenticationAttr(
7346 S.Context, AL, KeyType, AddressDiversityMode, ED,
7347 CustomDiscriminationValue));
7348}
7349
7350static bool modularFormatAttrsEquiv(const ModularFormatAttr *Existing,
7351 const IdentifierInfo *ModularImplFn,
7352 StringRef ImplName,
7353 ArrayRef<StringRef> Aspects) {
7354 return Existing->getModularImplFn() == ModularImplFn &&
7355 Existing->getImplName() == ImplName &&
7356 Existing->aspects_size() == Aspects.size() &&
7357 llvm::equal(LRange: Existing->aspects(), RRange&: Aspects);
7358}
7359
7360ModularFormatAttr *Sema::mergeModularFormatAttr(
7361 Decl *D, const AttributeCommonInfo &CI, const IdentifierInfo *ModularImplFn,
7362 StringRef ImplName, MutableArrayRef<StringRef> Aspects) {
7363 if (const auto *Existing = D->getAttr<ModularFormatAttr>()) {
7364 if (!modularFormatAttrsEquiv(Existing, ModularImplFn, ImplName, Aspects)) {
7365 Diag(Loc: Existing->getLocation(), DiagID: diag::err_duplicate_attribute) << *Existing;
7366 Diag(Loc: CI.getLoc(), DiagID: diag::note_conflicting_attribute);
7367 }
7368 return nullptr;
7369 }
7370 return ::new (Context) ModularFormatAttr(Context, CI, ModularImplFn, ImplName,
7371 Aspects.data(), Aspects.size());
7372}
7373
7374static void handleModularFormat(Sema &S, Decl *D, const ParsedAttr &AL) {
7375 bool Valid = true;
7376 if (!AL.isArgIdent(Arg: 0)) {
7377 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_argument_n_type)
7378 << AL << 1 << AANT_ArgumentIdentifier;
7379 Valid = false;
7380 }
7381 StringRef ImplName;
7382 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: 1, Str&: ImplName))
7383 Valid = false;
7384 SmallVector<StringRef> Aspects;
7385 llvm::DenseSet<StringRef> SeenAspects;
7386 for (unsigned I = 2, E = AL.getNumArgs(); I != E; ++I) {
7387 StringRef Aspect;
7388 if (!S.checkStringLiteralArgumentAttr(AL, ArgNum: I, Str&: Aspect))
7389 return;
7390 if (!SeenAspects.insert(V: Aspect).second) {
7391 S.Diag(Loc: AL.getArgAsExpr(Arg: I)->getExprLoc(),
7392 DiagID: diag::err_modular_format_duplicate_aspect)
7393 << Aspect;
7394 Valid = false;
7395 continue;
7396 }
7397 Aspects.push_back(Elt: Aspect);
7398 }
7399 if (!Valid)
7400 return;
7401
7402 // Store aspects sorted.
7403 llvm::sort(C&: Aspects);
7404 IdentifierInfo *ModularImplFn = AL.getArgAsIdent(Arg: 0)->getIdentifierInfo();
7405
7406 if (const auto *Existing = D->getAttr<ModularFormatAttr>()) {
7407 if (!modularFormatAttrsEquiv(Existing, ModularImplFn, ImplName, Aspects)) {
7408 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_duplicate_attribute) << *Existing;
7409 S.Diag(Loc: Existing->getLoc(), DiagID: diag::note_conflicting_attribute);
7410 }
7411 // Ignore the later declaration in favor of the earlier one.
7412 return;
7413 }
7414
7415 D->addAttr(A: ::new (S.Context) ModularFormatAttr(
7416 S.Context, AL, ModularImplFn, ImplName, Aspects.data(), Aspects.size()));
7417}
7418
7419//===----------------------------------------------------------------------===//
7420// Top Level Sema Entry Points
7421//===----------------------------------------------------------------------===//
7422
7423// Returns true if the attribute must delay setting its arguments until after
7424// template instantiation, and false otherwise.
7425static bool MustDelayAttributeArguments(const ParsedAttr &AL) {
7426 // Only attributes that accept expression parameter packs can delay arguments.
7427 if (!AL.acceptsExprPack())
7428 return false;
7429
7430 bool AttrHasVariadicArg = AL.hasVariadicArg();
7431 unsigned AttrNumArgs = AL.getNumArgMembers();
7432 for (size_t I = 0; I < std::min(a: AL.getNumArgs(), b: AttrNumArgs); ++I) {
7433 bool IsLastAttrArg = I == (AttrNumArgs - 1);
7434 // If the argument is the last argument and it is variadic it can contain
7435 // any expression.
7436 if (IsLastAttrArg && AttrHasVariadicArg)
7437 return false;
7438 Expr *E = AL.getArgAsExpr(Arg: I);
7439 bool ArgMemberCanHoldExpr = AL.isParamExpr(N: I);
7440 // If the expression is a pack expansion then arguments must be delayed
7441 // unless the argument is an expression and it is the last argument of the
7442 // attribute.
7443 if (isa<PackExpansionExpr>(Val: E))
7444 return !(IsLastAttrArg && ArgMemberCanHoldExpr);
7445 // Last case is if the expression is value dependent then it must delay
7446 // arguments unless the corresponding argument is able to hold the
7447 // expression.
7448 if (E->isValueDependent() && !ArgMemberCanHoldExpr)
7449 return true;
7450 }
7451 return false;
7452}
7453
7454PersonalityAttr *Sema::mergePersonalityAttr(Decl *D, FunctionDecl *Routine,
7455 const AttributeCommonInfo &CI) {
7456 if (PersonalityAttr *PA = D->getAttr<PersonalityAttr>()) {
7457 const FunctionDecl *Personality = PA->getRoutine();
7458 if (Context.isSameEntity(X: Personality, Y: Routine))
7459 return nullptr;
7460 Diag(Loc: PA->getLocation(), DiagID: diag::err_mismatched_personality);
7461 Diag(Loc: CI.getLoc(), DiagID: diag::note_previous_attribute);
7462 D->dropAttr<PersonalityAttr>();
7463 }
7464 return ::new (Context) PersonalityAttr(Context, CI, Routine);
7465}
7466
7467static void handlePersonalityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
7468 Expr *E = AL.getArgAsExpr(Arg: 0);
7469 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Val: E))
7470 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Val: DRE->getDecl()))
7471 if (Attr *A = S.mergePersonalityAttr(D, Routine: FD, CI: AL))
7472 return D->addAttr(A);
7473 S.Diag(Loc: E->getExprLoc(), DiagID: diag::err_attribute_personality_arg_not_function)
7474 << AL.getAttrName();
7475}
7476
7477/// ProcessDeclAttribute - Apply the specific attribute to the specified decl if
7478/// the attribute applies to decls. If the attribute is a type attribute, just
7479/// silently ignore it if a GNU attribute.
7480static void
7481ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
7482 const Sema::ProcessDeclAttributeOptions &Options) {
7483 if (AL.isInvalid() || AL.getKind() == ParsedAttr::IgnoredAttribute)
7484 return;
7485
7486 // Ignore C++11 attributes on declarator chunks: they appertain to the type
7487 // instead. Note, isCXX11Attribute() will look at whether the attribute is
7488 // [[]] or alignas, while isC23Attribute() will only look at [[]]. This is
7489 // important for ensuring that alignas in C23 is properly handled on a
7490 // structure member declaration because it is a type-specifier-qualifier in
7491 // C but still applies to the declaration rather than the type.
7492 if ((S.getLangOpts().CPlusPlus ? AL.isCXX11Attribute()
7493 : AL.isC23Attribute()) &&
7494 !Options.IncludeCXX11Attributes)
7495 return;
7496
7497 // Unknown attributes are automatically warned on. Target-specific attributes
7498 // which do not apply to the current target architecture are treated as
7499 // though they were unknown attributes.
7500 if (AL.getKind() == ParsedAttr::UnknownAttribute ||
7501 !AL.existsInTarget(Target: S.Context.getTargetInfo())) {
7502 if (AL.isRegularKeywordAttribute()) {
7503 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_keyword_not_supported_on_target)
7504 << AL.getAttrName() << AL.getRange();
7505 } else if (AL.isDeclspecAttribute()) {
7506 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_unhandled_ms_attribute_ignored)
7507 << AL.getAttrName() << AL.getRange();
7508 } else {
7509 S.DiagnoseUnknownAttribute(AL);
7510 }
7511 return;
7512 }
7513
7514 if (S.getLangOpts().HLSL && isa<FunctionDecl>(Val: D) &&
7515 AL.getKind() == ParsedAttr::AT_NoInline) {
7516 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
7517 for (const ParmVarDecl *PVD : FD->parameters()) {
7518 if (PVD->hasAttr<HLSLGroupSharedAddressSpaceAttr>()) {
7519 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_hlsl_attr_incompatible)
7520 << "'noinline'" << "'groupshared' parameter";
7521 return;
7522 }
7523 }
7524 }
7525 }
7526
7527 // Check if argument population must delayed to after template instantiation.
7528 bool MustDelayArgs = MustDelayAttributeArguments(AL);
7529
7530 // Argument number check must be skipped if arguments are delayed.
7531 if (S.checkCommonAttributeFeatures(D, A: AL, SkipArgCountCheck: MustDelayArgs))
7532 return;
7533
7534 if (MustDelayArgs) {
7535 AL.handleAttrWithDelayedArgs(S, D);
7536 return;
7537 }
7538
7539 switch (AL.getKind()) {
7540 default:
7541 if (AL.getInfo().handleDeclAttribute(S, D, Attr: AL) != ParsedAttrInfo::NotHandled)
7542 break;
7543 if (!AL.isStmtAttr()) {
7544 assert(AL.isTypeAttr() && "Non-type attribute not handled");
7545 }
7546 if (AL.isTypeAttr()) {
7547 if (Options.IgnoreTypeAttributes)
7548 break;
7549 if (!AL.isStandardAttributeSyntax() && !AL.isRegularKeywordAttribute()) {
7550 // Non-[[]] type attributes are handled in processTypeAttrs(); silently
7551 // move on.
7552 break;
7553 }
7554
7555 // According to the C and C++ standards, we should never see a
7556 // [[]] type attribute on a declaration. However, we have in the past
7557 // allowed some type attributes to "slide" to the `DeclSpec`, so we need
7558 // to continue to support this legacy behavior. We only do this, however,
7559 // if
7560 // - we actually have a `DeclSpec`, i.e. if we're looking at a
7561 // `DeclaratorDecl`, or
7562 // - we are looking at an alias-declaration, where historically we have
7563 // allowed type attributes after the identifier to slide to the type.
7564 if (AL.slidesFromDeclToDeclSpecLegacyBehavior() &&
7565 isa<DeclaratorDecl, TypeAliasDecl>(Val: D)) {
7566 // Suggest moving the attribute to the type instead, but only for our
7567 // own vendor attributes; moving other vendors' attributes might hurt
7568 // portability.
7569 if (AL.isClangScope()) {
7570 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_type_attribute_deprecated_on_decl)
7571 << AL << D->getLocation();
7572 }
7573
7574 // Allow this type attribute to be handled in processTypeAttrs();
7575 // silently move on.
7576 break;
7577 }
7578
7579 if (AL.getKind() == ParsedAttr::AT_Regparm) {
7580 // `regparm` is a special case: It's a type attribute but we still want
7581 // to treat it as if it had been written on the declaration because that
7582 // way we'll be able to handle it directly in `processTypeAttr()`.
7583 // If we treated `regparm` it as if it had been written on the
7584 // `DeclSpec`, the logic in `distributeFunctionTypeAttrFromDeclSepc()`
7585 // would try to move it to the declarator, but that doesn't work: We
7586 // can't remove the attribute from the list of declaration attributes
7587 // because it might be needed by other declarators in the same
7588 // declaration.
7589 break;
7590 }
7591
7592 if (AL.getKind() == ParsedAttr::AT_VectorSize) {
7593 // `vector_size` is a special case: It's a type attribute semantically,
7594 // but GCC expects the [[]] syntax to be written on the declaration (and
7595 // warns that the attribute has no effect if it is placed on the
7596 // decl-specifier-seq).
7597 // Silently move on and allow the attribute to be handled in
7598 // processTypeAttr().
7599 break;
7600 }
7601
7602 if (AL.getKind() == ParsedAttr::AT_NoDeref) {
7603 // FIXME: `noderef` currently doesn't work correctly in [[]] syntax.
7604 // See https://github.com/llvm/llvm-project/issues/55790 for details.
7605 // We allow processTypeAttrs() to emit a warning and silently move on.
7606 break;
7607 }
7608 }
7609 // N.B., ClangAttrEmitter.cpp emits a diagnostic helper that ensures a
7610 // statement attribute is not written on a declaration, but this code is
7611 // needed for type attributes as well as statement attributes in Attr.td
7612 // that do not list any subjects.
7613 S.Diag(Loc: AL.getLoc(), DiagID: diag::err_attribute_invalid_on_decl)
7614 << AL << AL.isRegularKeywordAttribute() << D->getLocation();
7615 break;
7616 case ParsedAttr::AT_Interrupt:
7617 handleInterruptAttr(S, D, AL);
7618 break;
7619 case ParsedAttr::AT_ARMInterruptSaveFP:
7620 S.ARM().handleInterruptSaveFPAttr(D, AL);
7621 break;
7622 case ParsedAttr::AT_X86ForceAlignArgPointer:
7623 S.X86().handleForceAlignArgPointerAttr(D, AL);
7624 break;
7625 case ParsedAttr::AT_ReadOnlyPlacement:
7626 handleSimpleAttribute<ReadOnlyPlacementAttr>(S, D, CI: AL);
7627 break;
7628 case ParsedAttr::AT_DLLExport:
7629 case ParsedAttr::AT_DLLImport:
7630 handleDLLAttr(S, D, A: AL);
7631 break;
7632 case ParsedAttr::AT_AMDGPUFlatWorkGroupSize:
7633 S.AMDGPU().handleAMDGPUFlatWorkGroupSizeAttr(D, AL);
7634 break;
7635 case ParsedAttr::AT_AMDGPUWavesPerEU:
7636 S.AMDGPU().handleAMDGPUWavesPerEUAttr(D, AL);
7637 break;
7638 case ParsedAttr::AT_AMDGPUNumSGPR:
7639 S.AMDGPU().handleAMDGPUNumSGPRAttr(D, AL);
7640 break;
7641 case ParsedAttr::AT_AMDGPUNumVGPR:
7642 S.AMDGPU().handleAMDGPUNumVGPRAttr(D, AL);
7643 break;
7644 case ParsedAttr::AT_AMDGPUMaxNumWorkGroups:
7645 S.AMDGPU().handleAMDGPUMaxNumWorkGroupsAttr(D, AL);
7646 break;
7647 case ParsedAttr::AT_AVRSignal:
7648 S.AVR().handleSignalAttr(D, AL);
7649 break;
7650 case ParsedAttr::AT_BPFPreserveAccessIndex:
7651 S.BPF().handlePreserveAccessIndexAttr(D, AL);
7652 break;
7653 case ParsedAttr::AT_BPFPreserveStaticOffset:
7654 handleSimpleAttribute<BPFPreserveStaticOffsetAttr>(S, D, CI: AL);
7655 break;
7656 case ParsedAttr::AT_BTFDeclTag:
7657 handleBTFDeclTagAttr(S, D, AL);
7658 break;
7659 case ParsedAttr::AT_WebAssemblyExportName:
7660 S.Wasm().handleWebAssemblyExportNameAttr(D, AL);
7661 break;
7662 case ParsedAttr::AT_WebAssemblyImportModule:
7663 S.Wasm().handleWebAssemblyImportModuleAttr(D, AL);
7664 break;
7665 case ParsedAttr::AT_WebAssemblyImportName:
7666 S.Wasm().handleWebAssemblyImportNameAttr(D, AL);
7667 break;
7668 case ParsedAttr::AT_IBOutlet:
7669 S.ObjC().handleIBOutlet(D, AL);
7670 break;
7671 case ParsedAttr::AT_IBOutletCollection:
7672 S.ObjC().handleIBOutletCollection(D, AL);
7673 break;
7674 case ParsedAttr::AT_IFunc:
7675 handleIFuncAttr(S, D, AL);
7676 break;
7677 case ParsedAttr::AT_Alias:
7678 handleAliasAttr(S, D, AL);
7679 break;
7680 case ParsedAttr::AT_Aligned:
7681 handleAlignedAttr(S, D, AL);
7682 break;
7683 case ParsedAttr::AT_AlignValue:
7684 handleAlignValueAttr(S, D, AL);
7685 break;
7686 case ParsedAttr::AT_AllocSize:
7687 handleAllocSizeAttr(S, D, AL);
7688 break;
7689 case ParsedAttr::AT_AlwaysInline:
7690 handleAlwaysInlineAttr(S, D, AL);
7691 break;
7692 case ParsedAttr::AT_AnalyzerNoReturn:
7693 handleAnalyzerNoReturnAttr(S, D, AL);
7694 break;
7695 case ParsedAttr::AT_TLSModel:
7696 handleTLSModelAttr(S, D, AL);
7697 break;
7698 case ParsedAttr::AT_Annotate:
7699 handleAnnotateAttr(S, D, AL);
7700 break;
7701 case ParsedAttr::AT_Availability:
7702 handleAvailabilityAttr(S, D, AL);
7703 break;
7704 case ParsedAttr::AT_CarriesDependency:
7705 handleDependencyAttr(S, Scope: scope, D, AL);
7706 break;
7707 case ParsedAttr::AT_CPUDispatch:
7708 case ParsedAttr::AT_CPUSpecific:
7709 handleCPUSpecificAttr(S, D, AL);
7710 break;
7711 case ParsedAttr::AT_Common:
7712 handleCommonAttr(S, D, AL);
7713 break;
7714 case ParsedAttr::AT_CUDAConstant:
7715 handleConstantAttr(S, D, AL);
7716 break;
7717 case ParsedAttr::AT_PassObjectSize:
7718 handlePassObjectSizeAttr(S, D, AL);
7719 break;
7720 case ParsedAttr::AT_Constructor:
7721 handleConstructorAttr(S, D, AL);
7722 break;
7723 case ParsedAttr::AT_Deprecated:
7724 handleDeprecatedAttr(S, D, AL);
7725 break;
7726 case ParsedAttr::AT_Destructor:
7727 handleDestructorAttr(S, D, AL);
7728 break;
7729 case ParsedAttr::AT_EnableIf:
7730 handleEnableIfAttr(S, D, AL);
7731 break;
7732 case ParsedAttr::AT_Error:
7733 handleErrorAttr(S, D, AL);
7734 break;
7735 case ParsedAttr::AT_ExcludeFromExplicitInstantiation:
7736 handleExcludeFromExplicitInstantiationAttr(S, D, AL);
7737 break;
7738 case ParsedAttr::AT_DiagnoseIf:
7739 handleDiagnoseIfAttr(S, D, AL);
7740 break;
7741 case ParsedAttr::AT_DiagnoseAsBuiltin:
7742 handleDiagnoseAsBuiltinAttr(S, D, AL);
7743 break;
7744 case ParsedAttr::AT_NoBuiltin:
7745 handleNoBuiltinAttr(S, D, AL);
7746 break;
7747 case ParsedAttr::AT_CFIUncheckedCallee:
7748 handleCFIUncheckedCalleeAttr(S, D, Attrs: AL);
7749 break;
7750 case ParsedAttr::AT_ExtVectorType:
7751 handleExtVectorTypeAttr(S, D, AL);
7752 break;
7753 case ParsedAttr::AT_ExternalSourceSymbol:
7754 handleExternalSourceSymbolAttr(S, D, AL);
7755 break;
7756 case ParsedAttr::AT_MinSize:
7757 handleMinSizeAttr(S, D, AL);
7758 break;
7759 case ParsedAttr::AT_OptimizeNone:
7760 handleOptimizeNoneAttr(S, D, AL);
7761 break;
7762 case ParsedAttr::AT_EnumExtensibility:
7763 handleEnumExtensibilityAttr(S, D, AL);
7764 break;
7765 case ParsedAttr::AT_SYCLKernel:
7766 S.SYCL().handleKernelAttr(D, AL);
7767 break;
7768 case ParsedAttr::AT_SYCLExternal:
7769 handleSimpleAttribute<SYCLExternalAttr>(S, D, CI: AL);
7770 break;
7771 case ParsedAttr::AT_SYCLKernelEntryPoint:
7772 S.SYCL().handleKernelEntryPointAttr(D, AL);
7773 break;
7774 case ParsedAttr::AT_SYCLSpecialClass:
7775 handleSimpleAttribute<SYCLSpecialClassAttr>(S, D, CI: AL);
7776 break;
7777 case ParsedAttr::AT_Format:
7778 handleFormatAttr(S, D, AL);
7779 break;
7780 case ParsedAttr::AT_FormatMatches:
7781 handleFormatMatchesAttr(S, D, AL);
7782 break;
7783 case ParsedAttr::AT_FormatArg:
7784 handleFormatArgAttr(S, D, AL);
7785 break;
7786 case ParsedAttr::AT_Callback:
7787 handleCallbackAttr(S, D, AL);
7788 break;
7789 case ParsedAttr::AT_LifetimeCaptureBy:
7790 handleLifetimeCaptureByAttr(S, D, AL);
7791 break;
7792 case ParsedAttr::AT_CalledOnce:
7793 handleCalledOnceAttr(S, D, AL);
7794 break;
7795 case ParsedAttr::AT_CUDAGlobal:
7796 handleGlobalAttr(S, D, AL);
7797 break;
7798 case ParsedAttr::AT_CUDADevice:
7799 handleDeviceAttr(S, D, AL);
7800 break;
7801 case ParsedAttr::AT_CUDAGridConstant:
7802 handleGridConstantAttr(S, D, AL);
7803 break;
7804 case ParsedAttr::AT_HIPManaged:
7805 handleManagedAttr(S, D, AL);
7806 break;
7807 case ParsedAttr::AT_GNUInline:
7808 handleGNUInlineAttr(S, D, AL);
7809 break;
7810 case ParsedAttr::AT_CUDALaunchBounds:
7811 handleLaunchBoundsAttr(S, D, AL);
7812 break;
7813 case ParsedAttr::AT_CUDAClusterDims:
7814 handleClusterDimsAttr(S, D, AL);
7815 break;
7816 case ParsedAttr::AT_CUDANoCluster:
7817 handleNoClusterAttr(S, D, AL);
7818 break;
7819 case ParsedAttr::AT_Restrict:
7820 handleRestrictAttr(S, D, AL);
7821 break;
7822 case ParsedAttr::AT_MallocSpan:
7823 handleMallocSpanAttr(S, D, AL);
7824 break;
7825 case ParsedAttr::AT_Mode:
7826 handleModeAttr(S, D, AL);
7827 break;
7828 case ParsedAttr::AT_NonString:
7829 handleNonStringAttr(S, D, AL);
7830 break;
7831 case ParsedAttr::AT_NonNull:
7832 if (auto *PVD = dyn_cast<ParmVarDecl>(Val: D))
7833 handleNonNullAttrParameter(S, D: PVD, AL);
7834 else
7835 handleNonNullAttr(S, D, AL);
7836 break;
7837 case ParsedAttr::AT_ReturnsNonNull:
7838 handleReturnsNonNullAttr(S, D, AL);
7839 break;
7840 case ParsedAttr::AT_NoEscape:
7841 handleNoEscapeAttr(S, D, AL);
7842 break;
7843 case ParsedAttr::AT_MaybeUndef:
7844 handleSimpleAttribute<MaybeUndefAttr>(S, D, CI: AL);
7845 break;
7846 case ParsedAttr::AT_AssumeAligned:
7847 handleAssumeAlignedAttr(S, D, AL);
7848 break;
7849 case ParsedAttr::AT_AllocAlign:
7850 handleAllocAlignAttr(S, D, AL);
7851 break;
7852 case ParsedAttr::AT_Ownership:
7853 handleOwnershipAttr(S, D, AL);
7854 break;
7855 case ParsedAttr::AT_Naked:
7856 handleNakedAttr(S, D, AL);
7857 break;
7858 case ParsedAttr::AT_NoReturn:
7859 handleNoReturnAttr(S, D, Attrs: AL);
7860 break;
7861 case ParsedAttr::AT_CXX11NoReturn:
7862 handleStandardNoReturnAttr(S, D, A: AL);
7863 break;
7864 case ParsedAttr::AT_AnyX86NoCfCheck:
7865 handleNoCfCheckAttr(S, D, Attrs: AL);
7866 break;
7867 case ParsedAttr::AT_NoThrow:
7868 if (!AL.isUsedAsTypeAttr())
7869 handleSimpleAttribute<NoThrowAttr>(S, D, CI: AL);
7870 break;
7871 case ParsedAttr::AT_CUDAShared:
7872 handleSharedAttr(S, D, AL);
7873 break;
7874 case ParsedAttr::AT_VecReturn:
7875 handleVecReturnAttr(S, D, AL);
7876 break;
7877 case ParsedAttr::AT_ObjCOwnership:
7878 S.ObjC().handleOwnershipAttr(D, AL);
7879 break;
7880 case ParsedAttr::AT_ObjCPreciseLifetime:
7881 S.ObjC().handlePreciseLifetimeAttr(D, AL);
7882 break;
7883 case ParsedAttr::AT_ObjCReturnsInnerPointer:
7884 S.ObjC().handleReturnsInnerPointerAttr(D, Attrs: AL);
7885 break;
7886 case ParsedAttr::AT_ObjCRequiresSuper:
7887 S.ObjC().handleRequiresSuperAttr(D, Attrs: AL);
7888 break;
7889 case ParsedAttr::AT_ObjCBridge:
7890 S.ObjC().handleBridgeAttr(D, AL);
7891 break;
7892 case ParsedAttr::AT_ObjCBridgeMutable:
7893 S.ObjC().handleBridgeMutableAttr(D, AL);
7894 break;
7895 case ParsedAttr::AT_ObjCBridgeRelated:
7896 S.ObjC().handleBridgeRelatedAttr(D, AL);
7897 break;
7898 case ParsedAttr::AT_ObjCDesignatedInitializer:
7899 S.ObjC().handleDesignatedInitializer(D, AL);
7900 break;
7901 case ParsedAttr::AT_ObjCRuntimeName:
7902 S.ObjC().handleRuntimeName(D, AL);
7903 break;
7904 case ParsedAttr::AT_ObjCBoxable:
7905 S.ObjC().handleBoxable(D, AL);
7906 break;
7907 case ParsedAttr::AT_NSErrorDomain:
7908 S.ObjC().handleNSErrorDomain(D, Attr: AL);
7909 break;
7910 case ParsedAttr::AT_CFConsumed:
7911 case ParsedAttr::AT_NSConsumed:
7912 case ParsedAttr::AT_OSConsumed:
7913 S.ObjC().AddXConsumedAttr(D, CI: AL,
7914 K: S.ObjC().parsedAttrToRetainOwnershipKind(AL),
7915 /*IsTemplateInstantiation=*/false);
7916 break;
7917 case ParsedAttr::AT_OSReturnsRetainedOnZero:
7918 handleSimpleAttributeOrDiagnose<OSReturnsRetainedOnZeroAttr>(
7919 S, D, CI: AL, PassesCheck: S.ObjC().isValidOSObjectOutParameter(D),
7920 DiagID: diag::warn_ns_attribute_wrong_parameter_type,
7921 /*Extra Args=*/ExtraArgs: AL, /*pointer-to-OSObject-pointer*/ ExtraArgs: 3, ExtraArgs: AL.getRange());
7922 break;
7923 case ParsedAttr::AT_OSReturnsRetainedOnNonZero:
7924 handleSimpleAttributeOrDiagnose<OSReturnsRetainedOnNonZeroAttr>(
7925 S, D, CI: AL, PassesCheck: S.ObjC().isValidOSObjectOutParameter(D),
7926 DiagID: diag::warn_ns_attribute_wrong_parameter_type,
7927 /*Extra Args=*/ExtraArgs: AL, /*pointer-to-OSObject-poointer*/ ExtraArgs: 3, ExtraArgs: AL.getRange());
7928 break;
7929 case ParsedAttr::AT_NSReturnsAutoreleased:
7930 case ParsedAttr::AT_NSReturnsNotRetained:
7931 case ParsedAttr::AT_NSReturnsRetained:
7932 case ParsedAttr::AT_CFReturnsNotRetained:
7933 case ParsedAttr::AT_CFReturnsRetained:
7934 case ParsedAttr::AT_OSReturnsNotRetained:
7935 case ParsedAttr::AT_OSReturnsRetained:
7936 S.ObjC().handleXReturnsXRetainedAttr(D, AL);
7937 break;
7938 case ParsedAttr::AT_WorkGroupSizeHint:
7939 handleWorkGroupSize<WorkGroupSizeHintAttr>(S, D, AL);
7940 break;
7941 case ParsedAttr::AT_ReqdWorkGroupSize:
7942 handleWorkGroupSize<ReqdWorkGroupSizeAttr>(S, D, AL);
7943 break;
7944 case ParsedAttr::AT_OpenCLIntelReqdSubGroupSize:
7945 S.OpenCL().handleSubGroupSize(D, AL);
7946 break;
7947 case ParsedAttr::AT_VecTypeHint:
7948 handleVecTypeHint(S, D, AL);
7949 break;
7950 case ParsedAttr::AT_InitPriority:
7951 handleInitPriorityAttr(S, D, AL);
7952 break;
7953 case ParsedAttr::AT_Packed:
7954 handlePackedAttr(S, D, AL);
7955 break;
7956 case ParsedAttr::AT_PreferredName:
7957 handlePreferredName(S, D, AL);
7958 break;
7959 case ParsedAttr::AT_NoSpecializations:
7960 handleNoSpecializations(S, D, AL);
7961 break;
7962 case ParsedAttr::AT_Section:
7963 handleSectionAttr(S, D, AL);
7964 break;
7965 case ParsedAttr::AT_CodeModel:
7966 handleCodeModelAttr(S, D, AL);
7967 break;
7968 case ParsedAttr::AT_RandomizeLayout:
7969 handleRandomizeLayoutAttr(S, D, AL);
7970 break;
7971 case ParsedAttr::AT_NoRandomizeLayout:
7972 handleNoRandomizeLayoutAttr(S, D, AL);
7973 break;
7974 case ParsedAttr::AT_CodeSeg:
7975 handleCodeSegAttr(S, D, AL);
7976 break;
7977 case ParsedAttr::AT_Target:
7978 handleTargetAttr(S, D, AL);
7979 break;
7980 case ParsedAttr::AT_TargetVersion:
7981 handleTargetVersionAttr(S, D, AL);
7982 break;
7983 case ParsedAttr::AT_TargetClones:
7984 handleTargetClonesAttr(S, D, AL);
7985 break;
7986 case ParsedAttr::AT_MinVectorWidth:
7987 handleMinVectorWidthAttr(S, D, AL);
7988 break;
7989 case ParsedAttr::AT_Unavailable:
7990 handleAttrWithMessage<UnavailableAttr>(S, D, AL);
7991 break;
7992 case ParsedAttr::AT_OMPAssume:
7993 S.OpenMP().handleOMPAssumeAttr(D, AL);
7994 break;
7995 case ParsedAttr::AT_ObjCDirect:
7996 S.ObjC().handleDirectAttr(D, AL);
7997 break;
7998 case ParsedAttr::AT_ObjCDirectMembers:
7999 S.ObjC().handleDirectMembersAttr(D, AL);
8000 handleSimpleAttribute<ObjCDirectMembersAttr>(S, D, CI: AL);
8001 break;
8002 case ParsedAttr::AT_ObjCExplicitProtocolImpl:
8003 S.ObjC().handleSuppresProtocolAttr(D, AL);
8004 break;
8005 case ParsedAttr::AT_Unused:
8006 handleUnusedAttr(S, D, AL);
8007 break;
8008 case ParsedAttr::AT_Visibility:
8009 handleVisibilityAttr(S, D, AL, isTypeVisibility: false);
8010 break;
8011 case ParsedAttr::AT_TypeVisibility:
8012 handleVisibilityAttr(S, D, AL, isTypeVisibility: true);
8013 break;
8014 case ParsedAttr::AT_WarnUnusedResult:
8015 handleWarnUnusedResult(S, D, AL);
8016 break;
8017 case ParsedAttr::AT_WeakRef:
8018 handleWeakRefAttr(S, D, AL);
8019 break;
8020 case ParsedAttr::AT_WeakImport:
8021 handleWeakImportAttr(S, D, AL);
8022 break;
8023 case ParsedAttr::AT_TransparentUnion:
8024 handleTransparentUnionAttr(S, D, AL);
8025 break;
8026 case ParsedAttr::AT_ObjCMethodFamily:
8027 S.ObjC().handleMethodFamilyAttr(D, AL);
8028 break;
8029 case ParsedAttr::AT_ObjCNSObject:
8030 S.ObjC().handleNSObject(D, AL);
8031 break;
8032 case ParsedAttr::AT_ObjCIndependentClass:
8033 S.ObjC().handleIndependentClass(D, AL);
8034 break;
8035 case ParsedAttr::AT_Blocks:
8036 S.ObjC().handleBlocksAttr(D, AL);
8037 break;
8038 case ParsedAttr::AT_Sentinel:
8039 handleSentinelAttr(S, D, AL);
8040 break;
8041 case ParsedAttr::AT_Cleanup:
8042 handleCleanupAttr(S, D, AL);
8043 break;
8044 case ParsedAttr::AT_NoDebug:
8045 handleNoDebugAttr(S, D, AL);
8046 break;
8047 case ParsedAttr::AT_CmseNSEntry:
8048 S.ARM().handleCmseNSEntryAttr(D, AL);
8049 break;
8050 case ParsedAttr::AT_StdCall:
8051 case ParsedAttr::AT_CDecl:
8052 case ParsedAttr::AT_FastCall:
8053 case ParsedAttr::AT_ThisCall:
8054 case ParsedAttr::AT_Pascal:
8055 case ParsedAttr::AT_RegCall:
8056 case ParsedAttr::AT_SwiftCall:
8057 case ParsedAttr::AT_SwiftAsyncCall:
8058 case ParsedAttr::AT_VectorCall:
8059 case ParsedAttr::AT_MSABI:
8060 case ParsedAttr::AT_SysVABI:
8061 case ParsedAttr::AT_Pcs:
8062 case ParsedAttr::AT_IntelOclBicc:
8063 case ParsedAttr::AT_PreserveMost:
8064 case ParsedAttr::AT_PreserveAll:
8065 case ParsedAttr::AT_AArch64VectorPcs:
8066 case ParsedAttr::AT_AArch64SVEPcs:
8067 case ParsedAttr::AT_M68kRTD:
8068 case ParsedAttr::AT_PreserveNone:
8069 case ParsedAttr::AT_RISCVVectorCC:
8070 case ParsedAttr::AT_RISCVVLSCC:
8071 handleCallConvAttr(S, D, AL);
8072 break;
8073 case ParsedAttr::AT_DeviceKernel:
8074 handleDeviceKernelAttr(S, D, AL);
8075 break;
8076 case ParsedAttr::AT_Suppress:
8077 handleSuppressAttr(S, D, AL);
8078 break;
8079 case ParsedAttr::AT_Owner:
8080 case ParsedAttr::AT_Pointer:
8081 handleLifetimeCategoryAttr(S, D, AL);
8082 break;
8083 case ParsedAttr::AT_OpenCLAccess:
8084 S.OpenCL().handleAccessAttr(D, AL);
8085 break;
8086 case ParsedAttr::AT_OpenCLNoSVM:
8087 S.OpenCL().handleNoSVMAttr(D, AL);
8088 break;
8089 case ParsedAttr::AT_SwiftContext:
8090 S.Swift().AddParameterABIAttr(D, CI: AL, abi: ParameterABI::SwiftContext);
8091 break;
8092 case ParsedAttr::AT_SwiftAsyncContext:
8093 S.Swift().AddParameterABIAttr(D, CI: AL, abi: ParameterABI::SwiftAsyncContext);
8094 break;
8095 case ParsedAttr::AT_SwiftErrorResult:
8096 S.Swift().AddParameterABIAttr(D, CI: AL, abi: ParameterABI::SwiftErrorResult);
8097 break;
8098 case ParsedAttr::AT_SwiftIndirectResult:
8099 S.Swift().AddParameterABIAttr(D, CI: AL, abi: ParameterABI::SwiftIndirectResult);
8100 break;
8101 case ParsedAttr::AT_InternalLinkage:
8102 handleInternalLinkageAttr(S, D, AL);
8103 break;
8104 case ParsedAttr::AT_ZeroCallUsedRegs:
8105 handleZeroCallUsedRegsAttr(S, D, AL);
8106 break;
8107 case ParsedAttr::AT_FunctionReturnThunks:
8108 handleFunctionReturnThunksAttr(S, D, AL);
8109 break;
8110 case ParsedAttr::AT_NoMerge:
8111 handleNoMergeAttr(S, D, AL);
8112 break;
8113 case ParsedAttr::AT_NoUniqueAddress:
8114 handleNoUniqueAddressAttr(S, D, AL);
8115 break;
8116
8117 case ParsedAttr::AT_AvailableOnlyInDefaultEvalMethod:
8118 handleAvailableOnlyInDefaultEvalMethod(S, D, AL);
8119 break;
8120
8121 case ParsedAttr::AT_CountedBy:
8122 case ParsedAttr::AT_CountedByOrNull:
8123 case ParsedAttr::AT_SizedBy:
8124 case ParsedAttr::AT_SizedByOrNull:
8125 handleCountedByAttrField(S, D, AL);
8126 break;
8127
8128 case ParsedAttr::AT_NoFieldProtection:
8129 handleNoPFPAttrField(S, D, AL);
8130 break;
8131
8132 case ParsedAttr::AT_Personality:
8133 handlePersonalityAttr(S, D, AL);
8134 break;
8135
8136 // Microsoft attributes:
8137 case ParsedAttr::AT_LayoutVersion:
8138 handleLayoutVersion(S, D, AL);
8139 break;
8140 case ParsedAttr::AT_Uuid:
8141 handleUuidAttr(S, D, AL);
8142 break;
8143 case ParsedAttr::AT_MSInheritance:
8144 handleMSInheritanceAttr(S, D, AL);
8145 break;
8146 case ParsedAttr::AT_Thread:
8147 handleDeclspecThreadAttr(S, D, AL);
8148 break;
8149 case ParsedAttr::AT_MSConstexpr:
8150 handleMSConstexprAttr(S, D, AL);
8151 break;
8152 case ParsedAttr::AT_HybridPatchable:
8153 handleSimpleAttribute<HybridPatchableAttr>(S, D, CI: AL);
8154 break;
8155
8156 // HLSL attributes:
8157 case ParsedAttr::AT_RootSignature:
8158 S.HLSL().handleRootSignatureAttr(D, AL);
8159 break;
8160 case ParsedAttr::AT_HLSLNumThreads:
8161 S.HLSL().handleNumThreadsAttr(D, AL);
8162 break;
8163 case ParsedAttr::AT_HLSLWaveSize:
8164 S.HLSL().handleWaveSizeAttr(D, AL);
8165 break;
8166 case ParsedAttr::AT_HLSLVkExtBuiltinInput:
8167 S.HLSL().handleVkExtBuiltinInputAttr(D, AL);
8168 break;
8169 case ParsedAttr::AT_HLSLVkExtBuiltinOutput:
8170 S.HLSL().handleVkExtBuiltinOutputAttr(D, AL);
8171 break;
8172 case ParsedAttr::AT_HLSLVkPushConstant:
8173 S.HLSL().handleVkPushConstantAttr(D, AL);
8174 break;
8175 case ParsedAttr::AT_HLSLVkConstantId:
8176 S.HLSL().handleVkConstantIdAttr(D, AL);
8177 break;
8178 case ParsedAttr::AT_HLSLVkBinding:
8179 S.HLSL().handleVkBindingAttr(D, AL);
8180 break;
8181 case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
8182 handleSimpleAttribute<HLSLGroupSharedAddressSpaceAttr>(S, D, CI: AL);
8183 break;
8184 case ParsedAttr::AT_HLSLPackOffset:
8185 S.HLSL().handlePackOffsetAttr(D, AL);
8186 break;
8187 case ParsedAttr::AT_HLSLShader:
8188 S.HLSL().handleShaderAttr(D, AL);
8189 break;
8190 case ParsedAttr::AT_HLSLResourceBinding:
8191 S.HLSL().handleResourceBindingAttr(D, AL);
8192 break;
8193 case ParsedAttr::AT_HLSLParamModifier:
8194 S.HLSL().handleParamModifierAttr(D, AL);
8195 break;
8196 case ParsedAttr::AT_HLSLUnparsedSemantic:
8197 S.HLSL().handleSemanticAttr(D, AL);
8198 break;
8199 case ParsedAttr::AT_HLSLVkLocation:
8200 S.HLSL().handleVkLocationAttr(D, AL);
8201 break;
8202
8203 case ParsedAttr::AT_AbiTag:
8204 handleAbiTagAttr(S, D, AL);
8205 break;
8206 case ParsedAttr::AT_CFGuard:
8207 handleCFGuardAttr(S, D, AL);
8208 break;
8209
8210 // Thread safety attributes:
8211 case ParsedAttr::AT_PtGuardedVar:
8212 handlePtGuardedVarAttr(S, D, AL);
8213 break;
8214 case ParsedAttr::AT_NoSanitize:
8215 handleNoSanitizeAttr(S, D, AL);
8216 break;
8217 case ParsedAttr::AT_NoSanitizeAddress:
8218 handleNoSanitizeAddressAttr(S, D, AL);
8219 break;
8220 case ParsedAttr::AT_NoSanitizeThread:
8221 handleNoSanitizeThreadAttr(S, D, AL);
8222 break;
8223 case ParsedAttr::AT_NoSanitizeMemory:
8224 handleNoSanitizeMemoryAttr(S, D, AL);
8225 break;
8226 case ParsedAttr::AT_GuardedBy:
8227 handleGuardedByAttr(S, D, AL);
8228 break;
8229 case ParsedAttr::AT_PtGuardedBy:
8230 handlePtGuardedByAttr(S, D, AL);
8231 break;
8232 case ParsedAttr::AT_LockReturned:
8233 handleLockReturnedAttr(S, D, AL);
8234 break;
8235 case ParsedAttr::AT_LocksExcluded:
8236 handleLocksExcludedAttr(S, D, AL);
8237 break;
8238 case ParsedAttr::AT_AcquiredBefore:
8239 handleAcquiredBeforeAttr(S, D, AL);
8240 break;
8241 case ParsedAttr::AT_AcquiredAfter:
8242 handleAcquiredAfterAttr(S, D, AL);
8243 break;
8244
8245 // Capability analysis attributes.
8246 case ParsedAttr::AT_Capability:
8247 case ParsedAttr::AT_Lockable:
8248 handleCapabilityAttr(S, D, AL);
8249 break;
8250 case ParsedAttr::AT_ReentrantCapability:
8251 handleReentrantCapabilityAttr(S, D, AL);
8252 break;
8253 case ParsedAttr::AT_RequiresCapability:
8254 handleRequiresCapabilityAttr(S, D, AL);
8255 break;
8256
8257 case ParsedAttr::AT_AssertCapability:
8258 handleAssertCapabilityAttr(S, D, AL);
8259 break;
8260 case ParsedAttr::AT_AcquireCapability:
8261 handleAcquireCapabilityAttr(S, D, AL);
8262 break;
8263 case ParsedAttr::AT_ReleaseCapability:
8264 handleReleaseCapabilityAttr(S, D, AL);
8265 break;
8266 case ParsedAttr::AT_TryAcquireCapability:
8267 handleTryAcquireCapabilityAttr(S, D, AL);
8268 break;
8269
8270 // Consumed analysis attributes.
8271 case ParsedAttr::AT_Consumable:
8272 handleConsumableAttr(S, D, AL);
8273 break;
8274 case ParsedAttr::AT_CallableWhen:
8275 handleCallableWhenAttr(S, D, AL);
8276 break;
8277 case ParsedAttr::AT_ParamTypestate:
8278 handleParamTypestateAttr(S, D, AL);
8279 break;
8280 case ParsedAttr::AT_ReturnTypestate:
8281 handleReturnTypestateAttr(S, D, AL);
8282 break;
8283 case ParsedAttr::AT_SetTypestate:
8284 handleSetTypestateAttr(S, D, AL);
8285 break;
8286 case ParsedAttr::AT_TestTypestate:
8287 handleTestTypestateAttr(S, D, AL);
8288 break;
8289
8290 // Type safety attributes.
8291 case ParsedAttr::AT_ArgumentWithTypeTag:
8292 handleArgumentWithTypeTagAttr(S, D, AL);
8293 break;
8294 case ParsedAttr::AT_TypeTagForDatatype:
8295 handleTypeTagForDatatypeAttr(S, D, AL);
8296 break;
8297
8298 // Swift attributes.
8299 case ParsedAttr::AT_SwiftAsyncName:
8300 S.Swift().handleAsyncName(D, AL);
8301 break;
8302 case ParsedAttr::AT_SwiftAttr:
8303 S.Swift().handleAttrAttr(D, AL);
8304 break;
8305 case ParsedAttr::AT_SwiftBridge:
8306 S.Swift().handleBridge(D, AL);
8307 break;
8308 case ParsedAttr::AT_SwiftError:
8309 S.Swift().handleError(D, AL);
8310 break;
8311 case ParsedAttr::AT_SwiftName:
8312 S.Swift().handleName(D, AL);
8313 break;
8314 case ParsedAttr::AT_SwiftNewType:
8315 S.Swift().handleNewType(D, AL);
8316 break;
8317 case ParsedAttr::AT_SwiftAsync:
8318 S.Swift().handleAsyncAttr(D, AL);
8319 break;
8320 case ParsedAttr::AT_SwiftAsyncError:
8321 S.Swift().handleAsyncError(D, AL);
8322 break;
8323
8324 // XRay attributes.
8325 case ParsedAttr::AT_XRayLogArgs:
8326 handleXRayLogArgsAttr(S, D, AL);
8327 break;
8328
8329 case ParsedAttr::AT_PatchableFunctionEntry:
8330 handlePatchableFunctionEntryAttr(S, D, AL);
8331 break;
8332
8333 case ParsedAttr::AT_AlwaysDestroy:
8334 case ParsedAttr::AT_NoDestroy:
8335 handleDestroyAttr(S, D, A: AL);
8336 break;
8337
8338 case ParsedAttr::AT_Uninitialized:
8339 handleUninitializedAttr(S, D, AL);
8340 break;
8341
8342 case ParsedAttr::AT_ObjCExternallyRetained:
8343 S.ObjC().handleExternallyRetainedAttr(D, AL);
8344 break;
8345
8346 case ParsedAttr::AT_MIGServerRoutine:
8347 handleMIGServerRoutineAttr(S, D, AL);
8348 break;
8349
8350 case ParsedAttr::AT_MSAllocator:
8351 handleMSAllocatorAttr(S, D, AL);
8352 break;
8353
8354 case ParsedAttr::AT_ArmBuiltinAlias:
8355 S.ARM().handleBuiltinAliasAttr(D, AL);
8356 break;
8357
8358 case ParsedAttr::AT_ArmLocallyStreaming:
8359 handleSimpleAttribute<ArmLocallyStreamingAttr>(S, D, CI: AL);
8360 break;
8361
8362 case ParsedAttr::AT_ArmNew:
8363 S.ARM().handleNewAttr(D, AL);
8364 break;
8365
8366 case ParsedAttr::AT_AcquireHandle:
8367 handleAcquireHandleAttr(S, D, AL);
8368 break;
8369
8370 case ParsedAttr::AT_ReleaseHandle:
8371 handleHandleAttr<ReleaseHandleAttr>(S, D, AL);
8372 break;
8373
8374 case ParsedAttr::AT_UnsafeBufferUsage:
8375 handleUnsafeBufferUsage<UnsafeBufferUsageAttr>(S, D, AL);
8376 break;
8377
8378 case ParsedAttr::AT_UseHandle:
8379 handleHandleAttr<UseHandleAttr>(S, D, AL);
8380 break;
8381
8382 case ParsedAttr::AT_EnforceTCB:
8383 handleEnforceTCBAttr<EnforceTCBAttr, EnforceTCBLeafAttr>(S, D, AL);
8384 break;
8385
8386 case ParsedAttr::AT_EnforceTCBLeaf:
8387 handleEnforceTCBAttr<EnforceTCBLeafAttr, EnforceTCBAttr>(S, D, AL);
8388 break;
8389
8390 case ParsedAttr::AT_BuiltinAlias:
8391 handleBuiltinAliasAttr(S, D, AL);
8392 break;
8393
8394 case ParsedAttr::AT_PreferredType:
8395 handlePreferredTypeAttr(S, D, AL);
8396 break;
8397
8398 case ParsedAttr::AT_UsingIfExists:
8399 handleSimpleAttribute<UsingIfExistsAttr>(S, D, CI: AL);
8400 break;
8401
8402 case ParsedAttr::AT_TypeNullable:
8403 handleNullableTypeAttr(S, D, AL);
8404 break;
8405
8406 case ParsedAttr::AT_VTablePointerAuthentication:
8407 handleVTablePointerAuthentication(S, D, AL);
8408 break;
8409
8410 case ParsedAttr::AT_ModularFormat:
8411 handleModularFormat(S, D, AL);
8412 break;
8413
8414 case ParsedAttr::AT_MSStruct:
8415 handleMSStructAttr(S, D, AL);
8416 break;
8417
8418 case ParsedAttr::AT_GCCStruct:
8419 handleGCCStructAttr(S, D, AL);
8420 break;
8421
8422 case ParsedAttr::AT_PointerFieldProtection:
8423 if (!S.getLangOpts().PointerFieldProtectionAttr)
8424 S.Diag(Loc: AL.getLoc(),
8425 DiagID: diag::err_attribute_pointer_field_protection_experimental)
8426 << AL << AL.isRegularKeywordAttribute() << D->getLocation();
8427 handleSimpleAttribute<PointerFieldProtectionAttr>(S, D, CI: AL);
8428 break;
8429 }
8430}
8431
8432static bool isKernelDecl(Decl *D) {
8433 const FunctionType *FnTy = D->getFunctionType();
8434 return D->hasAttr<DeviceKernelAttr>() ||
8435 (FnTy && FnTy->getCallConv() == CallingConv::CC_DeviceKernel) ||
8436 D->hasAttr<CUDAGlobalAttr>();
8437}
8438
8439static void checkAMDGPUReqdWorkGroupSize(Sema &S, Decl *D) {
8440 if (!S.Context.getTargetInfo().getTriple().isAMDGPU())
8441 return;
8442
8443 const auto *Flat = D->getAttr<AMDGPUFlatWorkGroupSizeAttr>();
8444 const auto *Reqd = D->getAttr<ReqdWorkGroupSizeAttr>();
8445 if (!Flat || !Reqd)
8446 return;
8447
8448 auto Eval = [&](Expr *E) -> std::optional<uint64_t> {
8449 if (E->isValueDependent())
8450 return std::nullopt;
8451 std::optional<llvm::APSInt> V = E->getIntegerConstantExpr(Ctx: S.Context);
8452 if (!V)
8453 return std::nullopt;
8454 return V->getZExtValue();
8455 };
8456
8457 std::optional<uint64_t> X = Eval(Reqd->getXDim());
8458 std::optional<uint64_t> Y = Eval(Reqd->getYDim());
8459 std::optional<uint64_t> Z = Eval(Reqd->getZDim());
8460 std::optional<uint64_t> Min = Eval(Flat->getMin());
8461 std::optional<uint64_t> Max = Eval(Flat->getMax());
8462 if (!X || !Y || !Z || !Min || !Max)
8463 return;
8464
8465 uint64_t Product = *X * *Y * *Z;
8466 if (*Min != Product || *Max != Product) {
8467 S.Diag(Loc: Flat->getLocation(),
8468 DiagID: diag::err_attribute_amdgpu_flat_work_group_size_mismatch);
8469 D->setInvalidDecl();
8470 }
8471}
8472
8473void Sema::ProcessDeclAttributeList(
8474 Scope *S, Decl *D, const ParsedAttributesView &AttrList,
8475 const ProcessDeclAttributeOptions &Options) {
8476 if (AttrList.empty())
8477 return;
8478
8479 for (const ParsedAttr &AL : AttrList)
8480 ProcessDeclAttribute(S&: *this, scope: S, D, AL, Options);
8481
8482 // FIXME: We should be able to handle these cases in TableGen.
8483 // GCC accepts
8484 // static int a9 __attribute__((weakref));
8485 // but that looks really pointless. We reject it.
8486 if (D->hasAttr<WeakRefAttr>() && !D->hasAttr<AliasAttr>()) {
8487 Diag(Loc: AttrList.begin()->getLoc(), DiagID: diag::err_attribute_weakref_without_alias)
8488 << cast<NamedDecl>(Val: D);
8489 D->dropAttr<WeakRefAttr>();
8490 return;
8491 }
8492
8493 // FIXME: We should be able to handle this in TableGen as well. It would be
8494 // good to have a way to specify "these attributes must appear as a group",
8495 // for these. Additionally, it would be good to have a way to specify "these
8496 // attribute must never appear as a group" for attributes like cold and hot.
8497 if (!(D->hasAttr<DeviceKernelAttr>() ||
8498 (D->hasAttr<CUDAGlobalAttr>() &&
8499 Context.getTargetInfo().getTriple().isSPIRV()))) {
8500 // These attributes cannot be applied to a non-kernel function.
8501 if (const auto *A = D->getAttr<ReqdWorkGroupSizeAttr>()) {
8502 // FIXME: This emits a different error message than
8503 // diag::err_attribute_wrong_decl_type + ExpectedKernelFunction.
8504 Diag(Loc: D->getLocation(), DiagID: diag::err_opencl_kernel_attr) << A;
8505 D->setInvalidDecl();
8506 } else if (const auto *A = D->getAttr<WorkGroupSizeHintAttr>()) {
8507 Diag(Loc: D->getLocation(), DiagID: diag::err_opencl_kernel_attr) << A;
8508 D->setInvalidDecl();
8509 } else if (const auto *A = D->getAttr<VecTypeHintAttr>()) {
8510 Diag(Loc: D->getLocation(), DiagID: diag::err_opencl_kernel_attr) << A;
8511 D->setInvalidDecl();
8512 } else if (const auto *A = D->getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {
8513 Diag(Loc: D->getLocation(), DiagID: diag::err_opencl_kernel_attr) << A;
8514 D->setInvalidDecl();
8515 }
8516 }
8517 if (!isKernelDecl(D)) {
8518 if (const auto *A = D->getAttr<AMDGPUFlatWorkGroupSizeAttr>()) {
8519 Diag(Loc: D->getLocation(), DiagID: diag::err_attribute_wrong_decl_type)
8520 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8521 D->setInvalidDecl();
8522 } else if (const auto *A = D->getAttr<AMDGPUWavesPerEUAttr>()) {
8523 Diag(Loc: D->getLocation(), DiagID: diag::err_attribute_wrong_decl_type)
8524 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8525 D->setInvalidDecl();
8526 } else if (const auto *A = D->getAttr<AMDGPUNumSGPRAttr>()) {
8527 Diag(Loc: D->getLocation(), DiagID: diag::err_attribute_wrong_decl_type)
8528 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8529 D->setInvalidDecl();
8530 } else if (const auto *A = D->getAttr<AMDGPUNumVGPRAttr>()) {
8531 Diag(Loc: D->getLocation(), DiagID: diag::err_attribute_wrong_decl_type)
8532 << A << A->isRegularKeywordAttribute() << ExpectedKernelFunction;
8533 D->setInvalidDecl();
8534 }
8535 }
8536 checkAMDGPUReqdWorkGroupSize(S&: *this, D);
8537
8538 // CUDA/HIP: restrict explicit CUDA target attributes on deduction guides.
8539 //
8540 // Deduction guides are not callable functions and never participate in
8541 // codegen; they are always treated as host+device for CUDA/HIP semantic
8542 // checks. We therefore allow either no CUDA target attributes or an explicit
8543 // '__host__ __device__' annotation, but reject guides that are host-only,
8544 // device-only, or marked '__global__'. The use of explicit CUDA/HIP target
8545 // attributes on deduction guides is deprecated and will be rejected in a
8546 // future Clang version.
8547 if (getLangOpts().CUDA)
8548 if (auto *Guide = dyn_cast<CXXDeductionGuideDecl>(Val: D)) {
8549 bool HasHost = Guide->hasAttr<CUDAHostAttr>();
8550 bool HasDevice = Guide->hasAttr<CUDADeviceAttr>();
8551 bool HasGlobal = Guide->hasAttr<CUDAGlobalAttr>();
8552
8553 if (HasGlobal || HasHost != HasDevice) {
8554 Diag(Loc: Guide->getLocation(), DiagID: diag::err_deduction_guide_target_attr);
8555 Guide->setInvalidDecl();
8556 } else if (HasHost && HasDevice) {
8557 Diag(Loc: Guide->getLocation(),
8558 DiagID: diag::warn_deduction_guide_target_attr_deprecated);
8559 }
8560 }
8561
8562 // Do not permit 'constructor' or 'destructor' attributes on __device__ code.
8563 if (getLangOpts().CUDAIsDevice && D->hasAttr<CUDADeviceAttr>() &&
8564 (D->hasAttr<ConstructorAttr>() || D->hasAttr<DestructorAttr>()) &&
8565 !getLangOpts().GPUAllowDeviceInit) {
8566 Diag(Loc: D->getLocation(), DiagID: diag::err_cuda_ctor_dtor_attrs)
8567 << (D->hasAttr<ConstructorAttr>() ? "constructors" : "destructors");
8568 D->setInvalidDecl();
8569 }
8570
8571 // Do this check after processing D's attributes because the attribute
8572 // objc_method_family can change whether the given method is in the init
8573 // family, and it can be applied after objc_designated_initializer. This is a
8574 // bit of a hack, but we need it to be compatible with versions of clang that
8575 // processed the attribute list in the wrong order.
8576 if (D->hasAttr<ObjCDesignatedInitializerAttr>() &&
8577 cast<ObjCMethodDecl>(Val: D)->getMethodFamily() != OMF_init) {
8578 Diag(Loc: D->getLocation(), DiagID: diag::err_designated_init_attr_non_init);
8579 D->dropAttr<ObjCDesignatedInitializerAttr>();
8580 }
8581}
8582
8583void Sema::ProcessDeclAttributeDelayed(Decl *D,
8584 const ParsedAttributesView &AttrList) {
8585 for (const ParsedAttr &AL : AttrList)
8586 if (AL.getKind() == ParsedAttr::AT_TransparentUnion) {
8587 handleTransparentUnionAttr(S&: *this, D, AL);
8588 break;
8589 }
8590
8591 // For BPFPreserveAccessIndexAttr, we want to populate the attributes
8592 // to fields and inner records as well.
8593 if (D && D->hasAttr<BPFPreserveAccessIndexAttr>())
8594 BPF().handlePreserveAIRecord(RD: cast<RecordDecl>(Val: D));
8595}
8596
8597bool Sema::ProcessAccessDeclAttributeList(
8598 AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList) {
8599 for (const ParsedAttr &AL : AttrList) {
8600 if (AL.getKind() == ParsedAttr::AT_Annotate) {
8601 ProcessDeclAttribute(S&: *this, scope: nullptr, D: ASDecl, AL,
8602 Options: ProcessDeclAttributeOptions());
8603 } else {
8604 Diag(Loc: AL.getLoc(), DiagID: diag::err_only_annotate_after_access_spec);
8605 return true;
8606 }
8607 }
8608 return false;
8609}
8610
8611/// checkUnusedDeclAttributes - Check a list of attributes to see if it
8612/// contains any decl attributes that we should warn about.
8613static void checkUnusedDeclAttributes(Sema &S, const ParsedAttributesView &A) {
8614 for (const ParsedAttr &AL : A) {
8615 // Only warn if the attribute is an unignored, non-type attribute.
8616 if (AL.isUsedAsTypeAttr() || AL.isInvalid())
8617 continue;
8618 if (AL.getKind() == ParsedAttr::IgnoredAttribute)
8619 continue;
8620
8621 if (AL.getKind() == ParsedAttr::UnknownAttribute) {
8622 S.DiagnoseUnknownAttribute(AL);
8623 } else {
8624 S.Diag(Loc: AL.getLoc(), DiagID: diag::warn_attribute_not_on_decl) << AL
8625 << AL.getRange();
8626 }
8627 }
8628}
8629
8630void Sema::checkUnusedDeclAttributes(Declarator &D) {
8631 ::checkUnusedDeclAttributes(S&: *this, A: D.getDeclarationAttributes());
8632 ::checkUnusedDeclAttributes(S&: *this, A: D.getDeclSpec().getAttributes());
8633 ::checkUnusedDeclAttributes(S&: *this, A: D.getAttributes());
8634 for (unsigned i = 0, e = D.getNumTypeObjects(); i != e; ++i)
8635 ::checkUnusedDeclAttributes(S&: *this, A: D.getTypeObject(i).getAttrs());
8636}
8637
8638void Sema::DiagnoseUnknownAttribute(const ParsedAttr &AL) {
8639 SourceRange NR = AL.getNormalizedRange();
8640 StringRef ScopeName = AL.getNormalizedScopeName();
8641 std::optional<StringRef> CorrectedScopeName =
8642 AL.tryGetCorrectedScopeName(ScopeName);
8643 if (CorrectedScopeName) {
8644 ScopeName = *CorrectedScopeName;
8645 }
8646
8647 StringRef AttrName = AL.getNormalizedAttrName(ScopeName);
8648 std::optional<StringRef> CorrectedAttrName = AL.tryGetCorrectedAttrName(
8649 ScopeName, AttrName, Target: Context.getTargetInfo(), LangOpts: getLangOpts());
8650 if (CorrectedAttrName) {
8651 AttrName = *CorrectedAttrName;
8652 }
8653
8654 if (CorrectedScopeName || CorrectedAttrName) {
8655 std::string CorrectedFullName =
8656 AL.getNormalizedFullName(ScopeName, AttrName);
8657 SemaDiagnosticBuilder D =
8658 Diag(Loc: CorrectedScopeName ? NR.getBegin() : AL.getRange().getBegin(),
8659 DiagID: diag::warn_unknown_attribute_ignored_suggestion);
8660
8661 D << AL << CorrectedFullName;
8662
8663 if (AL.isExplicitScope()) {
8664 D << FixItHint::CreateReplacement(RemoveRange: NR, Code: CorrectedFullName) << NR;
8665 } else {
8666 if (CorrectedScopeName) {
8667 D << FixItHint::CreateReplacement(RemoveRange: SourceRange(AL.getScopeLoc()),
8668 Code: ScopeName);
8669 }
8670 if (CorrectedAttrName) {
8671 D << FixItHint::CreateReplacement(RemoveRange: AL.getRange(), Code: AttrName);
8672 }
8673 }
8674 } else {
8675 Diag(Loc: NR.getBegin(), DiagID: diag::warn_unknown_attribute_ignored) << AL << NR;
8676 }
8677}
8678
8679NamedDecl *Sema::DeclClonePragmaWeak(NamedDecl *ND, const IdentifierInfo *II,
8680 SourceLocation Loc) {
8681 assert(isa<FunctionDecl>(ND) || isa<VarDecl>(ND));
8682 NamedDecl *NewD = nullptr;
8683 if (auto *FD = dyn_cast<FunctionDecl>(Val: ND)) {
8684 FunctionDecl *NewFD;
8685 // FIXME: Missing call to CheckFunctionDeclaration().
8686 // FIXME: Mangling?
8687 // FIXME: Is the qualifier info correct?
8688 // FIXME: Is the DeclContext correct?
8689 NewFD = FunctionDecl::Create(
8690 C&: FD->getASTContext(), DC: FD->getDeclContext(), StartLoc: Loc, NLoc: Loc,
8691 N: DeclarationName(II), T: FD->getType(), TInfo: FD->getTypeSourceInfo(), SC: SC_None,
8692 UsesFPIntrin: getCurFPFeatures().isFPConstrained(), isInlineSpecified: false /*isInlineSpecified*/,
8693 hasWrittenPrototype: FD->hasPrototype(), ConstexprKind: ConstexprSpecKind::Unspecified,
8694 TrailingRequiresClause: FD->getTrailingRequiresClause());
8695 NewD = NewFD;
8696
8697 if (FD->getQualifier())
8698 NewFD->setQualifierInfo(FD->getQualifierLoc());
8699
8700 // Fake up parameter variables; they are declared as if this were
8701 // a typedef.
8702 QualType FDTy = FD->getType();
8703 if (const auto *FT = FDTy->getAs<FunctionProtoType>()) {
8704 SmallVector<ParmVarDecl*, 16> Params;
8705 for (const auto &AI : FT->param_types()) {
8706 ParmVarDecl *Param = BuildParmVarDeclForTypedef(DC: NewFD, Loc, T: AI);
8707 Param->setScopeInfo(scopeDepth: 0, parameterIndex: Params.size());
8708 Params.push_back(Elt: Param);
8709 }
8710 NewFD->setParams(Params);
8711 }
8712 } else if (auto *VD = dyn_cast<VarDecl>(Val: ND)) {
8713 NewD = VarDecl::Create(C&: VD->getASTContext(), DC: VD->getDeclContext(),
8714 StartLoc: VD->getInnerLocStart(), IdLoc: VD->getLocation(), Id: II,
8715 T: VD->getType(), TInfo: VD->getTypeSourceInfo(),
8716 S: VD->getStorageClass());
8717 if (VD->getQualifier())
8718 cast<VarDecl>(Val: NewD)->setQualifierInfo(VD->getQualifierLoc());
8719 }
8720 return NewD;
8721}
8722
8723void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, const WeakInfo &W) {
8724 if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
8725 IdentifierInfo *NDId = ND->getIdentifier();
8726 NamedDecl *NewD = DeclClonePragmaWeak(ND, II: W.getAlias(), Loc: W.getLocation());
8727 NewD->addAttr(
8728 A: AliasAttr::CreateImplicit(Ctx&: Context, Aliasee: NDId->getName(), Range: W.getLocation()));
8729 NewD->addAttr(A: WeakAttr::CreateImplicit(Ctx&: Context, Range: W.getLocation()));
8730 WeakTopLevelDecl.push_back(Elt: NewD);
8731 // FIXME: "hideous" code from Sema::LazilyCreateBuiltin
8732 // to insert Decl at TU scope, sorry.
8733 DeclContext *SavedContext = CurContext;
8734 CurContext = Context.getTranslationUnitDecl();
8735 NewD->setDeclContext(CurContext);
8736 NewD->setLexicalDeclContext(CurContext);
8737 PushOnScopeChains(D: NewD, S);
8738 CurContext = SavedContext;
8739 } else { // just add weak to existing
8740 ND->addAttr(A: WeakAttr::CreateImplicit(Ctx&: Context, Range: W.getLocation()));
8741 }
8742}
8743
8744void Sema::ProcessPragmaWeak(Scope *S, Decl *D) {
8745 // It's valid to "forward-declare" #pragma weak, in which case we
8746 // have to do this.
8747 LoadExternalWeakUndeclaredIdentifiers();
8748 if (WeakUndeclaredIdentifiers.empty())
8749 return;
8750 NamedDecl *ND = nullptr;
8751 if (auto *VD = dyn_cast<VarDecl>(Val: D))
8752 if (VD->isExternC())
8753 ND = VD;
8754 if (auto *FD = dyn_cast<FunctionDecl>(Val: D))
8755 if (FD->isExternC())
8756 ND = FD;
8757 if (!ND)
8758 return;
8759 if (IdentifierInfo *Id = ND->getIdentifier()) {
8760 auto I = WeakUndeclaredIdentifiers.find(Key: Id);
8761 if (I != WeakUndeclaredIdentifiers.end()) {
8762 auto &WeakInfos = I->second;
8763 for (const auto &W : WeakInfos)
8764 DeclApplyPragmaWeak(S, ND, W);
8765 std::remove_reference_t<decltype(WeakInfos)> EmptyWeakInfos;
8766 WeakInfos.swap(RHS&: EmptyWeakInfos);
8767 }
8768 }
8769}
8770
8771/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
8772/// it, apply them to D. This is a bit tricky because PD can have attributes
8773/// specified in many different places, and we need to find and apply them all.
8774void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
8775 // Ordering of attributes can be important, so we take care to process
8776 // attributes in the order in which they appeared in the source code.
8777
8778 auto ProcessAttributesWithSliding =
8779 [&](const ParsedAttributesView &Src,
8780 const ProcessDeclAttributeOptions &Options) {
8781 ParsedAttributesView NonSlidingAttrs;
8782 for (ParsedAttr &AL : Src) {
8783 // FIXME: this sliding is specific to standard attributes and should
8784 // eventually be deprecated and removed as those are not intended to
8785 // slide to anything.
8786 if ((AL.isStandardAttributeSyntax() || AL.isAlignas()) &&
8787 AL.slidesFromDeclToDeclSpecLegacyBehavior()) {
8788 // Skip processing the attribute, but do check if it appertains to
8789 // the declaration. This is needed for the `MatrixType` attribute,
8790 // which, despite being a type attribute, defines a `SubjectList`
8791 // that only allows it to be used on typedef declarations.
8792 AL.diagnoseAppertainsTo(S&: *this, D);
8793 } else {
8794 NonSlidingAttrs.addAtEnd(newAttr: &AL);
8795 }
8796 }
8797 ProcessDeclAttributeList(S, D, AttrList: NonSlidingAttrs, Options);
8798 };
8799
8800 // First, process attributes that appeared on the declaration itself (but
8801 // only if they don't have the legacy behavior of "sliding" to the DeclSepc).
8802 ProcessAttributesWithSliding(PD.getDeclarationAttributes(), {});
8803
8804 // Apply decl attributes from the DeclSpec if present.
8805 ProcessAttributesWithSliding(PD.getDeclSpec().getAttributes(),
8806 ProcessDeclAttributeOptions()
8807 .WithIncludeCXX11Attributes(Val: false)
8808 .WithIgnoreTypeAttributes(Val: true));
8809
8810 // Walk the declarator structure, applying decl attributes that were in a type
8811 // position to the decl itself. This handles cases like:
8812 // int *__attr__(x)** D;
8813 // when X is a decl attribute.
8814 for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i) {
8815 ProcessDeclAttributeList(S, D, AttrList: PD.getTypeObject(i).getAttrs(),
8816 Options: ProcessDeclAttributeOptions()
8817 .WithIncludeCXX11Attributes(Val: false)
8818 .WithIgnoreTypeAttributes(Val: true));
8819 }
8820
8821 // Finally, apply any attributes on the decl itself.
8822 ProcessDeclAttributeList(S, D, AttrList: PD.getAttributes());
8823
8824 // Apply additional attributes specified by '#pragma clang attribute'.
8825 AddPragmaAttributes(S, D);
8826
8827 // Look for API notes that map to attributes.
8828 ProcessAPINotes(D);
8829}
8830
8831/// Is the given declaration allowed to use a forbidden type?
8832/// If so, it'll still be annotated with an attribute that makes it
8833/// illegal to actually use.
8834static bool isForbiddenTypeAllowed(Sema &S, Decl *D,
8835 const DelayedDiagnostic &diag,
8836 UnavailableAttr::ImplicitReason &reason) {
8837 // Private ivars are always okay. Unfortunately, people don't
8838 // always properly make their ivars private, even in system headers.
8839 // Plus we need to make fields okay, too.
8840 if (!isa<FieldDecl>(Val: D) && !isa<ObjCPropertyDecl>(Val: D) &&
8841 !isa<FunctionDecl>(Val: D))
8842 return false;
8843
8844 // Silently accept unsupported uses of __weak in both user and system
8845 // declarations when it's been disabled, for ease of integration with
8846 // -fno-objc-arc files. We do have to take some care against attempts
8847 // to define such things; for now, we've only done that for ivars
8848 // and properties.
8849 if ((isa<ObjCIvarDecl>(Val: D) || isa<ObjCPropertyDecl>(Val: D))) {
8850 if (diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_disabled ||
8851 diag.getForbiddenTypeDiagnostic() == diag::err_arc_weak_no_runtime) {
8852 reason = UnavailableAttr::IR_ForbiddenWeak;
8853 return true;
8854 }
8855 }
8856
8857 // Allow all sorts of things in system headers.
8858 if (S.Context.getSourceManager().isInSystemHeader(Loc: D->getLocation())) {
8859 // Currently, all the failures dealt with this way are due to ARC
8860 // restrictions.
8861 reason = UnavailableAttr::IR_ARCForbiddenType;
8862 return true;
8863 }
8864
8865 return false;
8866}
8867
8868/// Handle a delayed forbidden-type diagnostic.
8869static void handleDelayedForbiddenType(Sema &S, DelayedDiagnostic &DD,
8870 Decl *D) {
8871 auto Reason = UnavailableAttr::IR_None;
8872 if (D && isForbiddenTypeAllowed(S, D, diag: DD, reason&: Reason)) {
8873 assert(Reason && "didn't set reason?");
8874 D->addAttr(A: UnavailableAttr::CreateImplicit(Ctx&: S.Context, Message: "", ImplicitReason: Reason, Range: DD.Loc));
8875 return;
8876 }
8877 if (S.getLangOpts().ObjCAutoRefCount)
8878 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
8879 // FIXME: we may want to suppress diagnostics for all
8880 // kind of forbidden type messages on unavailable functions.
8881 if (FD->hasAttr<UnavailableAttr>() &&
8882 DD.getForbiddenTypeDiagnostic() ==
8883 diag::err_arc_array_param_no_ownership) {
8884 DD.Triggered = true;
8885 return;
8886 }
8887 }
8888
8889 S.Diag(Loc: DD.Loc, DiagID: DD.getForbiddenTypeDiagnostic())
8890 << DD.getForbiddenTypeOperand() << DD.getForbiddenTypeArgument();
8891 DD.Triggered = true;
8892}
8893
8894
8895void Sema::PopParsingDeclaration(ParsingDeclState state, Decl *decl) {
8896 assert(DelayedDiagnostics.getCurrentPool());
8897 DelayedDiagnosticPool &poppedPool = *DelayedDiagnostics.getCurrentPool();
8898 DelayedDiagnostics.popWithoutEmitting(state);
8899
8900 // When delaying diagnostics to run in the context of a parsed
8901 // declaration, we only want to actually emit anything if parsing
8902 // succeeds.
8903 if (!decl) return;
8904
8905 // We emit all the active diagnostics in this pool or any of its
8906 // parents. In general, we'll get one pool for the decl spec
8907 // and a child pool for each declarator; in a decl group like:
8908 // deprecated_typedef foo, *bar, baz();
8909 // only the declarator pops will be passed decls. This is correct;
8910 // we really do need to consider delayed diagnostics from the decl spec
8911 // for each of the different declarations.
8912 const DelayedDiagnosticPool *pool = &poppedPool;
8913 do {
8914 bool AnyAccessFailures = false;
8915 for (DelayedDiagnosticPool::pool_iterator
8916 i = pool->pool_begin(), e = pool->pool_end(); i != e; ++i) {
8917 // This const_cast is a bit lame. Really, Triggered should be mutable.
8918 DelayedDiagnostic &diag = const_cast<DelayedDiagnostic&>(*i);
8919 if (diag.Triggered)
8920 continue;
8921
8922 switch (diag.Kind) {
8923 case DelayedDiagnostic::Availability:
8924 // Don't bother giving deprecation/unavailable diagnostics if
8925 // the decl is invalid.
8926 if (!decl->isInvalidDecl())
8927 handleDelayedAvailabilityCheck(DD&: diag, Ctx: decl);
8928 break;
8929
8930 case DelayedDiagnostic::Access:
8931 // Only produce one access control diagnostic for a structured binding
8932 // declaration: we don't need to tell the user that all the fields are
8933 // inaccessible one at a time.
8934 if (AnyAccessFailures && isa<DecompositionDecl>(Val: decl))
8935 continue;
8936 HandleDelayedAccessCheck(DD&: diag, Ctx: decl);
8937 if (diag.Triggered)
8938 AnyAccessFailures = true;
8939 break;
8940
8941 case DelayedDiagnostic::ForbiddenType:
8942 handleDelayedForbiddenType(S&: *this, DD&: diag, D: decl);
8943 break;
8944 }
8945 }
8946 } while ((pool = pool->getParent()));
8947}
8948
8949void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {
8950 DelayedDiagnosticPool *curPool = DelayedDiagnostics.getCurrentPool();
8951 assert(curPool && "re-emitting in undelayed context not supported");
8952 curPool->steal(pool);
8953}
8954
8955void Sema::ActOnCleanupAttr(Decl *D, const Attr *A) {
8956 VarDecl *VD = cast<VarDecl>(Val: D);
8957 if (VD->getType()->isDependentType())
8958 return;
8959
8960 // Obtains the FunctionDecl that was found when handling the attribute
8961 // earlier.
8962 CleanupAttr *Attr = D->getAttr<CleanupAttr>();
8963 FunctionDecl *FD = Attr->getFunctionDecl();
8964 DeclarationNameInfo NI = FD->getNameInfo();
8965
8966 // We're currently more strict than GCC about what function types we accept.
8967 // If this ever proves to be a problem it should be easy to fix.
8968 QualType Ty = this->Context.getPointerType(T: VD->getType());
8969 QualType ParamTy = FD->getParamDecl(i: 0)->getType();
8970 if (QualType ConvertedTy;
8971 !this->IsAssignConvertCompatible(ConvTy: this->CheckAssignmentConstraints(
8972 Loc: FD->getParamDecl(i: 0)->getLocation(), LHSType: ParamTy, RHSType: Ty)) &&
8973 !ObjC().isObjCWritebackConversion(FromType: Ty, ToType: ParamTy, ConvertedType&: ConvertedTy)) {
8974 this->Diag(Loc: Attr->getArgLoc(),
8975 DiagID: diag::err_attribute_cleanup_func_arg_incompatible_type)
8976 << NI.getName() << ParamTy << Ty;
8977 D->dropAttr<CleanupAttr>();
8978 return;
8979 }
8980}
8981
8982void Sema::ActOnInitPriorityAttr(Decl *D, const Attr *A) {
8983 QualType T = cast<VarDecl>(Val: D)->getType();
8984 if (this->Context.getAsArrayType(T))
8985 T = this->Context.getBaseElementType(QT: T);
8986 if (!T->isRecordType()) {
8987 this->Diag(Loc: A->getLoc(), DiagID: diag::err_init_priority_object_attr);
8988 D->dropAttr<InitPriorityAttr>();
8989 }
8990}
8991