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