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