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