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 "clang/AST/ASTConsumer.h" 15 #include "clang/AST/Attr.h" 16 #include "clang/AST/Expr.h" 17 #include "clang/Basic/TargetInfo.h" 18 #include "clang/Lex/Preprocessor.h" 19 #include "clang/Sema/Lookup.h" 20 #include "clang/Sema/SemaInternal.h" 21 using namespace clang; 22 23 //===----------------------------------------------------------------------===// 24 // Pragma 'pack' and 'options align' 25 //===----------------------------------------------------------------------===// 26 27 Sema::PragmaStackSentinelRAII::PragmaStackSentinelRAII(Sema &S, 28 StringRef SlotLabel, 29 bool ShouldAct) 30 : S(S), SlotLabel(SlotLabel), ShouldAct(ShouldAct) { 31 if (ShouldAct) { 32 S.VtorDispStack.SentinelAction(PSK_Push, SlotLabel); 33 S.DataSegStack.SentinelAction(PSK_Push, SlotLabel); 34 S.BSSSegStack.SentinelAction(PSK_Push, SlotLabel); 35 S.ConstSegStack.SentinelAction(PSK_Push, SlotLabel); 36 S.CodeSegStack.SentinelAction(PSK_Push, SlotLabel); 37 } 38 } 39 40 Sema::PragmaStackSentinelRAII::~PragmaStackSentinelRAII() { 41 if (ShouldAct) { 42 S.VtorDispStack.SentinelAction(PSK_Pop, SlotLabel); 43 S.DataSegStack.SentinelAction(PSK_Pop, SlotLabel); 44 S.BSSSegStack.SentinelAction(PSK_Pop, SlotLabel); 45 S.ConstSegStack.SentinelAction(PSK_Pop, SlotLabel); 46 S.CodeSegStack.SentinelAction(PSK_Pop, SlotLabel); 47 } 48 } 49 50 void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) { 51 // If there is no pack value, we don't need any attributes. 52 if (!PackStack.CurrentValue) 53 return; 54 55 // Otherwise, check to see if we need a max field alignment attribute. 56 if (unsigned Alignment = PackStack.CurrentValue) { 57 if (Alignment == Sema::kMac68kAlignmentSentinel) 58 RD->addAttr(AlignMac68kAttr::CreateImplicit(Context)); 59 else 60 RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(Context, 61 Alignment * 8)); 62 } 63 if (PackIncludeStack.empty()) 64 return; 65 // The #pragma pack affected a record in an included file, so Clang should 66 // warn when that pragma was written in a file that included the included 67 // file. 68 for (auto &PackedInclude : llvm::reverse(PackIncludeStack)) { 69 if (PackedInclude.CurrentPragmaLocation != PackStack.CurrentPragmaLocation) 70 break; 71 if (PackedInclude.HasNonDefaultValue) 72 PackedInclude.ShouldWarnOnInclude = true; 73 } 74 } 75 76 void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) { 77 if (MSStructPragmaOn) 78 RD->addAttr(MSStructAttr::CreateImplicit(Context)); 79 80 // FIXME: We should merge AddAlignmentAttributesForRecord with 81 // AddMsStructLayoutForRecord into AddPragmaAttributesForRecord, which takes 82 // all active pragmas and applies them as attributes to class definitions. 83 if (VtorDispStack.CurrentValue != getLangOpts().VtorDispMode) 84 RD->addAttr( 85 MSVtorDispAttr::CreateImplicit(Context, VtorDispStack.CurrentValue)); 86 } 87 88 template <typename Attribute> 89 static void addGslOwnerPointerAttributeIfNotExisting(ASTContext &Context, 90 CXXRecordDecl *Record) { 91 if (Record->hasAttr<OwnerAttr>() || Record->hasAttr<PointerAttr>()) 92 return; 93 94 for (Decl *Redecl : Record->redecls()) 95 Redecl->addAttr(Attribute::CreateImplicit(Context, /*DerefType=*/nullptr)); 96 } 97 98 void Sema::inferGslPointerAttribute(NamedDecl *ND, 99 CXXRecordDecl *UnderlyingRecord) { 100 if (!UnderlyingRecord) 101 return; 102 103 const auto *Parent = dyn_cast<CXXRecordDecl>(ND->getDeclContext()); 104 if (!Parent) 105 return; 106 107 static llvm::StringSet<> Containers{ 108 "array", 109 "basic_string", 110 "deque", 111 "forward_list", 112 "vector", 113 "list", 114 "map", 115 "multiset", 116 "multimap", 117 "priority_queue", 118 "queue", 119 "set", 120 "stack", 121 "unordered_set", 122 "unordered_map", 123 "unordered_multiset", 124 "unordered_multimap", 125 }; 126 127 static llvm::StringSet<> Iterators{"iterator", "const_iterator", 128 "reverse_iterator", 129 "const_reverse_iterator"}; 130 131 if (Parent->isInStdNamespace() && Iterators.count(ND->getName()) && 132 Containers.count(Parent->getName())) 133 addGslOwnerPointerAttributeIfNotExisting<PointerAttr>(Context, 134 UnderlyingRecord); 135 } 136 137 void Sema::inferGslPointerAttribute(TypedefNameDecl *TD) { 138 139 QualType Canonical = TD->getUnderlyingType().getCanonicalType(); 140 141 CXXRecordDecl *RD = Canonical->getAsCXXRecordDecl(); 142 if (!RD) { 143 if (auto *TST = 144 dyn_cast<TemplateSpecializationType>(Canonical.getTypePtr())) { 145 146 RD = dyn_cast_or_null<CXXRecordDecl>( 147 TST->getTemplateName().getAsTemplateDecl()->getTemplatedDecl()); 148 } 149 } 150 151 inferGslPointerAttribute(TD, RD); 152 } 153 154 void Sema::inferGslOwnerPointerAttribute(CXXRecordDecl *Record) { 155 static llvm::StringSet<> StdOwners{ 156 "any", 157 "array", 158 "basic_regex", 159 "basic_string", 160 "deque", 161 "forward_list", 162 "vector", 163 "list", 164 "map", 165 "multiset", 166 "multimap", 167 "optional", 168 "priority_queue", 169 "queue", 170 "set", 171 "stack", 172 "unique_ptr", 173 "unordered_set", 174 "unordered_map", 175 "unordered_multiset", 176 "unordered_multimap", 177 "variant", 178 }; 179 static llvm::StringSet<> StdPointers{ 180 "basic_string_view", 181 "reference_wrapper", 182 "regex_iterator", 183 }; 184 185 if (!Record->getIdentifier()) 186 return; 187 188 // Handle classes that directly appear in std namespace. 189 if (Record->isInStdNamespace()) { 190 if (Record->hasAttr<OwnerAttr>() || Record->hasAttr<PointerAttr>()) 191 return; 192 193 if (StdOwners.count(Record->getName())) 194 addGslOwnerPointerAttributeIfNotExisting<OwnerAttr>(Context, Record); 195 else if (StdPointers.count(Record->getName())) 196 addGslOwnerPointerAttributeIfNotExisting<PointerAttr>(Context, Record); 197 198 return; 199 } 200 201 // Handle nested classes that could be a gsl::Pointer. 202 inferGslPointerAttribute(Record, Record); 203 } 204 205 void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, 206 SourceLocation PragmaLoc) { 207 PragmaMsStackAction Action = Sema::PSK_Reset; 208 unsigned Alignment = 0; 209 switch (Kind) { 210 // For all targets we support native and natural are the same. 211 // 212 // FIXME: This is not true on Darwin/PPC. 213 case POAK_Native: 214 case POAK_Power: 215 case POAK_Natural: 216 Action = Sema::PSK_Push_Set; 217 Alignment = 0; 218 break; 219 220 // Note that '#pragma options align=packed' is not equivalent to attribute 221 // packed, it has a different precedence relative to attribute aligned. 222 case POAK_Packed: 223 Action = Sema::PSK_Push_Set; 224 Alignment = 1; 225 break; 226 227 case POAK_Mac68k: 228 // Check if the target supports this. 229 if (!this->Context.getTargetInfo().hasAlignMac68kSupport()) { 230 Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported); 231 return; 232 } 233 Action = Sema::PSK_Push_Set; 234 Alignment = Sema::kMac68kAlignmentSentinel; 235 break; 236 237 case POAK_Reset: 238 // Reset just pops the top of the stack, or resets the current alignment to 239 // default. 240 Action = Sema::PSK_Pop; 241 if (PackStack.Stack.empty()) { 242 if (PackStack.CurrentValue) { 243 Action = Sema::PSK_Reset; 244 } else { 245 Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed) 246 << "stack empty"; 247 return; 248 } 249 } 250 break; 251 } 252 253 PackStack.Act(PragmaLoc, Action, StringRef(), Alignment); 254 } 255 256 void Sema::ActOnPragmaClangSection(SourceLocation PragmaLoc, PragmaClangSectionAction Action, 257 PragmaClangSectionKind SecKind, StringRef SecName) { 258 PragmaClangSection *CSec; 259 switch (SecKind) { 260 case PragmaClangSectionKind::PCSK_BSS: 261 CSec = &PragmaClangBSSSection; 262 break; 263 case PragmaClangSectionKind::PCSK_Data: 264 CSec = &PragmaClangDataSection; 265 break; 266 case PragmaClangSectionKind::PCSK_Rodata: 267 CSec = &PragmaClangRodataSection; 268 break; 269 case PragmaClangSectionKind::PCSK_Text: 270 CSec = &PragmaClangTextSection; 271 break; 272 default: 273 llvm_unreachable("invalid clang section kind"); 274 } 275 276 if (Action == PragmaClangSectionAction::PCSA_Clear) { 277 CSec->Valid = false; 278 return; 279 } 280 281 CSec->Valid = true; 282 CSec->SectionName = SecName; 283 CSec->PragmaLocation = PragmaLoc; 284 } 285 286 void Sema::ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action, 287 StringRef SlotLabel, Expr *alignment) { 288 Expr *Alignment = static_cast<Expr *>(alignment); 289 290 // If specified then alignment must be a "small" power of two. 291 unsigned AlignmentVal = 0; 292 if (Alignment) { 293 llvm::APSInt Val; 294 295 // pack(0) is like pack(), which just works out since that is what 296 // we use 0 for in PackAttr. 297 if (Alignment->isTypeDependent() || 298 Alignment->isValueDependent() || 299 !Alignment->isIntegerConstantExpr(Val, Context) || 300 !(Val == 0 || Val.isPowerOf2()) || 301 Val.getZExtValue() > 16) { 302 Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment); 303 return; // Ignore 304 } 305 306 AlignmentVal = (unsigned) Val.getZExtValue(); 307 } 308 if (Action == Sema::PSK_Show) { 309 // Show the current alignment, making sure to show the right value 310 // for the default. 311 // FIXME: This should come from the target. 312 AlignmentVal = PackStack.CurrentValue; 313 if (AlignmentVal == 0) 314 AlignmentVal = 8; 315 if (AlignmentVal == Sema::kMac68kAlignmentSentinel) 316 Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k"; 317 else 318 Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal; 319 } 320 // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack: 321 // "#pragma pack(pop, identifier, n) is undefined" 322 if (Action & Sema::PSK_Pop) { 323 if (Alignment && !SlotLabel.empty()) 324 Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifier_and_alignment); 325 if (PackStack.Stack.empty()) 326 Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "pack" << "stack empty"; 327 } 328 329 PackStack.Act(PragmaLoc, Action, SlotLabel, AlignmentVal); 330 } 331 332 void Sema::DiagnoseNonDefaultPragmaPack(PragmaPackDiagnoseKind Kind, 333 SourceLocation IncludeLoc) { 334 if (Kind == PragmaPackDiagnoseKind::NonDefaultStateAtInclude) { 335 SourceLocation PrevLocation = PackStack.CurrentPragmaLocation; 336 // Warn about non-default alignment at #includes (without redundant 337 // warnings for the same directive in nested includes). 338 // The warning is delayed until the end of the file to avoid warnings 339 // for files that don't have any records that are affected by the modified 340 // alignment. 341 bool HasNonDefaultValue = 342 PackStack.hasValue() && 343 (PackIncludeStack.empty() || 344 PackIncludeStack.back().CurrentPragmaLocation != PrevLocation); 345 PackIncludeStack.push_back( 346 {PackStack.CurrentValue, 347 PackStack.hasValue() ? PrevLocation : SourceLocation(), 348 HasNonDefaultValue, /*ShouldWarnOnInclude*/ false}); 349 return; 350 } 351 352 assert(Kind == PragmaPackDiagnoseKind::ChangedStateAtExit && "invalid kind"); 353 PackIncludeState PrevPackState = PackIncludeStack.pop_back_val(); 354 if (PrevPackState.ShouldWarnOnInclude) { 355 // Emit the delayed non-default alignment at #include warning. 356 Diag(IncludeLoc, diag::warn_pragma_pack_non_default_at_include); 357 Diag(PrevPackState.CurrentPragmaLocation, diag::note_pragma_pack_here); 358 } 359 // Warn about modified alignment after #includes. 360 if (PrevPackState.CurrentValue != PackStack.CurrentValue) { 361 Diag(IncludeLoc, diag::warn_pragma_pack_modified_after_include); 362 Diag(PackStack.CurrentPragmaLocation, diag::note_pragma_pack_here); 363 } 364 } 365 366 void Sema::DiagnoseUnterminatedPragmaPack() { 367 if (PackStack.Stack.empty()) 368 return; 369 bool IsInnermost = true; 370 for (const auto &StackSlot : llvm::reverse(PackStack.Stack)) { 371 Diag(StackSlot.PragmaPushLocation, diag::warn_pragma_pack_no_pop_eof); 372 // The user might have already reset the alignment, so suggest replacing 373 // the reset with a pop. 374 if (IsInnermost && PackStack.CurrentValue == PackStack.DefaultValue) { 375 DiagnosticBuilder DB = Diag(PackStack.CurrentPragmaLocation, 376 diag::note_pragma_pack_pop_instead_reset); 377 SourceLocation FixItLoc = Lexer::findLocationAfterToken( 378 PackStack.CurrentPragmaLocation, tok::l_paren, SourceMgr, LangOpts, 379 /*SkipTrailing=*/false); 380 if (FixItLoc.isValid()) 381 DB << FixItHint::CreateInsertion(FixItLoc, "pop"); 382 } 383 IsInnermost = false; 384 } 385 } 386 387 void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) { 388 MSStructPragmaOn = (Kind == PMSST_ON); 389 } 390 391 void Sema::ActOnPragmaMSComment(SourceLocation CommentLoc, 392 PragmaMSCommentKind Kind, StringRef Arg) { 393 auto *PCD = PragmaCommentDecl::Create( 394 Context, Context.getTranslationUnitDecl(), CommentLoc, Kind, Arg); 395 Context.getTranslationUnitDecl()->addDecl(PCD); 396 Consumer.HandleTopLevelDecl(DeclGroupRef(PCD)); 397 } 398 399 void Sema::ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name, 400 StringRef Value) { 401 auto *PDMD = PragmaDetectMismatchDecl::Create( 402 Context, Context.getTranslationUnitDecl(), Loc, Name, Value); 403 Context.getTranslationUnitDecl()->addDecl(PDMD); 404 Consumer.HandleTopLevelDecl(DeclGroupRef(PDMD)); 405 } 406 407 void Sema::ActOnPragmaMSPointersToMembers( 408 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod, 409 SourceLocation PragmaLoc) { 410 MSPointerToMemberRepresentationMethod = RepresentationMethod; 411 ImplicitMSInheritanceAttrLoc = PragmaLoc; 412 } 413 414 void Sema::ActOnPragmaMSVtorDisp(PragmaMsStackAction Action, 415 SourceLocation PragmaLoc, 416 MSVtorDispAttr::Mode Mode) { 417 if (Action & PSK_Pop && VtorDispStack.Stack.empty()) 418 Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp" 419 << "stack empty"; 420 VtorDispStack.Act(PragmaLoc, Action, StringRef(), Mode); 421 } 422 423 template<typename ValueType> 424 void Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation, 425 PragmaMsStackAction Action, 426 llvm::StringRef StackSlotLabel, 427 ValueType Value) { 428 if (Action == PSK_Reset) { 429 CurrentValue = DefaultValue; 430 CurrentPragmaLocation = PragmaLocation; 431 return; 432 } 433 if (Action & PSK_Push) 434 Stack.emplace_back(StackSlotLabel, CurrentValue, CurrentPragmaLocation, 435 PragmaLocation); 436 else if (Action & PSK_Pop) { 437 if (!StackSlotLabel.empty()) { 438 // If we've got a label, try to find it and jump there. 439 auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) { 440 return x.StackSlotLabel == StackSlotLabel; 441 }); 442 // If we found the label so pop from there. 443 if (I != Stack.rend()) { 444 CurrentValue = I->Value; 445 CurrentPragmaLocation = I->PragmaLocation; 446 Stack.erase(std::prev(I.base()), Stack.end()); 447 } 448 } else if (!Stack.empty()) { 449 // We do not have a label, just pop the last entry. 450 CurrentValue = Stack.back().Value; 451 CurrentPragmaLocation = Stack.back().PragmaLocation; 452 Stack.pop_back(); 453 } 454 } 455 if (Action & PSK_Set) { 456 CurrentValue = Value; 457 CurrentPragmaLocation = PragmaLocation; 458 } 459 } 460 461 bool Sema::UnifySection(StringRef SectionName, 462 int SectionFlags, 463 DeclaratorDecl *Decl) { 464 auto Section = Context.SectionInfos.find(SectionName); 465 if (Section == Context.SectionInfos.end()) { 466 Context.SectionInfos[SectionName] = 467 ASTContext::SectionInfo(Decl, SourceLocation(), SectionFlags); 468 return false; 469 } 470 // A pre-declared section takes precedence w/o diagnostic. 471 if (Section->second.SectionFlags == SectionFlags || 472 !(Section->second.SectionFlags & ASTContext::PSF_Implicit)) 473 return false; 474 auto OtherDecl = Section->second.Decl; 475 Diag(Decl->getLocation(), diag::err_section_conflict) 476 << Decl << OtherDecl; 477 Diag(OtherDecl->getLocation(), diag::note_declared_at) 478 << OtherDecl->getName(); 479 if (auto A = Decl->getAttr<SectionAttr>()) 480 if (A->isImplicit()) 481 Diag(A->getLocation(), diag::note_pragma_entered_here); 482 if (auto A = OtherDecl->getAttr<SectionAttr>()) 483 if (A->isImplicit()) 484 Diag(A->getLocation(), diag::note_pragma_entered_here); 485 return true; 486 } 487 488 bool Sema::UnifySection(StringRef SectionName, 489 int SectionFlags, 490 SourceLocation PragmaSectionLocation) { 491 auto Section = Context.SectionInfos.find(SectionName); 492 if (Section != Context.SectionInfos.end()) { 493 if (Section->second.SectionFlags == SectionFlags) 494 return false; 495 if (!(Section->second.SectionFlags & ASTContext::PSF_Implicit)) { 496 Diag(PragmaSectionLocation, diag::err_section_conflict) 497 << "this" << "a prior #pragma section"; 498 Diag(Section->second.PragmaSectionLocation, 499 diag::note_pragma_entered_here); 500 return true; 501 } 502 } 503 Context.SectionInfos[SectionName] = 504 ASTContext::SectionInfo(nullptr, PragmaSectionLocation, SectionFlags); 505 return false; 506 } 507 508 /// Called on well formed \#pragma bss_seg(). 509 void Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation, 510 PragmaMsStackAction Action, 511 llvm::StringRef StackSlotLabel, 512 StringLiteral *SegmentName, 513 llvm::StringRef PragmaName) { 514 PragmaStack<StringLiteral *> *Stack = 515 llvm::StringSwitch<PragmaStack<StringLiteral *> *>(PragmaName) 516 .Case("data_seg", &DataSegStack) 517 .Case("bss_seg", &BSSSegStack) 518 .Case("const_seg", &ConstSegStack) 519 .Case("code_seg", &CodeSegStack); 520 if (Action & PSK_Pop && Stack->Stack.empty()) 521 Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName 522 << "stack empty"; 523 if (SegmentName) { 524 if (!checkSectionName(SegmentName->getBeginLoc(), SegmentName->getString())) 525 return; 526 527 if (SegmentName->getString() == ".drectve" && 528 Context.getTargetInfo().getCXXABI().isMicrosoft()) 529 Diag(PragmaLocation, diag::warn_attribute_section_drectve) << PragmaName; 530 } 531 532 Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName); 533 } 534 535 /// Called on well formed \#pragma bss_seg(). 536 void Sema::ActOnPragmaMSSection(SourceLocation PragmaLocation, 537 int SectionFlags, StringLiteral *SegmentName) { 538 UnifySection(SegmentName->getString(), SectionFlags, PragmaLocation); 539 } 540 541 void Sema::ActOnPragmaMSInitSeg(SourceLocation PragmaLocation, 542 StringLiteral *SegmentName) { 543 // There's no stack to maintain, so we just have a current section. When we 544 // see the default section, reset our current section back to null so we stop 545 // tacking on unnecessary attributes. 546 CurInitSeg = SegmentName->getString() == ".CRT$XCU" ? nullptr : SegmentName; 547 CurInitSegLoc = PragmaLocation; 548 } 549 550 void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope, 551 SourceLocation PragmaLoc) { 552 553 IdentifierInfo *Name = IdTok.getIdentifierInfo(); 554 LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName); 555 LookupParsedName(Lookup, curScope, nullptr, true); 556 557 if (Lookup.empty()) { 558 Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var) 559 << Name << SourceRange(IdTok.getLocation()); 560 return; 561 } 562 563 VarDecl *VD = Lookup.getAsSingle<VarDecl>(); 564 if (!VD) { 565 Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg) 566 << Name << SourceRange(IdTok.getLocation()); 567 return; 568 } 569 570 // Warn if this was used before being marked unused. 571 if (VD->isUsed()) 572 Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name; 573 574 VD->addAttr(UnusedAttr::CreateImplicit(Context, IdTok.getLocation(), 575 AttributeCommonInfo::AS_Pragma, 576 UnusedAttr::GNU_unused)); 577 } 578 579 void Sema::AddCFAuditedAttribute(Decl *D) { 580 IdentifierInfo *Ident; 581 SourceLocation Loc; 582 std::tie(Ident, Loc) = PP.getPragmaARCCFCodeAuditedInfo(); 583 if (!Loc.isValid()) return; 584 585 // Don't add a redundant or conflicting attribute. 586 if (D->hasAttr<CFAuditedTransferAttr>() || 587 D->hasAttr<CFUnknownTransferAttr>()) 588 return; 589 590 AttributeCommonInfo Info(Ident, SourceRange(Loc), 591 AttributeCommonInfo::AS_Pragma); 592 D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Info)); 593 } 594 595 namespace { 596 597 Optional<attr::SubjectMatchRule> 598 getParentAttrMatcherRule(attr::SubjectMatchRule Rule) { 599 using namespace attr; 600 switch (Rule) { 601 default: 602 return None; 603 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) 604 #define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \ 605 case Value: \ 606 return Parent; 607 #include "clang/Basic/AttrSubMatchRulesList.inc" 608 } 609 } 610 611 bool isNegatedAttrMatcherSubRule(attr::SubjectMatchRule Rule) { 612 using namespace attr; 613 switch (Rule) { 614 default: 615 return false; 616 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) 617 #define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \ 618 case Value: \ 619 return IsNegated; 620 #include "clang/Basic/AttrSubMatchRulesList.inc" 621 } 622 } 623 624 CharSourceRange replacementRangeForListElement(const Sema &S, 625 SourceRange Range) { 626 // Make sure that the ',' is removed as well. 627 SourceLocation AfterCommaLoc = Lexer::findLocationAfterToken( 628 Range.getEnd(), tok::comma, S.getSourceManager(), S.getLangOpts(), 629 /*SkipTrailingWhitespaceAndNewLine=*/false); 630 if (AfterCommaLoc.isValid()) 631 return CharSourceRange::getCharRange(Range.getBegin(), AfterCommaLoc); 632 else 633 return CharSourceRange::getTokenRange(Range); 634 } 635 636 std::string 637 attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) { 638 std::string Result; 639 llvm::raw_string_ostream OS(Result); 640 for (const auto &I : llvm::enumerate(Rules)) { 641 if (I.index()) 642 OS << (I.index() == Rules.size() - 1 ? ", and " : ", "); 643 OS << "'" << attr::getSubjectMatchRuleSpelling(I.value()) << "'"; 644 } 645 return OS.str(); 646 } 647 648 } // end anonymous namespace 649 650 void Sema::ActOnPragmaAttributeAttribute( 651 ParsedAttr &Attribute, SourceLocation PragmaLoc, 652 attr::ParsedSubjectMatchRuleSet Rules) { 653 Attribute.setIsPragmaClangAttribute(); 654 SmallVector<attr::SubjectMatchRule, 4> SubjectMatchRules; 655 // Gather the subject match rules that are supported by the attribute. 656 SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4> 657 StrictSubjectMatchRuleSet; 658 Attribute.getMatchRules(LangOpts, StrictSubjectMatchRuleSet); 659 660 // Figure out which subject matching rules are valid. 661 if (StrictSubjectMatchRuleSet.empty()) { 662 // Check for contradicting match rules. Contradicting match rules are 663 // either: 664 // - a top-level rule and one of its sub-rules. E.g. variable and 665 // variable(is_parameter). 666 // - a sub-rule and a sibling that's negated. E.g. 667 // variable(is_thread_local) and variable(unless(is_parameter)) 668 llvm::SmallDenseMap<int, std::pair<int, SourceRange>, 2> 669 RulesToFirstSpecifiedNegatedSubRule; 670 for (const auto &Rule : Rules) { 671 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first); 672 Optional<attr::SubjectMatchRule> ParentRule = 673 getParentAttrMatcherRule(MatchRule); 674 if (!ParentRule) 675 continue; 676 auto It = Rules.find(*ParentRule); 677 if (It != Rules.end()) { 678 // A sub-rule contradicts a parent rule. 679 Diag(Rule.second.getBegin(), 680 diag::err_pragma_attribute_matcher_subrule_contradicts_rule) 681 << attr::getSubjectMatchRuleSpelling(MatchRule) 682 << attr::getSubjectMatchRuleSpelling(*ParentRule) << It->second 683 << FixItHint::CreateRemoval( 684 replacementRangeForListElement(*this, Rule.second)); 685 // Keep going without removing this rule as it won't change the set of 686 // declarations that receive the attribute. 687 continue; 688 } 689 if (isNegatedAttrMatcherSubRule(MatchRule)) 690 RulesToFirstSpecifiedNegatedSubRule.insert( 691 std::make_pair(*ParentRule, Rule)); 692 } 693 bool IgnoreNegatedSubRules = false; 694 for (const auto &Rule : Rules) { 695 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first); 696 Optional<attr::SubjectMatchRule> ParentRule = 697 getParentAttrMatcherRule(MatchRule); 698 if (!ParentRule) 699 continue; 700 auto It = RulesToFirstSpecifiedNegatedSubRule.find(*ParentRule); 701 if (It != RulesToFirstSpecifiedNegatedSubRule.end() && 702 It->second != Rule) { 703 // Negated sub-rule contradicts another sub-rule. 704 Diag( 705 It->second.second.getBegin(), 706 diag:: 707 err_pragma_attribute_matcher_negated_subrule_contradicts_subrule) 708 << attr::getSubjectMatchRuleSpelling( 709 attr::SubjectMatchRule(It->second.first)) 710 << attr::getSubjectMatchRuleSpelling(MatchRule) << Rule.second 711 << FixItHint::CreateRemoval( 712 replacementRangeForListElement(*this, It->second.second)); 713 // Keep going but ignore all of the negated sub-rules. 714 IgnoreNegatedSubRules = true; 715 RulesToFirstSpecifiedNegatedSubRule.erase(It); 716 } 717 } 718 719 if (!IgnoreNegatedSubRules) { 720 for (const auto &Rule : Rules) 721 SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first)); 722 } else { 723 for (const auto &Rule : Rules) { 724 if (!isNegatedAttrMatcherSubRule(attr::SubjectMatchRule(Rule.first))) 725 SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first)); 726 } 727 } 728 Rules.clear(); 729 } else { 730 for (const auto &Rule : StrictSubjectMatchRuleSet) { 731 if (Rules.erase(Rule.first)) { 732 // Add the rule to the set of attribute receivers only if it's supported 733 // in the current language mode. 734 if (Rule.second) 735 SubjectMatchRules.push_back(Rule.first); 736 } 737 } 738 } 739 740 if (!Rules.empty()) { 741 auto Diagnostic = 742 Diag(PragmaLoc, diag::err_pragma_attribute_invalid_matchers) 743 << Attribute; 744 SmallVector<attr::SubjectMatchRule, 2> ExtraRules; 745 for (const auto &Rule : Rules) { 746 ExtraRules.push_back(attr::SubjectMatchRule(Rule.first)); 747 Diagnostic << FixItHint::CreateRemoval( 748 replacementRangeForListElement(*this, Rule.second)); 749 } 750 Diagnostic << attrMatcherRuleListToString(ExtraRules); 751 } 752 753 if (PragmaAttributeStack.empty()) { 754 Diag(PragmaLoc, diag::err_pragma_attr_attr_no_push); 755 return; 756 } 757 758 PragmaAttributeStack.back().Entries.push_back( 759 {PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false}); 760 } 761 762 void Sema::ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc, 763 const IdentifierInfo *Namespace) { 764 PragmaAttributeStack.emplace_back(); 765 PragmaAttributeStack.back().Loc = PragmaLoc; 766 PragmaAttributeStack.back().Namespace = Namespace; 767 } 768 769 void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc, 770 const IdentifierInfo *Namespace) { 771 if (PragmaAttributeStack.empty()) { 772 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1; 773 return; 774 } 775 776 // Dig back through the stack trying to find the most recently pushed group 777 // that in Namespace. Note that this works fine if no namespace is present, 778 // think of push/pops without namespaces as having an implicit "nullptr" 779 // namespace. 780 for (size_t Index = PragmaAttributeStack.size(); Index;) { 781 --Index; 782 if (PragmaAttributeStack[Index].Namespace == Namespace) { 783 for (const PragmaAttributeEntry &Entry : 784 PragmaAttributeStack[Index].Entries) { 785 if (!Entry.IsUsed) { 786 assert(Entry.Attribute && "Expected an attribute"); 787 Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused) 788 << *Entry.Attribute; 789 Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here); 790 } 791 } 792 PragmaAttributeStack.erase(PragmaAttributeStack.begin() + Index); 793 return; 794 } 795 } 796 797 if (Namespace) 798 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) 799 << 0 << Namespace->getName(); 800 else 801 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1; 802 } 803 804 void Sema::AddPragmaAttributes(Scope *S, Decl *D) { 805 if (PragmaAttributeStack.empty()) 806 return; 807 for (auto &Group : PragmaAttributeStack) { 808 for (auto &Entry : Group.Entries) { 809 ParsedAttr *Attribute = Entry.Attribute; 810 assert(Attribute && "Expected an attribute"); 811 assert(Attribute->isPragmaClangAttribute() && 812 "expected #pragma clang attribute"); 813 814 // Ensure that the attribute can be applied to the given declaration. 815 bool Applies = false; 816 for (const auto &Rule : Entry.MatchRules) { 817 if (Attribute->appliesToDecl(D, Rule)) { 818 Applies = true; 819 break; 820 } 821 } 822 if (!Applies) 823 continue; 824 Entry.IsUsed = true; 825 PragmaAttributeCurrentTargetDecl = D; 826 ParsedAttributesView Attrs; 827 Attrs.addAtEnd(Attribute); 828 ProcessDeclAttributeList(S, D, Attrs); 829 PragmaAttributeCurrentTargetDecl = nullptr; 830 } 831 } 832 } 833 834 void Sema::PrintPragmaAttributeInstantiationPoint() { 835 assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration"); 836 Diags.Report(PragmaAttributeCurrentTargetDecl->getBeginLoc(), 837 diag::note_pragma_attribute_applied_decl_here); 838 } 839 840 void Sema::DiagnoseUnterminatedPragmaAttribute() { 841 if (PragmaAttributeStack.empty()) 842 return; 843 Diag(PragmaAttributeStack.back().Loc, diag::err_pragma_attribute_no_pop_eof); 844 } 845 846 void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) { 847 if(On) 848 OptimizeOffPragmaLocation = SourceLocation(); 849 else 850 OptimizeOffPragmaLocation = PragmaLoc; 851 } 852 853 void Sema::AddRangeBasedOptnone(FunctionDecl *FD) { 854 // In the future, check other pragmas if they're implemented (e.g. pragma 855 // optimize 0 will probably map to this functionality too). 856 if(OptimizeOffPragmaLocation.isValid()) 857 AddOptnoneAttributeIfNoConflicts(FD, OptimizeOffPragmaLocation); 858 } 859 860 void Sema::AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, 861 SourceLocation Loc) { 862 // Don't add a conflicting attribute. No diagnostic is needed. 863 if (FD->hasAttr<MinSizeAttr>() || FD->hasAttr<AlwaysInlineAttr>()) 864 return; 865 866 // Add attributes only if required. Optnone requires noinline as well, but if 867 // either is already present then don't bother adding them. 868 if (!FD->hasAttr<OptimizeNoneAttr>()) 869 FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc)); 870 if (!FD->hasAttr<NoInlineAttr>()) 871 FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc)); 872 } 873 874 typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack; 875 enum : unsigned { NoVisibility = ~0U }; 876 877 void Sema::AddPushedVisibilityAttribute(Decl *D) { 878 if (!VisContext) 879 return; 880 881 NamedDecl *ND = dyn_cast<NamedDecl>(D); 882 if (ND && ND->getExplicitVisibility(NamedDecl::VisibilityForValue)) 883 return; 884 885 VisStack *Stack = static_cast<VisStack*>(VisContext); 886 unsigned rawType = Stack->back().first; 887 if (rawType == NoVisibility) return; 888 889 VisibilityAttr::VisibilityType type 890 = (VisibilityAttr::VisibilityType) rawType; 891 SourceLocation loc = Stack->back().second; 892 893 D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc)); 894 } 895 896 /// FreeVisContext - Deallocate and null out VisContext. 897 void Sema::FreeVisContext() { 898 delete static_cast<VisStack*>(VisContext); 899 VisContext = nullptr; 900 } 901 902 static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) { 903 // Put visibility on stack. 904 if (!S.VisContext) 905 S.VisContext = new VisStack; 906 907 VisStack *Stack = static_cast<VisStack*>(S.VisContext); 908 Stack->push_back(std::make_pair(type, loc)); 909 } 910 911 void Sema::ActOnPragmaVisibility(const IdentifierInfo* VisType, 912 SourceLocation PragmaLoc) { 913 if (VisType) { 914 // Compute visibility to use. 915 VisibilityAttr::VisibilityType T; 916 if (!VisibilityAttr::ConvertStrToVisibilityType(VisType->getName(), T)) { 917 Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << VisType; 918 return; 919 } 920 PushPragmaVisibility(*this, T, PragmaLoc); 921 } else { 922 PopPragmaVisibility(false, PragmaLoc); 923 } 924 } 925 926 void Sema::ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC) { 927 switch (FPC) { 928 case LangOptions::FPC_On: 929 FPFeatures.setAllowFPContractWithinStatement(); 930 break; 931 case LangOptions::FPC_Fast: 932 FPFeatures.setAllowFPContractAcrossStatement(); 933 break; 934 case LangOptions::FPC_Off: 935 FPFeatures.setDisallowFPContract(); 936 break; 937 } 938 } 939 940 void Sema::ActOnPragmaFEnvAccess(LangOptions::FEnvAccessModeKind FPC) { 941 switch (FPC) { 942 case LangOptions::FEA_On: 943 FPFeatures.setAllowFEnvAccess(); 944 break; 945 case LangOptions::FEA_Off: 946 FPFeatures.setDisallowFEnvAccess(); 947 break; 948 } 949 } 950 951 952 void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr, 953 SourceLocation Loc) { 954 // Visibility calculations will consider the namespace's visibility. 955 // Here we just want to note that we're in a visibility context 956 // which overrides any enclosing #pragma context, but doesn't itself 957 // contribute visibility. 958 PushPragmaVisibility(*this, NoVisibility, Loc); 959 } 960 961 void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) { 962 if (!VisContext) { 963 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch); 964 return; 965 } 966 967 // Pop visibility from stack 968 VisStack *Stack = static_cast<VisStack*>(VisContext); 969 970 const std::pair<unsigned, SourceLocation> *Back = &Stack->back(); 971 bool StartsWithPragma = Back->first != NoVisibility; 972 if (StartsWithPragma && IsNamespaceEnd) { 973 Diag(Back->second, diag::err_pragma_push_visibility_mismatch); 974 Diag(EndLoc, diag::note_surrounding_namespace_ends_here); 975 976 // For better error recovery, eat all pushes inside the namespace. 977 do { 978 Stack->pop_back(); 979 Back = &Stack->back(); 980 StartsWithPragma = Back->first != NoVisibility; 981 } while (StartsWithPragma); 982 } else if (!StartsWithPragma && !IsNamespaceEnd) { 983 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch); 984 Diag(Back->second, diag::note_surrounding_namespace_starts_here); 985 return; 986 } 987 988 Stack->pop_back(); 989 // To simplify the implementation, never keep around an empty stack. 990 if (Stack->empty()) 991 FreeVisContext(); 992 } 993