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

source code of clang/lib/Sema/SemaDeclAttr.cpp