1 //===--- SemaAttr.cpp - Semantic Analysis for Attributes ------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements semantic analysis for non-trivial attributes and 10 // pragmas. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "CheckExprLifetime.h" 15 #include "clang/AST/ASTConsumer.h" 16 #include "clang/AST/Attr.h" 17 #include "clang/AST/Expr.h" 18 #include "clang/Basic/TargetInfo.h" 19 #include "clang/Lex/Preprocessor.h" 20 #include "clang/Sema/Lookup.h" 21 #include <optional> 22 using namespace clang; 23 24 //===----------------------------------------------------------------------===// 25 // Pragma 'pack' and 'options align' 26 //===----------------------------------------------------------------------===// 27 28 Sema::PragmaStackSentinelRAII::PragmaStackSentinelRAII(Sema &S, 29 StringRef SlotLabel, 30 bool ShouldAct) 31 : S(S), SlotLabel(SlotLabel), ShouldAct(ShouldAct) { 32 if (ShouldAct) { 33 S.VtorDispStack.SentinelAction(PSK_Push, SlotLabel); 34 S.DataSegStack.SentinelAction(PSK_Push, SlotLabel); 35 S.BSSSegStack.SentinelAction(PSK_Push, SlotLabel); 36 S.ConstSegStack.SentinelAction(PSK_Push, SlotLabel); 37 S.CodeSegStack.SentinelAction(PSK_Push, SlotLabel); 38 S.StrictGuardStackCheckStack.SentinelAction(PSK_Push, SlotLabel); 39 } 40 } 41 42 Sema::PragmaStackSentinelRAII::~PragmaStackSentinelRAII() { 43 if (ShouldAct) { 44 S.VtorDispStack.SentinelAction(PSK_Pop, SlotLabel); 45 S.DataSegStack.SentinelAction(PSK_Pop, SlotLabel); 46 S.BSSSegStack.SentinelAction(PSK_Pop, SlotLabel); 47 S.ConstSegStack.SentinelAction(PSK_Pop, SlotLabel); 48 S.CodeSegStack.SentinelAction(PSK_Pop, SlotLabel); 49 S.StrictGuardStackCheckStack.SentinelAction(PSK_Pop, SlotLabel); 50 } 51 } 52 53 void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) { 54 AlignPackInfo InfoVal = AlignPackStack.CurrentValue; 55 AlignPackInfo::Mode M = InfoVal.getAlignMode(); 56 bool IsPackSet = InfoVal.IsPackSet(); 57 bool IsXLPragma = getLangOpts().XLPragmaPack; 58 59 // If we are not under mac68k/natural alignment mode and also there is no pack 60 // value, we don't need any attributes. 61 if (!IsPackSet && M != AlignPackInfo::Mac68k && M != AlignPackInfo::Natural) 62 return; 63 64 if (M == AlignPackInfo::Mac68k && (IsXLPragma || InfoVal.IsAlignAttr())) { 65 RD->addAttr(AlignMac68kAttr::CreateImplicit(Context)); 66 } else if (IsPackSet) { 67 // Check to see if we need a max field alignment attribute. 68 RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit( 69 Context, InfoVal.getPackNumber() * 8)); 70 } 71 72 if (IsXLPragma && M == AlignPackInfo::Natural) 73 RD->addAttr(AlignNaturalAttr::CreateImplicit(Context)); 74 75 if (AlignPackIncludeStack.empty()) 76 return; 77 // The #pragma align/pack affected a record in an included file, so Clang 78 // should warn when that pragma was written in a file that included the 79 // included file. 80 for (auto &AlignPackedInclude : llvm::reverse(AlignPackIncludeStack)) { 81 if (AlignPackedInclude.CurrentPragmaLocation != 82 AlignPackStack.CurrentPragmaLocation) 83 break; 84 if (AlignPackedInclude.HasNonDefaultValue) 85 AlignPackedInclude.ShouldWarnOnInclude = true; 86 } 87 } 88 89 void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) { 90 if (MSStructPragmaOn) 91 RD->addAttr(MSStructAttr::CreateImplicit(Context)); 92 93 // FIXME: We should merge AddAlignmentAttributesForRecord with 94 // AddMsStructLayoutForRecord into AddPragmaAttributesForRecord, which takes 95 // all active pragmas and applies them as attributes to class definitions. 96 if (VtorDispStack.CurrentValue != getLangOpts().getVtorDispMode()) 97 RD->addAttr(MSVtorDispAttr::CreateImplicit( 98 Context, unsigned(VtorDispStack.CurrentValue))); 99 } 100 101 template <typename Attribute> 102 static void addGslOwnerPointerAttributeIfNotExisting(ASTContext &Context, 103 CXXRecordDecl *Record) { 104 if (Record->hasAttr<OwnerAttr>() || Record->hasAttr<PointerAttr>()) 105 return; 106 107 for (Decl *Redecl : Record->redecls()) 108 Redecl->addAttr(Attribute::CreateImplicit(Context, /*DerefType=*/nullptr)); 109 } 110 111 void Sema::inferGslPointerAttribute(NamedDecl *ND, 112 CXXRecordDecl *UnderlyingRecord) { 113 if (!UnderlyingRecord) 114 return; 115 116 const auto *Parent = dyn_cast<CXXRecordDecl>(ND->getDeclContext()); 117 if (!Parent) 118 return; 119 120 static const llvm::StringSet<> Containers{ 121 "array", 122 "basic_string", 123 "deque", 124 "forward_list", 125 "vector", 126 "list", 127 "map", 128 "multiset", 129 "multimap", 130 "priority_queue", 131 "queue", 132 "set", 133 "stack", 134 "unordered_set", 135 "unordered_map", 136 "unordered_multiset", 137 "unordered_multimap", 138 }; 139 140 static const llvm::StringSet<> Iterators{"iterator", "const_iterator", 141 "reverse_iterator", 142 "const_reverse_iterator"}; 143 144 if (Parent->isInStdNamespace() && Iterators.count(ND->getName()) && 145 Containers.count(Parent->getName())) 146 addGslOwnerPointerAttributeIfNotExisting<PointerAttr>(Context, 147 UnderlyingRecord); 148 } 149 150 void Sema::inferGslPointerAttribute(TypedefNameDecl *TD) { 151 152 QualType Canonical = TD->getUnderlyingType().getCanonicalType(); 153 154 CXXRecordDecl *RD = Canonical->getAsCXXRecordDecl(); 155 if (!RD) { 156 if (auto *TST = 157 dyn_cast<TemplateSpecializationType>(Canonical.getTypePtr())) { 158 159 RD = dyn_cast_or_null<CXXRecordDecl>( 160 TST->getTemplateName().getAsTemplateDecl()->getTemplatedDecl()); 161 } 162 } 163 164 inferGslPointerAttribute(TD, RD); 165 } 166 167 void Sema::inferGslOwnerPointerAttribute(CXXRecordDecl *Record) { 168 static const llvm::StringSet<> StdOwners{ 169 "any", 170 "array", 171 "basic_regex", 172 "basic_string", 173 "deque", 174 "forward_list", 175 "vector", 176 "list", 177 "map", 178 "multiset", 179 "multimap", 180 "optional", 181 "priority_queue", 182 "queue", 183 "set", 184 "stack", 185 "unique_ptr", 186 "unordered_set", 187 "unordered_map", 188 "unordered_multiset", 189 "unordered_multimap", 190 "variant", 191 }; 192 static const llvm::StringSet<> StdPointers{ 193 "basic_string_view", 194 "reference_wrapper", 195 "regex_iterator", 196 "span", 197 }; 198 199 if (!Record->getIdentifier()) 200 return; 201 202 // Handle classes that directly appear in std namespace. 203 if (Record->isInStdNamespace()) { 204 if (Record->hasAttr<OwnerAttr>() || Record->hasAttr<PointerAttr>()) 205 return; 206 207 if (StdOwners.count(Record->getName())) 208 addGslOwnerPointerAttributeIfNotExisting<OwnerAttr>(Context, Record); 209 else if (StdPointers.count(Record->getName())) 210 addGslOwnerPointerAttributeIfNotExisting<PointerAttr>(Context, Record); 211 212 return; 213 } 214 215 // Handle nested classes that could be a gsl::Pointer. 216 inferGslPointerAttribute(Record, Record); 217 } 218 219 void Sema::inferLifetimeBoundAttribute(FunctionDecl *FD) { 220 if (FD->getNumParams() == 0) 221 return; 222 223 if (unsigned BuiltinID = FD->getBuiltinID()) { 224 // Add lifetime attribute to std::move, std::fowrard et al. 225 switch (BuiltinID) { 226 case Builtin::BIaddressof: 227 case Builtin::BI__addressof: 228 case Builtin::BI__builtin_addressof: 229 case Builtin::BIas_const: 230 case Builtin::BIforward: 231 case Builtin::BIforward_like: 232 case Builtin::BImove: 233 case Builtin::BImove_if_noexcept: 234 if (ParmVarDecl *P = FD->getParamDecl(0u); 235 !P->hasAttr<LifetimeBoundAttr>()) 236 P->addAttr( 237 LifetimeBoundAttr::CreateImplicit(Context, FD->getLocation())); 238 break; 239 default: 240 break; 241 } 242 return; 243 } 244 if (auto *CMD = dyn_cast<CXXMethodDecl>(FD)) { 245 const auto *CRD = CMD->getParent(); 246 if (!CRD->isInStdNamespace() || !CRD->getIdentifier()) 247 return; 248 249 if (isa<CXXConstructorDecl>(CMD)) { 250 auto *Param = CMD->getParamDecl(0); 251 if (Param->hasAttr<LifetimeBoundAttr>()) 252 return; 253 if (CRD->getName() == "basic_string_view" && 254 Param->getType()->isPointerType()) { 255 // construct from a char array pointed by a pointer. 256 // basic_string_view(const CharT* s); 257 // basic_string_view(const CharT* s, size_type count); 258 Param->addAttr( 259 LifetimeBoundAttr::CreateImplicit(Context, FD->getLocation())); 260 } else if (CRD->getName() == "span") { 261 // construct from a reference of array. 262 // span(std::type_identity_t<element_type> (&arr)[N]); 263 const auto *LRT = Param->getType()->getAs<LValueReferenceType>(); 264 if (LRT && LRT->getPointeeType().IgnoreParens()->isArrayType()) 265 Param->addAttr( 266 LifetimeBoundAttr::CreateImplicit(Context, FD->getLocation())); 267 } 268 } 269 } 270 } 271 272 void Sema::inferLifetimeCaptureByAttribute(FunctionDecl *FD) { 273 auto *MD = dyn_cast_if_present<CXXMethodDecl>(FD); 274 if (!MD || !MD->getParent()->isInStdNamespace()) 275 return; 276 auto Annotate = [this](const FunctionDecl *MD) { 277 // Do not infer if any parameter is explicitly annotated. 278 for (ParmVarDecl *PVD : MD->parameters()) 279 if (PVD->hasAttr<LifetimeCaptureByAttr>()) 280 return; 281 for (ParmVarDecl *PVD : MD->parameters()) { 282 // Methods in standard containers that capture values typically accept 283 // reference-type parameters, e.g., `void push_back(const T& value)`. 284 // We only apply the lifetime_capture_by attribute to parameters of 285 // pointer-like reference types (`const T&`, `T&&`). 286 if (PVD->getType()->isReferenceType() && 287 sema::isGLSPointerType(PVD->getType().getNonReferenceType())) { 288 int CaptureByThis[] = {LifetimeCaptureByAttr::THIS}; 289 PVD->addAttr( 290 LifetimeCaptureByAttr::CreateImplicit(Context, CaptureByThis, 1)); 291 } 292 } 293 }; 294 295 if (!MD->getIdentifier()) { 296 static const llvm::StringSet<> MapLikeContainer{ 297 "map", 298 "multimap", 299 "unordered_map", 300 "unordered_multimap", 301 }; 302 // Infer for the map's operator []: 303 // std::map<string_view, ...> m; 304 // m[ReturnString(..)] = ...; // !dangling references in m. 305 if (MD->getOverloadedOperator() == OO_Subscript && 306 MapLikeContainer.contains(MD->getParent()->getName())) 307 Annotate(MD); 308 return; 309 } 310 static const llvm::StringSet<> CapturingMethods{ 311 "insert", "insert_or_assign", "push", "push_front", "push_back"}; 312 if (!CapturingMethods.contains(MD->getName())) 313 return; 314 Annotate(MD); 315 } 316 317 void Sema::inferNullableClassAttribute(CXXRecordDecl *CRD) { 318 static const llvm::StringSet<> Nullable{ 319 "auto_ptr", "shared_ptr", "unique_ptr", "exception_ptr", 320 "coroutine_handle", "function", "move_only_function", 321 }; 322 323 if (CRD->isInStdNamespace() && Nullable.count(CRD->getName()) && 324 !CRD->hasAttr<TypeNullableAttr>()) 325 for (Decl *Redecl : CRD->redecls()) 326 Redecl->addAttr(TypeNullableAttr::CreateImplicit(Context)); 327 } 328 329 void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, 330 SourceLocation PragmaLoc) { 331 PragmaMsStackAction Action = Sema::PSK_Reset; 332 AlignPackInfo::Mode ModeVal = AlignPackInfo::Native; 333 334 switch (Kind) { 335 // For most of the platforms we support, native and natural are the same. 336 // With XL, native is the same as power, natural means something else. 337 case POAK_Native: 338 case POAK_Power: 339 Action = Sema::PSK_Push_Set; 340 break; 341 case POAK_Natural: 342 Action = Sema::PSK_Push_Set; 343 ModeVal = AlignPackInfo::Natural; 344 break; 345 346 // Note that '#pragma options align=packed' is not equivalent to attribute 347 // packed, it has a different precedence relative to attribute aligned. 348 case POAK_Packed: 349 Action = Sema::PSK_Push_Set; 350 ModeVal = AlignPackInfo::Packed; 351 break; 352 353 case POAK_Mac68k: 354 // Check if the target supports this. 355 if (!this->Context.getTargetInfo().hasAlignMac68kSupport()) { 356 Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported); 357 return; 358 } 359 Action = Sema::PSK_Push_Set; 360 ModeVal = AlignPackInfo::Mac68k; 361 break; 362 case POAK_Reset: 363 // Reset just pops the top of the stack, or resets the current alignment to 364 // default. 365 Action = Sema::PSK_Pop; 366 if (AlignPackStack.Stack.empty()) { 367 if (AlignPackStack.CurrentValue.getAlignMode() != AlignPackInfo::Native || 368 AlignPackStack.CurrentValue.IsPackAttr()) { 369 Action = Sema::PSK_Reset; 370 } else { 371 Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed) 372 << "stack empty"; 373 return; 374 } 375 } 376 break; 377 } 378 379 AlignPackInfo Info(ModeVal, getLangOpts().XLPragmaPack); 380 381 AlignPackStack.Act(PragmaLoc, Action, StringRef(), Info); 382 } 383 384 void Sema::ActOnPragmaClangSection(SourceLocation PragmaLoc, 385 PragmaClangSectionAction Action, 386 PragmaClangSectionKind SecKind, 387 StringRef SecName) { 388 PragmaClangSection *CSec; 389 int SectionFlags = ASTContext::PSF_Read; 390 switch (SecKind) { 391 case PragmaClangSectionKind::PCSK_BSS: 392 CSec = &PragmaClangBSSSection; 393 SectionFlags |= ASTContext::PSF_Write | ASTContext::PSF_ZeroInit; 394 break; 395 case PragmaClangSectionKind::PCSK_Data: 396 CSec = &PragmaClangDataSection; 397 SectionFlags |= ASTContext::PSF_Write; 398 break; 399 case PragmaClangSectionKind::PCSK_Rodata: 400 CSec = &PragmaClangRodataSection; 401 break; 402 case PragmaClangSectionKind::PCSK_Relro: 403 CSec = &PragmaClangRelroSection; 404 break; 405 case PragmaClangSectionKind::PCSK_Text: 406 CSec = &PragmaClangTextSection; 407 SectionFlags |= ASTContext::PSF_Execute; 408 break; 409 default: 410 llvm_unreachable("invalid clang section kind"); 411 } 412 413 if (Action == PragmaClangSectionAction::PCSA_Clear) { 414 CSec->Valid = false; 415 return; 416 } 417 418 if (llvm::Error E = isValidSectionSpecifier(SecName)) { 419 Diag(PragmaLoc, diag::err_pragma_section_invalid_for_target) 420 << toString(std::move(E)); 421 CSec->Valid = false; 422 return; 423 } 424 425 if (UnifySection(SecName, SectionFlags, PragmaLoc)) 426 return; 427 428 CSec->Valid = true; 429 CSec->SectionName = std::string(SecName); 430 CSec->PragmaLocation = PragmaLoc; 431 } 432 433 void Sema::ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action, 434 StringRef SlotLabel, Expr *alignment) { 435 bool IsXLPragma = getLangOpts().XLPragmaPack; 436 // XL pragma pack does not support identifier syntax. 437 if (IsXLPragma && !SlotLabel.empty()) { 438 Diag(PragmaLoc, diag::err_pragma_pack_identifer_not_supported); 439 return; 440 } 441 442 const AlignPackInfo CurVal = AlignPackStack.CurrentValue; 443 Expr *Alignment = static_cast<Expr *>(alignment); 444 445 // If specified then alignment must be a "small" power of two. 446 unsigned AlignmentVal = 0; 447 AlignPackInfo::Mode ModeVal = CurVal.getAlignMode(); 448 449 if (Alignment) { 450 std::optional<llvm::APSInt> Val; 451 Val = Alignment->getIntegerConstantExpr(Context); 452 453 // pack(0) is like pack(), which just works out since that is what 454 // we use 0 for in PackAttr. 455 if (Alignment->isTypeDependent() || !Val || 456 !(*Val == 0 || Val->isPowerOf2()) || Val->getZExtValue() > 16) { 457 Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment); 458 return; // Ignore 459 } 460 461 if (IsXLPragma && *Val == 0) { 462 // pack(0) does not work out with XL. 463 Diag(PragmaLoc, diag::err_pragma_pack_invalid_alignment); 464 return; // Ignore 465 } 466 467 AlignmentVal = (unsigned)Val->getZExtValue(); 468 } 469 470 if (Action == Sema::PSK_Show) { 471 // Show the current alignment, making sure to show the right value 472 // for the default. 473 // FIXME: This should come from the target. 474 AlignmentVal = CurVal.IsPackSet() ? CurVal.getPackNumber() : 8; 475 if (ModeVal == AlignPackInfo::Mac68k && 476 (IsXLPragma || CurVal.IsAlignAttr())) 477 Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k"; 478 else 479 Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal; 480 } 481 482 // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack: 483 // "#pragma pack(pop, identifier, n) is undefined" 484 if (Action & Sema::PSK_Pop) { 485 if (Alignment && !SlotLabel.empty()) 486 Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifier_and_alignment); 487 if (AlignPackStack.Stack.empty()) { 488 assert(CurVal.getAlignMode() == AlignPackInfo::Native && 489 "Empty pack stack can only be at Native alignment mode."); 490 Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "pack" << "stack empty"; 491 } 492 } 493 494 AlignPackInfo Info(ModeVal, AlignmentVal, IsXLPragma); 495 496 AlignPackStack.Act(PragmaLoc, Action, SlotLabel, Info); 497 } 498 499 bool Sema::ConstantFoldAttrArgs(const AttributeCommonInfo &CI, 500 MutableArrayRef<Expr *> Args) { 501 llvm::SmallVector<PartialDiagnosticAt, 8> Notes; 502 for (unsigned Idx = 0; Idx < Args.size(); Idx++) { 503 Expr *&E = Args.begin()[Idx]; 504 assert(E && "error are handled before"); 505 if (E->isValueDependent() || E->isTypeDependent()) 506 continue; 507 508 // FIXME: Use DefaultFunctionArrayLValueConversion() in place of the logic 509 // that adds implicit casts here. 510 if (E->getType()->isArrayType()) 511 E = ImpCastExprToType(E, Context.getPointerType(E->getType()), 512 clang::CK_ArrayToPointerDecay) 513 .get(); 514 if (E->getType()->isFunctionType()) 515 E = ImplicitCastExpr::Create(Context, 516 Context.getPointerType(E->getType()), 517 clang::CK_FunctionToPointerDecay, E, nullptr, 518 VK_PRValue, FPOptionsOverride()); 519 if (E->isLValue()) 520 E = ImplicitCastExpr::Create(Context, E->getType().getNonReferenceType(), 521 clang::CK_LValueToRValue, E, nullptr, 522 VK_PRValue, FPOptionsOverride()); 523 524 Expr::EvalResult Eval; 525 Notes.clear(); 526 Eval.Diag = &Notes; 527 528 bool Result = E->EvaluateAsConstantExpr(Eval, Context); 529 530 /// Result means the expression can be folded to a constant. 531 /// Note.empty() means the expression is a valid constant expression in the 532 /// current language mode. 533 if (!Result || !Notes.empty()) { 534 Diag(E->getBeginLoc(), diag::err_attribute_argument_n_type) 535 << CI << (Idx + 1) << AANT_ArgumentConstantExpr; 536 for (auto &Note : Notes) 537 Diag(Note.first, Note.second); 538 return false; 539 } 540 assert(Eval.Val.hasValue()); 541 E = ConstantExpr::Create(Context, E, Eval.Val); 542 } 543 544 return true; 545 } 546 547 void Sema::DiagnoseNonDefaultPragmaAlignPack(PragmaAlignPackDiagnoseKind Kind, 548 SourceLocation IncludeLoc) { 549 if (Kind == PragmaAlignPackDiagnoseKind::NonDefaultStateAtInclude) { 550 SourceLocation PrevLocation = AlignPackStack.CurrentPragmaLocation; 551 // Warn about non-default alignment at #includes (without redundant 552 // warnings for the same directive in nested includes). 553 // The warning is delayed until the end of the file to avoid warnings 554 // for files that don't have any records that are affected by the modified 555 // alignment. 556 bool HasNonDefaultValue = 557 AlignPackStack.hasValue() && 558 (AlignPackIncludeStack.empty() || 559 AlignPackIncludeStack.back().CurrentPragmaLocation != PrevLocation); 560 AlignPackIncludeStack.push_back( 561 {AlignPackStack.CurrentValue, 562 AlignPackStack.hasValue() ? PrevLocation : SourceLocation(), 563 HasNonDefaultValue, /*ShouldWarnOnInclude*/ false}); 564 return; 565 } 566 567 assert(Kind == PragmaAlignPackDiagnoseKind::ChangedStateAtExit && 568 "invalid kind"); 569 AlignPackIncludeState PrevAlignPackState = 570 AlignPackIncludeStack.pop_back_val(); 571 // FIXME: AlignPackStack may contain both #pragma align and #pragma pack 572 // information, diagnostics below might not be accurate if we have mixed 573 // pragmas. 574 if (PrevAlignPackState.ShouldWarnOnInclude) { 575 // Emit the delayed non-default alignment at #include warning. 576 Diag(IncludeLoc, diag::warn_pragma_pack_non_default_at_include); 577 Diag(PrevAlignPackState.CurrentPragmaLocation, diag::note_pragma_pack_here); 578 } 579 // Warn about modified alignment after #includes. 580 if (PrevAlignPackState.CurrentValue != AlignPackStack.CurrentValue) { 581 Diag(IncludeLoc, diag::warn_pragma_pack_modified_after_include); 582 Diag(AlignPackStack.CurrentPragmaLocation, diag::note_pragma_pack_here); 583 } 584 } 585 586 void Sema::DiagnoseUnterminatedPragmaAlignPack() { 587 if (AlignPackStack.Stack.empty()) 588 return; 589 bool IsInnermost = true; 590 591 // FIXME: AlignPackStack may contain both #pragma align and #pragma pack 592 // information, diagnostics below might not be accurate if we have mixed 593 // pragmas. 594 for (const auto &StackSlot : llvm::reverse(AlignPackStack.Stack)) { 595 Diag(StackSlot.PragmaPushLocation, diag::warn_pragma_pack_no_pop_eof); 596 // The user might have already reset the alignment, so suggest replacing 597 // the reset with a pop. 598 if (IsInnermost && 599 AlignPackStack.CurrentValue == AlignPackStack.DefaultValue) { 600 auto DB = Diag(AlignPackStack.CurrentPragmaLocation, 601 diag::note_pragma_pack_pop_instead_reset); 602 SourceLocation FixItLoc = 603 Lexer::findLocationAfterToken(AlignPackStack.CurrentPragmaLocation, 604 tok::l_paren, SourceMgr, LangOpts, 605 /*SkipTrailing=*/false); 606 if (FixItLoc.isValid()) 607 DB << FixItHint::CreateInsertion(FixItLoc, "pop"); 608 } 609 IsInnermost = false; 610 } 611 } 612 613 void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) { 614 MSStructPragmaOn = (Kind == PMSST_ON); 615 } 616 617 void Sema::ActOnPragmaMSComment(SourceLocation CommentLoc, 618 PragmaMSCommentKind Kind, StringRef Arg) { 619 auto *PCD = PragmaCommentDecl::Create( 620 Context, Context.getTranslationUnitDecl(), CommentLoc, Kind, Arg); 621 Context.getTranslationUnitDecl()->addDecl(PCD); 622 Consumer.HandleTopLevelDecl(DeclGroupRef(PCD)); 623 } 624 625 void Sema::ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name, 626 StringRef Value) { 627 auto *PDMD = PragmaDetectMismatchDecl::Create( 628 Context, Context.getTranslationUnitDecl(), Loc, Name, Value); 629 Context.getTranslationUnitDecl()->addDecl(PDMD); 630 Consumer.HandleTopLevelDecl(DeclGroupRef(PDMD)); 631 } 632 633 void Sema::ActOnPragmaFPEvalMethod(SourceLocation Loc, 634 LangOptions::FPEvalMethodKind Value) { 635 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides(); 636 switch (Value) { 637 default: 638 llvm_unreachable("invalid pragma eval_method kind"); 639 case LangOptions::FEM_Source: 640 NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Source); 641 break; 642 case LangOptions::FEM_Double: 643 NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Double); 644 break; 645 case LangOptions::FEM_Extended: 646 NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Extended); 647 break; 648 } 649 if (getLangOpts().ApproxFunc) 650 Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context) << 0 << 0; 651 if (getLangOpts().AllowFPReassoc) 652 Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context) << 0 << 1; 653 if (getLangOpts().AllowRecip) 654 Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context) << 0 << 2; 655 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures); 656 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts()); 657 PP.setCurrentFPEvalMethod(Loc, Value); 658 } 659 660 void Sema::ActOnPragmaFloatControl(SourceLocation Loc, 661 PragmaMsStackAction Action, 662 PragmaFloatControlKind Value) { 663 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides(); 664 if ((Action == PSK_Push_Set || Action == PSK_Push || Action == PSK_Pop) && 665 !CurContext->getRedeclContext()->isFileContext()) { 666 // Push and pop can only occur at file or namespace scope, or within a 667 // language linkage declaration. 668 Diag(Loc, diag::err_pragma_fc_pp_scope); 669 return; 670 } 671 switch (Value) { 672 default: 673 llvm_unreachable("invalid pragma float_control kind"); 674 case PFC_Precise: 675 NewFPFeatures.setFPPreciseEnabled(true); 676 FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures); 677 break; 678 case PFC_NoPrecise: 679 if (CurFPFeatures.getExceptionMode() == LangOptions::FPE_Strict) 680 Diag(Loc, diag::err_pragma_fc_noprecise_requires_noexcept); 681 else if (CurFPFeatures.getAllowFEnvAccess()) 682 Diag(Loc, diag::err_pragma_fc_noprecise_requires_nofenv); 683 else 684 NewFPFeatures.setFPPreciseEnabled(false); 685 FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures); 686 break; 687 case PFC_Except: 688 if (!isPreciseFPEnabled()) 689 Diag(Loc, diag::err_pragma_fc_except_requires_precise); 690 else 691 NewFPFeatures.setSpecifiedExceptionModeOverride(LangOptions::FPE_Strict); 692 FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures); 693 break; 694 case PFC_NoExcept: 695 NewFPFeatures.setSpecifiedExceptionModeOverride(LangOptions::FPE_Ignore); 696 FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures); 697 break; 698 case PFC_Push: 699 FpPragmaStack.Act(Loc, Sema::PSK_Push_Set, StringRef(), NewFPFeatures); 700 break; 701 case PFC_Pop: 702 if (FpPragmaStack.Stack.empty()) { 703 Diag(Loc, diag::warn_pragma_pop_failed) << "float_control" 704 << "stack empty"; 705 return; 706 } 707 FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures); 708 NewFPFeatures = FpPragmaStack.CurrentValue; 709 break; 710 } 711 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts()); 712 } 713 714 void Sema::ActOnPragmaMSPointersToMembers( 715 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod, 716 SourceLocation PragmaLoc) { 717 MSPointerToMemberRepresentationMethod = RepresentationMethod; 718 ImplicitMSInheritanceAttrLoc = PragmaLoc; 719 } 720 721 void Sema::ActOnPragmaMSVtorDisp(PragmaMsStackAction Action, 722 SourceLocation PragmaLoc, 723 MSVtorDispMode Mode) { 724 if (Action & PSK_Pop && VtorDispStack.Stack.empty()) 725 Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp" 726 << "stack empty"; 727 VtorDispStack.Act(PragmaLoc, Action, StringRef(), Mode); 728 } 729 730 template <> 731 void Sema::PragmaStack<Sema::AlignPackInfo>::Act(SourceLocation PragmaLocation, 732 PragmaMsStackAction Action, 733 llvm::StringRef StackSlotLabel, 734 AlignPackInfo Value) { 735 if (Action == PSK_Reset) { 736 CurrentValue = DefaultValue; 737 CurrentPragmaLocation = PragmaLocation; 738 return; 739 } 740 if (Action & PSK_Push) 741 Stack.emplace_back(Slot(StackSlotLabel, CurrentValue, CurrentPragmaLocation, 742 PragmaLocation)); 743 else if (Action & PSK_Pop) { 744 if (!StackSlotLabel.empty()) { 745 // If we've got a label, try to find it and jump there. 746 auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) { 747 return x.StackSlotLabel == StackSlotLabel; 748 }); 749 // We found the label, so pop from there. 750 if (I != Stack.rend()) { 751 CurrentValue = I->Value; 752 CurrentPragmaLocation = I->PragmaLocation; 753 Stack.erase(std::prev(I.base()), Stack.end()); 754 } 755 } else if (Value.IsXLStack() && Value.IsAlignAttr() && 756 CurrentValue.IsPackAttr()) { 757 // XL '#pragma align(reset)' would pop the stack until 758 // a current in effect pragma align is popped. 759 auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) { 760 return x.Value.IsAlignAttr(); 761 }); 762 // If we found pragma align so pop from there. 763 if (I != Stack.rend()) { 764 Stack.erase(std::prev(I.base()), Stack.end()); 765 if (Stack.empty()) { 766 CurrentValue = DefaultValue; 767 CurrentPragmaLocation = PragmaLocation; 768 } else { 769 CurrentValue = Stack.back().Value; 770 CurrentPragmaLocation = Stack.back().PragmaLocation; 771 Stack.pop_back(); 772 } 773 } 774 } else if (!Stack.empty()) { 775 // xl '#pragma align' sets the baseline, and `#pragma pack` cannot pop 776 // over the baseline. 777 if (Value.IsXLStack() && Value.IsPackAttr() && CurrentValue.IsAlignAttr()) 778 return; 779 780 // We don't have a label, just pop the last entry. 781 CurrentValue = Stack.back().Value; 782 CurrentPragmaLocation = Stack.back().PragmaLocation; 783 Stack.pop_back(); 784 } 785 } 786 if (Action & PSK_Set) { 787 CurrentValue = Value; 788 CurrentPragmaLocation = PragmaLocation; 789 } 790 } 791 792 bool Sema::UnifySection(StringRef SectionName, int SectionFlags, 793 NamedDecl *Decl) { 794 SourceLocation PragmaLocation; 795 if (auto A = Decl->getAttr<SectionAttr>()) 796 if (A->isImplicit()) 797 PragmaLocation = A->getLocation(); 798 auto [SectionIt, Inserted] = Context.SectionInfos.try_emplace( 799 SectionName, Decl, PragmaLocation, SectionFlags); 800 if (Inserted) 801 return false; 802 // A pre-declared section takes precedence w/o diagnostic. 803 const auto &Section = SectionIt->second; 804 if (Section.SectionFlags == SectionFlags || 805 ((SectionFlags & ASTContext::PSF_Implicit) && 806 !(Section.SectionFlags & ASTContext::PSF_Implicit))) 807 return false; 808 Diag(Decl->getLocation(), diag::err_section_conflict) << Decl << Section; 809 if (Section.Decl) 810 Diag(Section.Decl->getLocation(), diag::note_declared_at) 811 << Section.Decl->getName(); 812 if (PragmaLocation.isValid()) 813 Diag(PragmaLocation, diag::note_pragma_entered_here); 814 if (Section.PragmaSectionLocation.isValid()) 815 Diag(Section.PragmaSectionLocation, diag::note_pragma_entered_here); 816 return true; 817 } 818 819 bool Sema::UnifySection(StringRef SectionName, 820 int SectionFlags, 821 SourceLocation PragmaSectionLocation) { 822 auto SectionIt = Context.SectionInfos.find(SectionName); 823 if (SectionIt != Context.SectionInfos.end()) { 824 const auto &Section = SectionIt->second; 825 if (Section.SectionFlags == SectionFlags) 826 return false; 827 if (!(Section.SectionFlags & ASTContext::PSF_Implicit)) { 828 Diag(PragmaSectionLocation, diag::err_section_conflict) 829 << "this" << Section; 830 if (Section.Decl) 831 Diag(Section.Decl->getLocation(), diag::note_declared_at) 832 << Section.Decl->getName(); 833 if (Section.PragmaSectionLocation.isValid()) 834 Diag(Section.PragmaSectionLocation, diag::note_pragma_entered_here); 835 return true; 836 } 837 } 838 Context.SectionInfos[SectionName] = 839 ASTContext::SectionInfo(nullptr, PragmaSectionLocation, SectionFlags); 840 return false; 841 } 842 843 /// Called on well formed \#pragma bss_seg(). 844 void Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation, 845 PragmaMsStackAction Action, 846 llvm::StringRef StackSlotLabel, 847 StringLiteral *SegmentName, 848 llvm::StringRef PragmaName) { 849 PragmaStack<StringLiteral *> *Stack = 850 llvm::StringSwitch<PragmaStack<StringLiteral *> *>(PragmaName) 851 .Case("data_seg", &DataSegStack) 852 .Case("bss_seg", &BSSSegStack) 853 .Case("const_seg", &ConstSegStack) 854 .Case("code_seg", &CodeSegStack); 855 if (Action & PSK_Pop && Stack->Stack.empty()) 856 Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName 857 << "stack empty"; 858 if (SegmentName) { 859 if (!checkSectionName(SegmentName->getBeginLoc(), SegmentName->getString())) 860 return; 861 862 if (SegmentName->getString() == ".drectve" && 863 Context.getTargetInfo().getCXXABI().isMicrosoft()) 864 Diag(PragmaLocation, diag::warn_attribute_section_drectve) << PragmaName; 865 } 866 867 Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName); 868 } 869 870 /// Called on well formed \#pragma strict_gs_check(). 871 void Sema::ActOnPragmaMSStrictGuardStackCheck(SourceLocation PragmaLocation, 872 PragmaMsStackAction Action, 873 bool Value) { 874 if (Action & PSK_Pop && StrictGuardStackCheckStack.Stack.empty()) 875 Diag(PragmaLocation, diag::warn_pragma_pop_failed) << "strict_gs_check" 876 << "stack empty"; 877 878 StrictGuardStackCheckStack.Act(PragmaLocation, Action, StringRef(), Value); 879 } 880 881 /// Called on well formed \#pragma bss_seg(). 882 void Sema::ActOnPragmaMSSection(SourceLocation PragmaLocation, 883 int SectionFlags, StringLiteral *SegmentName) { 884 UnifySection(SegmentName->getString(), SectionFlags, PragmaLocation); 885 } 886 887 void Sema::ActOnPragmaMSInitSeg(SourceLocation PragmaLocation, 888 StringLiteral *SegmentName) { 889 // There's no stack to maintain, so we just have a current section. When we 890 // see the default section, reset our current section back to null so we stop 891 // tacking on unnecessary attributes. 892 CurInitSeg = SegmentName->getString() == ".CRT$XCU" ? nullptr : SegmentName; 893 CurInitSegLoc = PragmaLocation; 894 } 895 896 void Sema::ActOnPragmaMSAllocText( 897 SourceLocation PragmaLocation, StringRef Section, 898 const SmallVector<std::tuple<IdentifierInfo *, SourceLocation>> 899 &Functions) { 900 if (!CurContext->getRedeclContext()->isFileContext()) { 901 Diag(PragmaLocation, diag::err_pragma_expected_file_scope) << "alloc_text"; 902 return; 903 } 904 905 for (auto &Function : Functions) { 906 IdentifierInfo *II; 907 SourceLocation Loc; 908 std::tie(II, Loc) = Function; 909 910 DeclarationName DN(II); 911 NamedDecl *ND = LookupSingleName(TUScope, DN, Loc, LookupOrdinaryName); 912 if (!ND) { 913 Diag(Loc, diag::err_undeclared_use) << II->getName(); 914 return; 915 } 916 917 auto *FD = dyn_cast<FunctionDecl>(ND->getCanonicalDecl()); 918 if (!FD) { 919 Diag(Loc, diag::err_pragma_alloc_text_not_function); 920 return; 921 } 922 923 if (getLangOpts().CPlusPlus && !FD->isInExternCContext()) { 924 Diag(Loc, diag::err_pragma_alloc_text_c_linkage); 925 return; 926 } 927 928 FunctionToSectionMap[II->getName()] = std::make_tuple(Section, Loc); 929 } 930 } 931 932 void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope, 933 SourceLocation PragmaLoc) { 934 935 IdentifierInfo *Name = IdTok.getIdentifierInfo(); 936 LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName); 937 LookupName(Lookup, curScope, /*AllowBuiltinCreation=*/true); 938 939 if (Lookup.empty()) { 940 Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var) 941 << Name << SourceRange(IdTok.getLocation()); 942 return; 943 } 944 945 VarDecl *VD = Lookup.getAsSingle<VarDecl>(); 946 if (!VD) { 947 Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg) 948 << Name << SourceRange(IdTok.getLocation()); 949 return; 950 } 951 952 // Warn if this was used before being marked unused. 953 if (VD->isUsed()) 954 Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name; 955 956 VD->addAttr(UnusedAttr::CreateImplicit(Context, IdTok.getLocation(), 957 UnusedAttr::GNU_unused)); 958 } 959 960 namespace { 961 962 std::optional<attr::SubjectMatchRule> 963 getParentAttrMatcherRule(attr::SubjectMatchRule Rule) { 964 using namespace attr; 965 switch (Rule) { 966 default: 967 return std::nullopt; 968 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) 969 #define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \ 970 case Value: \ 971 return Parent; 972 #include "clang/Basic/AttrSubMatchRulesList.inc" 973 } 974 } 975 976 bool isNegatedAttrMatcherSubRule(attr::SubjectMatchRule Rule) { 977 using namespace attr; 978 switch (Rule) { 979 default: 980 return false; 981 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) 982 #define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \ 983 case Value: \ 984 return IsNegated; 985 #include "clang/Basic/AttrSubMatchRulesList.inc" 986 } 987 } 988 989 CharSourceRange replacementRangeForListElement(const Sema &S, 990 SourceRange Range) { 991 // Make sure that the ',' is removed as well. 992 SourceLocation AfterCommaLoc = Lexer::findLocationAfterToken( 993 Range.getEnd(), tok::comma, S.getSourceManager(), S.getLangOpts(), 994 /*SkipTrailingWhitespaceAndNewLine=*/false); 995 if (AfterCommaLoc.isValid()) 996 return CharSourceRange::getCharRange(Range.getBegin(), AfterCommaLoc); 997 else 998 return CharSourceRange::getTokenRange(Range); 999 } 1000 1001 std::string 1002 attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) { 1003 std::string Result; 1004 llvm::raw_string_ostream OS(Result); 1005 for (const auto &I : llvm::enumerate(Rules)) { 1006 if (I.index()) 1007 OS << (I.index() == Rules.size() - 1 ? ", and " : ", "); 1008 OS << "'" << attr::getSubjectMatchRuleSpelling(I.value()) << "'"; 1009 } 1010 return Result; 1011 } 1012 1013 } // end anonymous namespace 1014 1015 void Sema::ActOnPragmaAttributeAttribute( 1016 ParsedAttr &Attribute, SourceLocation PragmaLoc, 1017 attr::ParsedSubjectMatchRuleSet Rules) { 1018 Attribute.setIsPragmaClangAttribute(); 1019 SmallVector<attr::SubjectMatchRule, 4> SubjectMatchRules; 1020 // Gather the subject match rules that are supported by the attribute. 1021 SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4> 1022 StrictSubjectMatchRuleSet; 1023 Attribute.getMatchRules(LangOpts, StrictSubjectMatchRuleSet); 1024 1025 // Figure out which subject matching rules are valid. 1026 if (StrictSubjectMatchRuleSet.empty()) { 1027 // Check for contradicting match rules. Contradicting match rules are 1028 // either: 1029 // - a top-level rule and one of its sub-rules. E.g. variable and 1030 // variable(is_parameter). 1031 // - a sub-rule and a sibling that's negated. E.g. 1032 // variable(is_thread_local) and variable(unless(is_parameter)) 1033 llvm::SmallDenseMap<int, std::pair<int, SourceRange>, 2> 1034 RulesToFirstSpecifiedNegatedSubRule; 1035 for (const auto &Rule : Rules) { 1036 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first); 1037 std::optional<attr::SubjectMatchRule> ParentRule = 1038 getParentAttrMatcherRule(MatchRule); 1039 if (!ParentRule) 1040 continue; 1041 auto It = Rules.find(*ParentRule); 1042 if (It != Rules.end()) { 1043 // A sub-rule contradicts a parent rule. 1044 Diag(Rule.second.getBegin(), 1045 diag::err_pragma_attribute_matcher_subrule_contradicts_rule) 1046 << attr::getSubjectMatchRuleSpelling(MatchRule) 1047 << attr::getSubjectMatchRuleSpelling(*ParentRule) << It->second 1048 << FixItHint::CreateRemoval( 1049 replacementRangeForListElement(*this, Rule.second)); 1050 // Keep going without removing this rule as it won't change the set of 1051 // declarations that receive the attribute. 1052 continue; 1053 } 1054 if (isNegatedAttrMatcherSubRule(MatchRule)) 1055 RulesToFirstSpecifiedNegatedSubRule.insert( 1056 std::make_pair(*ParentRule, Rule)); 1057 } 1058 bool IgnoreNegatedSubRules = false; 1059 for (const auto &Rule : Rules) { 1060 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first); 1061 std::optional<attr::SubjectMatchRule> ParentRule = 1062 getParentAttrMatcherRule(MatchRule); 1063 if (!ParentRule) 1064 continue; 1065 auto It = RulesToFirstSpecifiedNegatedSubRule.find(*ParentRule); 1066 if (It != RulesToFirstSpecifiedNegatedSubRule.end() && 1067 It->second != Rule) { 1068 // Negated sub-rule contradicts another sub-rule. 1069 Diag( 1070 It->second.second.getBegin(), 1071 diag:: 1072 err_pragma_attribute_matcher_negated_subrule_contradicts_subrule) 1073 << attr::getSubjectMatchRuleSpelling( 1074 attr::SubjectMatchRule(It->second.first)) 1075 << attr::getSubjectMatchRuleSpelling(MatchRule) << Rule.second 1076 << FixItHint::CreateRemoval( 1077 replacementRangeForListElement(*this, It->second.second)); 1078 // Keep going but ignore all of the negated sub-rules. 1079 IgnoreNegatedSubRules = true; 1080 RulesToFirstSpecifiedNegatedSubRule.erase(It); 1081 } 1082 } 1083 1084 if (!IgnoreNegatedSubRules) { 1085 for (const auto &Rule : Rules) 1086 SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first)); 1087 } else { 1088 for (const auto &Rule : Rules) { 1089 if (!isNegatedAttrMatcherSubRule(attr::SubjectMatchRule(Rule.first))) 1090 SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first)); 1091 } 1092 } 1093 Rules.clear(); 1094 } else { 1095 // Each rule in Rules must be a strict subset of the attribute's 1096 // SubjectMatch rules. I.e. we're allowed to use 1097 // `apply_to=variables(is_global)` on an attrubute with SubjectList<[Var]>, 1098 // but should not allow `apply_to=variables` on an attribute which has 1099 // `SubjectList<[GlobalVar]>`. 1100 for (const auto &StrictRule : StrictSubjectMatchRuleSet) { 1101 // First, check for exact match. 1102 if (Rules.erase(StrictRule.first)) { 1103 // Add the rule to the set of attribute receivers only if it's supported 1104 // in the current language mode. 1105 if (StrictRule.second) 1106 SubjectMatchRules.push_back(StrictRule.first); 1107 } 1108 } 1109 // Check remaining rules for subset matches. 1110 auto RulesToCheck = Rules; 1111 for (const auto &Rule : RulesToCheck) { 1112 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first); 1113 if (auto ParentRule = getParentAttrMatcherRule(MatchRule)) { 1114 if (llvm::any_of(StrictSubjectMatchRuleSet, 1115 [ParentRule](const auto &StrictRule) { 1116 return StrictRule.first == *ParentRule && 1117 StrictRule.second; // IsEnabled 1118 })) { 1119 SubjectMatchRules.push_back(MatchRule); 1120 Rules.erase(MatchRule); 1121 } 1122 } 1123 } 1124 } 1125 1126 if (!Rules.empty()) { 1127 auto Diagnostic = 1128 Diag(PragmaLoc, diag::err_pragma_attribute_invalid_matchers) 1129 << Attribute; 1130 SmallVector<attr::SubjectMatchRule, 2> ExtraRules; 1131 for (const auto &Rule : Rules) { 1132 ExtraRules.push_back(attr::SubjectMatchRule(Rule.first)); 1133 Diagnostic << FixItHint::CreateRemoval( 1134 replacementRangeForListElement(*this, Rule.second)); 1135 } 1136 Diagnostic << attrMatcherRuleListToString(ExtraRules); 1137 } 1138 1139 if (PragmaAttributeStack.empty()) { 1140 Diag(PragmaLoc, diag::err_pragma_attr_attr_no_push); 1141 return; 1142 } 1143 1144 PragmaAttributeStack.back().Entries.push_back( 1145 {PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false}); 1146 } 1147 1148 void Sema::ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc, 1149 const IdentifierInfo *Namespace) { 1150 PragmaAttributeStack.emplace_back(); 1151 PragmaAttributeStack.back().Loc = PragmaLoc; 1152 PragmaAttributeStack.back().Namespace = Namespace; 1153 } 1154 1155 void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc, 1156 const IdentifierInfo *Namespace) { 1157 if (PragmaAttributeStack.empty()) { 1158 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1; 1159 return; 1160 } 1161 1162 // Dig back through the stack trying to find the most recently pushed group 1163 // that in Namespace. Note that this works fine if no namespace is present, 1164 // think of push/pops without namespaces as having an implicit "nullptr" 1165 // namespace. 1166 for (size_t Index = PragmaAttributeStack.size(); Index;) { 1167 --Index; 1168 if (PragmaAttributeStack[Index].Namespace == Namespace) { 1169 for (const PragmaAttributeEntry &Entry : 1170 PragmaAttributeStack[Index].Entries) { 1171 if (!Entry.IsUsed) { 1172 assert(Entry.Attribute && "Expected an attribute"); 1173 Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused) 1174 << *Entry.Attribute; 1175 Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here); 1176 } 1177 } 1178 PragmaAttributeStack.erase(PragmaAttributeStack.begin() + Index); 1179 return; 1180 } 1181 } 1182 1183 if (Namespace) 1184 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) 1185 << 0 << Namespace->getName(); 1186 else 1187 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1; 1188 } 1189 1190 void Sema::AddPragmaAttributes(Scope *S, Decl *D) { 1191 if (PragmaAttributeStack.empty()) 1192 return; 1193 for (auto &Group : PragmaAttributeStack) { 1194 for (auto &Entry : Group.Entries) { 1195 ParsedAttr *Attribute = Entry.Attribute; 1196 assert(Attribute && "Expected an attribute"); 1197 assert(Attribute->isPragmaClangAttribute() && 1198 "expected #pragma clang attribute"); 1199 1200 // Ensure that the attribute can be applied to the given declaration. 1201 bool Applies = false; 1202 for (const auto &Rule : Entry.MatchRules) { 1203 if (Attribute->appliesToDecl(D, Rule)) { 1204 Applies = true; 1205 break; 1206 } 1207 } 1208 if (!Applies) 1209 continue; 1210 Entry.IsUsed = true; 1211 PragmaAttributeCurrentTargetDecl = D; 1212 ParsedAttributesView Attrs; 1213 Attrs.addAtEnd(Attribute); 1214 ProcessDeclAttributeList(S, D, Attrs); 1215 PragmaAttributeCurrentTargetDecl = nullptr; 1216 } 1217 } 1218 } 1219 1220 void Sema::PrintPragmaAttributeInstantiationPoint() { 1221 assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration"); 1222 Diags.Report(PragmaAttributeCurrentTargetDecl->getBeginLoc(), 1223 diag::note_pragma_attribute_applied_decl_here); 1224 } 1225 1226 void Sema::DiagnosePrecisionLossInComplexDivision() { 1227 for (auto &[Type, Num] : ExcessPrecisionNotSatisfied) { 1228 assert(LocationOfExcessPrecisionNotSatisfied.isValid() && 1229 "expected a valid source location"); 1230 Diag(LocationOfExcessPrecisionNotSatisfied, 1231 diag::warn_excess_precision_not_supported) 1232 << static_cast<bool>(Num); 1233 } 1234 } 1235 1236 void Sema::DiagnoseUnterminatedPragmaAttribute() { 1237 if (PragmaAttributeStack.empty()) 1238 return; 1239 Diag(PragmaAttributeStack.back().Loc, diag::err_pragma_attribute_no_pop_eof); 1240 } 1241 1242 void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) { 1243 if(On) 1244 OptimizeOffPragmaLocation = SourceLocation(); 1245 else 1246 OptimizeOffPragmaLocation = PragmaLoc; 1247 } 1248 1249 void Sema::ActOnPragmaMSOptimize(SourceLocation Loc, bool IsOn) { 1250 if (!CurContext->getRedeclContext()->isFileContext()) { 1251 Diag(Loc, diag::err_pragma_expected_file_scope) << "optimize"; 1252 return; 1253 } 1254 1255 MSPragmaOptimizeIsOn = IsOn; 1256 } 1257 1258 void Sema::ActOnPragmaMSFunction( 1259 SourceLocation Loc, const llvm::SmallVectorImpl<StringRef> &NoBuiltins) { 1260 if (!CurContext->getRedeclContext()->isFileContext()) { 1261 Diag(Loc, diag::err_pragma_expected_file_scope) << "function"; 1262 return; 1263 } 1264 1265 MSFunctionNoBuiltins.insert(NoBuiltins.begin(), NoBuiltins.end()); 1266 } 1267 1268 void Sema::AddRangeBasedOptnone(FunctionDecl *FD) { 1269 // In the future, check other pragmas if they're implemented (e.g. pragma 1270 // optimize 0 will probably map to this functionality too). 1271 if(OptimizeOffPragmaLocation.isValid()) 1272 AddOptnoneAttributeIfNoConflicts(FD, OptimizeOffPragmaLocation); 1273 } 1274 1275 void Sema::AddSectionMSAllocText(FunctionDecl *FD) { 1276 if (!FD->getIdentifier()) 1277 return; 1278 1279 StringRef Name = FD->getName(); 1280 auto It = FunctionToSectionMap.find(Name); 1281 if (It != FunctionToSectionMap.end()) { 1282 StringRef Section; 1283 SourceLocation Loc; 1284 std::tie(Section, Loc) = It->second; 1285 1286 if (!FD->hasAttr<SectionAttr>()) 1287 FD->addAttr(SectionAttr::CreateImplicit(Context, Section)); 1288 } 1289 } 1290 1291 void Sema::ModifyFnAttributesMSPragmaOptimize(FunctionDecl *FD) { 1292 // Don't modify the function attributes if it's "on". "on" resets the 1293 // optimizations to the ones listed on the command line 1294 if (!MSPragmaOptimizeIsOn) 1295 AddOptnoneAttributeIfNoConflicts(FD, FD->getBeginLoc()); 1296 } 1297 1298 void Sema::AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, 1299 SourceLocation Loc) { 1300 // Don't add a conflicting attribute. No diagnostic is needed. 1301 if (FD->hasAttr<MinSizeAttr>() || FD->hasAttr<AlwaysInlineAttr>()) 1302 return; 1303 1304 // Add attributes only if required. Optnone requires noinline as well, but if 1305 // either is already present then don't bother adding them. 1306 if (!FD->hasAttr<OptimizeNoneAttr>()) 1307 FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc)); 1308 if (!FD->hasAttr<NoInlineAttr>()) 1309 FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc)); 1310 } 1311 1312 void Sema::AddImplicitMSFunctionNoBuiltinAttr(FunctionDecl *FD) { 1313 if (FD->isDeleted() || FD->isDefaulted()) 1314 return; 1315 SmallVector<StringRef> V(MSFunctionNoBuiltins.begin(), 1316 MSFunctionNoBuiltins.end()); 1317 if (!MSFunctionNoBuiltins.empty()) 1318 FD->addAttr(NoBuiltinAttr::CreateImplicit(Context, V.data(), V.size())); 1319 } 1320 1321 typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack; 1322 enum : unsigned { NoVisibility = ~0U }; 1323 1324 void Sema::AddPushedVisibilityAttribute(Decl *D) { 1325 if (!VisContext) 1326 return; 1327 1328 NamedDecl *ND = dyn_cast<NamedDecl>(D); 1329 if (ND && ND->getExplicitVisibility(NamedDecl::VisibilityForValue)) 1330 return; 1331 1332 VisStack *Stack = static_cast<VisStack*>(VisContext); 1333 unsigned rawType = Stack->back().first; 1334 if (rawType == NoVisibility) return; 1335 1336 VisibilityAttr::VisibilityType type 1337 = (VisibilityAttr::VisibilityType) rawType; 1338 SourceLocation loc = Stack->back().second; 1339 1340 D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc)); 1341 } 1342 1343 void Sema::FreeVisContext() { 1344 delete static_cast<VisStack*>(VisContext); 1345 VisContext = nullptr; 1346 } 1347 1348 static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) { 1349 // Put visibility on stack. 1350 if (!S.VisContext) 1351 S.VisContext = new VisStack; 1352 1353 VisStack *Stack = static_cast<VisStack*>(S.VisContext); 1354 Stack->push_back(std::make_pair(type, loc)); 1355 } 1356 1357 void Sema::ActOnPragmaVisibility(const IdentifierInfo* VisType, 1358 SourceLocation PragmaLoc) { 1359 if (VisType) { 1360 // Compute visibility to use. 1361 VisibilityAttr::VisibilityType T; 1362 if (!VisibilityAttr::ConvertStrToVisibilityType(VisType->getName(), T)) { 1363 Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << VisType; 1364 return; 1365 } 1366 PushPragmaVisibility(*this, T, PragmaLoc); 1367 } else { 1368 PopPragmaVisibility(false, PragmaLoc); 1369 } 1370 } 1371 1372 void Sema::ActOnPragmaFPContract(SourceLocation Loc, 1373 LangOptions::FPModeKind FPC) { 1374 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides(); 1375 switch (FPC) { 1376 case LangOptions::FPM_On: 1377 NewFPFeatures.setAllowFPContractWithinStatement(); 1378 break; 1379 case LangOptions::FPM_Fast: 1380 case LangOptions::FPM_FastHonorPragmas: 1381 NewFPFeatures.setAllowFPContractAcrossStatement(); 1382 break; 1383 case LangOptions::FPM_Off: 1384 NewFPFeatures.setDisallowFPContract(); 1385 break; 1386 } 1387 FpPragmaStack.Act(Loc, Sema::PSK_Set, StringRef(), NewFPFeatures); 1388 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts()); 1389 } 1390 1391 void Sema::ActOnPragmaFPValueChangingOption(SourceLocation Loc, 1392 PragmaFPKind Kind, bool IsEnabled) { 1393 if (IsEnabled) { 1394 // For value unsafe context, combining this pragma with eval method 1395 // setting is not recommended. See comment in function FixupInvocation#506. 1396 int Reason = -1; 1397 if (getLangOpts().getFPEvalMethod() != LangOptions::FEM_UnsetOnCommandLine) 1398 // Eval method set using the option 'ffp-eval-method'. 1399 Reason = 1; 1400 if (PP.getLastFPEvalPragmaLocation().isValid()) 1401 // Eval method set using the '#pragma clang fp eval_method'. 1402 // We could have both an option and a pragma used to the set the eval 1403 // method. The pragma overrides the option in the command line. The Reason 1404 // of the diagnostic is overriden too. 1405 Reason = 0; 1406 if (Reason != -1) 1407 Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context) 1408 << Reason << (Kind == PFK_Reassociate ? 4 : 5); 1409 } 1410 1411 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides(); 1412 switch (Kind) { 1413 case PFK_Reassociate: 1414 NewFPFeatures.setAllowFPReassociateOverride(IsEnabled); 1415 break; 1416 case PFK_Reciprocal: 1417 NewFPFeatures.setAllowReciprocalOverride(IsEnabled); 1418 break; 1419 default: 1420 llvm_unreachable("unhandled value changing pragma fp"); 1421 } 1422 1423 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures); 1424 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts()); 1425 } 1426 1427 void Sema::ActOnPragmaFEnvRound(SourceLocation Loc, llvm::RoundingMode FPR) { 1428 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides(); 1429 NewFPFeatures.setConstRoundingModeOverride(FPR); 1430 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures); 1431 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts()); 1432 } 1433 1434 void Sema::setExceptionMode(SourceLocation Loc, 1435 LangOptions::FPExceptionModeKind FPE) { 1436 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides(); 1437 NewFPFeatures.setSpecifiedExceptionModeOverride(FPE); 1438 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures); 1439 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts()); 1440 } 1441 1442 void Sema::ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled) { 1443 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides(); 1444 if (IsEnabled) { 1445 // Verify Microsoft restriction: 1446 // You can't enable fenv_access unless precise semantics are enabled. 1447 // Precise semantics can be enabled either by the float_control 1448 // pragma, or by using the /fp:precise or /fp:strict compiler options 1449 if (!isPreciseFPEnabled()) 1450 Diag(Loc, diag::err_pragma_fenv_requires_precise); 1451 } 1452 NewFPFeatures.setAllowFEnvAccessOverride(IsEnabled); 1453 NewFPFeatures.setRoundingMathOverride(IsEnabled); 1454 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures); 1455 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts()); 1456 } 1457 1458 void Sema::ActOnPragmaCXLimitedRange(SourceLocation Loc, 1459 LangOptions::ComplexRangeKind Range) { 1460 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides(); 1461 NewFPFeatures.setComplexRangeOverride(Range); 1462 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures); 1463 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts()); 1464 } 1465 1466 void Sema::ActOnPragmaFPExceptions(SourceLocation Loc, 1467 LangOptions::FPExceptionModeKind FPE) { 1468 setExceptionMode(Loc, FPE); 1469 } 1470 1471 void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr, 1472 SourceLocation Loc) { 1473 // Visibility calculations will consider the namespace's visibility. 1474 // Here we just want to note that we're in a visibility context 1475 // which overrides any enclosing #pragma context, but doesn't itself 1476 // contribute visibility. 1477 PushPragmaVisibility(*this, NoVisibility, Loc); 1478 } 1479 1480 void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) { 1481 if (!VisContext) { 1482 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch); 1483 return; 1484 } 1485 1486 // Pop visibility from stack 1487 VisStack *Stack = static_cast<VisStack*>(VisContext); 1488 1489 const std::pair<unsigned, SourceLocation> *Back = &Stack->back(); 1490 bool StartsWithPragma = Back->first != NoVisibility; 1491 if (StartsWithPragma && IsNamespaceEnd) { 1492 Diag(Back->second, diag::err_pragma_push_visibility_mismatch); 1493 Diag(EndLoc, diag::note_surrounding_namespace_ends_here); 1494 1495 // For better error recovery, eat all pushes inside the namespace. 1496 do { 1497 Stack->pop_back(); 1498 Back = &Stack->back(); 1499 StartsWithPragma = Back->first != NoVisibility; 1500 } while (StartsWithPragma); 1501 } else if (!StartsWithPragma && !IsNamespaceEnd) { 1502 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch); 1503 Diag(Back->second, diag::note_surrounding_namespace_starts_here); 1504 return; 1505 } 1506 1507 Stack->pop_back(); 1508 // To simplify the implementation, never keep around an empty stack. 1509 if (Stack->empty()) 1510 FreeVisContext(); 1511 } 1512 1513 template <typename Ty> 1514 static bool checkCommonAttributeFeatures(Sema &S, const Ty *Node, 1515 const ParsedAttr &A, 1516 bool SkipArgCountCheck) { 1517 // Several attributes carry different semantics than the parsing requires, so 1518 // those are opted out of the common argument checks. 1519 // 1520 // We also bail on unknown and ignored attributes because those are handled 1521 // as part of the target-specific handling logic. 1522 if (A.getKind() == ParsedAttr::UnknownAttribute) 1523 return false; 1524 // Check whether the attribute requires specific language extensions to be 1525 // enabled. 1526 if (!A.diagnoseLangOpts(S)) 1527 return true; 1528 // Check whether the attribute appertains to the given subject. 1529 if (!A.diagnoseAppertainsTo(S, Node)) 1530 return true; 1531 // Check whether the attribute is mutually exclusive with other attributes 1532 // that have already been applied to the declaration. 1533 if (!A.diagnoseMutualExclusion(S, Node)) 1534 return true; 1535 // Check whether the attribute exists in the target architecture. 1536 if (S.CheckAttrTarget(A)) 1537 return true; 1538 1539 if (A.hasCustomParsing()) 1540 return false; 1541 1542 if (!SkipArgCountCheck) { 1543 if (A.getMinArgs() == A.getMaxArgs()) { 1544 // If there are no optional arguments, then checking for the argument 1545 // count is trivial. 1546 if (!A.checkExactlyNumArgs(S, A.getMinArgs())) 1547 return true; 1548 } else { 1549 // There are optional arguments, so checking is slightly more involved. 1550 if (A.getMinArgs() && !A.checkAtLeastNumArgs(S, A.getMinArgs())) 1551 return true; 1552 else if (!A.hasVariadicArg() && A.getMaxArgs() && 1553 !A.checkAtMostNumArgs(S, A.getMaxArgs())) 1554 return true; 1555 } 1556 } 1557 1558 return false; 1559 } 1560 1561 bool Sema::checkCommonAttributeFeatures(const Decl *D, const ParsedAttr &A, 1562 bool SkipArgCountCheck) { 1563 return ::checkCommonAttributeFeatures(*this, D, A, SkipArgCountCheck); 1564 } 1565 bool Sema::checkCommonAttributeFeatures(const Stmt *S, const ParsedAttr &A, 1566 bool SkipArgCountCheck) { 1567 return ::checkCommonAttributeFeatures(*this, S, A, SkipArgCountCheck); 1568 } 1569