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 !checkSectionName(SegmentName->getBeginLoc(), SegmentName->getString())) 408 return; 409 Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName); 410 } 411 412 /// Called on well formed \#pragma bss_seg(). 413 void Sema::ActOnPragmaMSSection(SourceLocation PragmaLocation, 414 int SectionFlags, StringLiteral *SegmentName) { 415 UnifySection(SegmentName->getString(), SectionFlags, PragmaLocation); 416 } 417 418 void Sema::ActOnPragmaMSInitSeg(SourceLocation PragmaLocation, 419 StringLiteral *SegmentName) { 420 // There's no stack to maintain, so we just have a current section. When we 421 // see the default section, reset our current section back to null so we stop 422 // tacking on unnecessary attributes. 423 CurInitSeg = SegmentName->getString() == ".CRT$XCU" ? nullptr : SegmentName; 424 CurInitSegLoc = PragmaLocation; 425 } 426 427 void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope, 428 SourceLocation PragmaLoc) { 429 430 IdentifierInfo *Name = IdTok.getIdentifierInfo(); 431 LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName); 432 LookupParsedName(Lookup, curScope, nullptr, true); 433 434 if (Lookup.empty()) { 435 Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var) 436 << Name << SourceRange(IdTok.getLocation()); 437 return; 438 } 439 440 VarDecl *VD = Lookup.getAsSingle<VarDecl>(); 441 if (!VD) { 442 Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg) 443 << Name << SourceRange(IdTok.getLocation()); 444 return; 445 } 446 447 // Warn if this was used before being marked unused. 448 if (VD->isUsed()) 449 Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name; 450 451 VD->addAttr(UnusedAttr::CreateImplicit(Context, UnusedAttr::GNU_unused, 452 IdTok.getLocation())); 453 } 454 455 void Sema::AddCFAuditedAttribute(Decl *D) { 456 SourceLocation Loc = PP.getPragmaARCCFCodeAuditedLoc(); 457 if (!Loc.isValid()) return; 458 459 // Don't add a redundant or conflicting attribute. 460 if (D->hasAttr<CFAuditedTransferAttr>() || 461 D->hasAttr<CFUnknownTransferAttr>()) 462 return; 463 464 D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Loc)); 465 } 466 467 namespace { 468 469 Optional<attr::SubjectMatchRule> 470 getParentAttrMatcherRule(attr::SubjectMatchRule Rule) { 471 using namespace attr; 472 switch (Rule) { 473 default: 474 return None; 475 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) 476 #define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \ 477 case Value: \ 478 return Parent; 479 #include "clang/Basic/AttrSubMatchRulesList.inc" 480 } 481 } 482 483 bool isNegatedAttrMatcherSubRule(attr::SubjectMatchRule Rule) { 484 using namespace attr; 485 switch (Rule) { 486 default: 487 return false; 488 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) 489 #define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \ 490 case Value: \ 491 return IsNegated; 492 #include "clang/Basic/AttrSubMatchRulesList.inc" 493 } 494 } 495 496 CharSourceRange replacementRangeForListElement(const Sema &S, 497 SourceRange Range) { 498 // Make sure that the ',' is removed as well. 499 SourceLocation AfterCommaLoc = Lexer::findLocationAfterToken( 500 Range.getEnd(), tok::comma, S.getSourceManager(), S.getLangOpts(), 501 /*SkipTrailingWhitespaceAndNewLine=*/false); 502 if (AfterCommaLoc.isValid()) 503 return CharSourceRange::getCharRange(Range.getBegin(), AfterCommaLoc); 504 else 505 return CharSourceRange::getTokenRange(Range); 506 } 507 508 std::string 509 attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) { 510 std::string Result; 511 llvm::raw_string_ostream OS(Result); 512 for (const auto &I : llvm::enumerate(Rules)) { 513 if (I.index()) 514 OS << (I.index() == Rules.size() - 1 ? ", and " : ", "); 515 OS << "'" << attr::getSubjectMatchRuleSpelling(I.value()) << "'"; 516 } 517 return OS.str(); 518 } 519 520 } // end anonymous namespace 521 522 void Sema::ActOnPragmaAttributeAttribute( 523 ParsedAttr &Attribute, SourceLocation PragmaLoc, 524 attr::ParsedSubjectMatchRuleSet Rules) { 525 Attribute.setIsPragmaClangAttribute(); 526 SmallVector<attr::SubjectMatchRule, 4> SubjectMatchRules; 527 // Gather the subject match rules that are supported by the attribute. 528 SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4> 529 StrictSubjectMatchRuleSet; 530 Attribute.getMatchRules(LangOpts, StrictSubjectMatchRuleSet); 531 532 // Figure out which subject matching rules are valid. 533 if (StrictSubjectMatchRuleSet.empty()) { 534 // Check for contradicting match rules. Contradicting match rules are 535 // either: 536 // - a top-level rule and one of its sub-rules. E.g. variable and 537 // variable(is_parameter). 538 // - a sub-rule and a sibling that's negated. E.g. 539 // variable(is_thread_local) and variable(unless(is_parameter)) 540 llvm::SmallDenseMap<int, std::pair<int, SourceRange>, 2> 541 RulesToFirstSpecifiedNegatedSubRule; 542 for (const auto &Rule : Rules) { 543 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first); 544 Optional<attr::SubjectMatchRule> ParentRule = 545 getParentAttrMatcherRule(MatchRule); 546 if (!ParentRule) 547 continue; 548 auto It = Rules.find(*ParentRule); 549 if (It != Rules.end()) { 550 // A sub-rule contradicts a parent rule. 551 Diag(Rule.second.getBegin(), 552 diag::err_pragma_attribute_matcher_subrule_contradicts_rule) 553 << attr::getSubjectMatchRuleSpelling(MatchRule) 554 << attr::getSubjectMatchRuleSpelling(*ParentRule) << It->second 555 << FixItHint::CreateRemoval( 556 replacementRangeForListElement(*this, Rule.second)); 557 // Keep going without removing this rule as it won't change the set of 558 // declarations that receive the attribute. 559 continue; 560 } 561 if (isNegatedAttrMatcherSubRule(MatchRule)) 562 RulesToFirstSpecifiedNegatedSubRule.insert( 563 std::make_pair(*ParentRule, Rule)); 564 } 565 bool IgnoreNegatedSubRules = false; 566 for (const auto &Rule : Rules) { 567 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first); 568 Optional<attr::SubjectMatchRule> ParentRule = 569 getParentAttrMatcherRule(MatchRule); 570 if (!ParentRule) 571 continue; 572 auto It = RulesToFirstSpecifiedNegatedSubRule.find(*ParentRule); 573 if (It != RulesToFirstSpecifiedNegatedSubRule.end() && 574 It->second != Rule) { 575 // Negated sub-rule contradicts another sub-rule. 576 Diag( 577 It->second.second.getBegin(), 578 diag:: 579 err_pragma_attribute_matcher_negated_subrule_contradicts_subrule) 580 << attr::getSubjectMatchRuleSpelling( 581 attr::SubjectMatchRule(It->second.first)) 582 << attr::getSubjectMatchRuleSpelling(MatchRule) << Rule.second 583 << FixItHint::CreateRemoval( 584 replacementRangeForListElement(*this, It->second.second)); 585 // Keep going but ignore all of the negated sub-rules. 586 IgnoreNegatedSubRules = true; 587 RulesToFirstSpecifiedNegatedSubRule.erase(It); 588 } 589 } 590 591 if (!IgnoreNegatedSubRules) { 592 for (const auto &Rule : Rules) 593 SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first)); 594 } else { 595 for (const auto &Rule : Rules) { 596 if (!isNegatedAttrMatcherSubRule(attr::SubjectMatchRule(Rule.first))) 597 SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first)); 598 } 599 } 600 Rules.clear(); 601 } else { 602 for (const auto &Rule : StrictSubjectMatchRuleSet) { 603 if (Rules.erase(Rule.first)) { 604 // Add the rule to the set of attribute receivers only if it's supported 605 // in the current language mode. 606 if (Rule.second) 607 SubjectMatchRules.push_back(Rule.first); 608 } 609 } 610 } 611 612 if (!Rules.empty()) { 613 auto Diagnostic = 614 Diag(PragmaLoc, diag::err_pragma_attribute_invalid_matchers) 615 << Attribute.getName(); 616 SmallVector<attr::SubjectMatchRule, 2> ExtraRules; 617 for (const auto &Rule : Rules) { 618 ExtraRules.push_back(attr::SubjectMatchRule(Rule.first)); 619 Diagnostic << FixItHint::CreateRemoval( 620 replacementRangeForListElement(*this, Rule.second)); 621 } 622 Diagnostic << attrMatcherRuleListToString(ExtraRules); 623 } 624 625 if (PragmaAttributeStack.empty()) { 626 Diag(PragmaLoc, diag::err_pragma_attr_attr_no_push); 627 return; 628 } 629 630 PragmaAttributeStack.back().Entries.push_back( 631 {PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false}); 632 } 633 634 void Sema::ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc, 635 const IdentifierInfo *Namespace) { 636 PragmaAttributeStack.emplace_back(); 637 PragmaAttributeStack.back().Loc = PragmaLoc; 638 PragmaAttributeStack.back().Namespace = Namespace; 639 } 640 641 void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc, 642 const IdentifierInfo *Namespace) { 643 if (PragmaAttributeStack.empty()) { 644 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1; 645 return; 646 } 647 648 // Dig back through the stack trying to find the most recently pushed group 649 // that in Namespace. Note that this works fine if no namespace is present, 650 // think of push/pops without namespaces as having an implicit "nullptr" 651 // namespace. 652 for (size_t Index = PragmaAttributeStack.size(); Index;) { 653 --Index; 654 if (PragmaAttributeStack[Index].Namespace == Namespace) { 655 for (const PragmaAttributeEntry &Entry : 656 PragmaAttributeStack[Index].Entries) { 657 if (!Entry.IsUsed) { 658 assert(Entry.Attribute && "Expected an attribute"); 659 Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused) 660 << *Entry.Attribute; 661 Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here); 662 } 663 } 664 PragmaAttributeStack.erase(PragmaAttributeStack.begin() + Index); 665 return; 666 } 667 } 668 669 if (Namespace) 670 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) 671 << 0 << Namespace->getName(); 672 else 673 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1; 674 } 675 676 void Sema::AddPragmaAttributes(Scope *S, Decl *D) { 677 if (PragmaAttributeStack.empty()) 678 return; 679 for (auto &Group : PragmaAttributeStack) { 680 for (auto &Entry : Group.Entries) { 681 ParsedAttr *Attribute = Entry.Attribute; 682 assert(Attribute && "Expected an attribute"); 683 assert(Attribute->isPragmaClangAttribute() && 684 "expected #pragma clang attribute"); 685 686 // Ensure that the attribute can be applied to the given declaration. 687 bool Applies = false; 688 for (const auto &Rule : Entry.MatchRules) { 689 if (Attribute->appliesToDecl(D, Rule)) { 690 Applies = true; 691 break; 692 } 693 } 694 if (!Applies) 695 continue; 696 Entry.IsUsed = true; 697 PragmaAttributeCurrentTargetDecl = D; 698 ParsedAttributesView Attrs; 699 Attrs.addAtEnd(Attribute); 700 ProcessDeclAttributeList(S, D, Attrs); 701 PragmaAttributeCurrentTargetDecl = nullptr; 702 } 703 } 704 } 705 706 void Sema::PrintPragmaAttributeInstantiationPoint() { 707 assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration"); 708 Diags.Report(PragmaAttributeCurrentTargetDecl->getBeginLoc(), 709 diag::note_pragma_attribute_applied_decl_here); 710 } 711 712 void Sema::DiagnoseUnterminatedPragmaAttribute() { 713 if (PragmaAttributeStack.empty()) 714 return; 715 Diag(PragmaAttributeStack.back().Loc, diag::err_pragma_attribute_no_pop_eof); 716 } 717 718 void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) { 719 if(On) 720 OptimizeOffPragmaLocation = SourceLocation(); 721 else 722 OptimizeOffPragmaLocation = PragmaLoc; 723 } 724 725 void Sema::AddRangeBasedOptnone(FunctionDecl *FD) { 726 // In the future, check other pragmas if they're implemented (e.g. pragma 727 // optimize 0 will probably map to this functionality too). 728 if(OptimizeOffPragmaLocation.isValid()) 729 AddOptnoneAttributeIfNoConflicts(FD, OptimizeOffPragmaLocation); 730 } 731 732 void Sema::AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, 733 SourceLocation Loc) { 734 // Don't add a conflicting attribute. No diagnostic is needed. 735 if (FD->hasAttr<MinSizeAttr>() || FD->hasAttr<AlwaysInlineAttr>()) 736 return; 737 738 // Add attributes only if required. Optnone requires noinline as well, but if 739 // either is already present then don't bother adding them. 740 if (!FD->hasAttr<OptimizeNoneAttr>()) 741 FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc)); 742 if (!FD->hasAttr<NoInlineAttr>()) 743 FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc)); 744 } 745 746 typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack; 747 enum : unsigned { NoVisibility = ~0U }; 748 749 void Sema::AddPushedVisibilityAttribute(Decl *D) { 750 if (!VisContext) 751 return; 752 753 NamedDecl *ND = dyn_cast<NamedDecl>(D); 754 if (ND && ND->getExplicitVisibility(NamedDecl::VisibilityForValue)) 755 return; 756 757 VisStack *Stack = static_cast<VisStack*>(VisContext); 758 unsigned rawType = Stack->back().first; 759 if (rawType == NoVisibility) return; 760 761 VisibilityAttr::VisibilityType type 762 = (VisibilityAttr::VisibilityType) rawType; 763 SourceLocation loc = Stack->back().second; 764 765 D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc)); 766 } 767 768 /// FreeVisContext - Deallocate and null out VisContext. 769 void Sema::FreeVisContext() { 770 delete static_cast<VisStack*>(VisContext); 771 VisContext = nullptr; 772 } 773 774 static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) { 775 // Put visibility on stack. 776 if (!S.VisContext) 777 S.VisContext = new VisStack; 778 779 VisStack *Stack = static_cast<VisStack*>(S.VisContext); 780 Stack->push_back(std::make_pair(type, loc)); 781 } 782 783 void Sema::ActOnPragmaVisibility(const IdentifierInfo* VisType, 784 SourceLocation PragmaLoc) { 785 if (VisType) { 786 // Compute visibility to use. 787 VisibilityAttr::VisibilityType T; 788 if (!VisibilityAttr::ConvertStrToVisibilityType(VisType->getName(), T)) { 789 Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << VisType; 790 return; 791 } 792 PushPragmaVisibility(*this, T, PragmaLoc); 793 } else { 794 PopPragmaVisibility(false, PragmaLoc); 795 } 796 } 797 798 void Sema::ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC) { 799 switch (FPC) { 800 case LangOptions::FPC_On: 801 FPFeatures.setAllowFPContractWithinStatement(); 802 break; 803 case LangOptions::FPC_Fast: 804 FPFeatures.setAllowFPContractAcrossStatement(); 805 break; 806 case LangOptions::FPC_Off: 807 FPFeatures.setDisallowFPContract(); 808 break; 809 } 810 } 811 812 void Sema::ActOnPragmaFEnvAccess(LangOptions::FEnvAccessModeKind FPC) { 813 switch (FPC) { 814 case LangOptions::FEA_On: 815 FPFeatures.setAllowFEnvAccess(); 816 break; 817 case LangOptions::FEA_Off: 818 FPFeatures.setDisallowFEnvAccess(); 819 break; 820 } 821 } 822 823 824 void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr, 825 SourceLocation Loc) { 826 // Visibility calculations will consider the namespace's visibility. 827 // Here we just want to note that we're in a visibility context 828 // which overrides any enclosing #pragma context, but doesn't itself 829 // contribute visibility. 830 PushPragmaVisibility(*this, NoVisibility, Loc); 831 } 832 833 void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) { 834 if (!VisContext) { 835 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch); 836 return; 837 } 838 839 // Pop visibility from stack 840 VisStack *Stack = static_cast<VisStack*>(VisContext); 841 842 const std::pair<unsigned, SourceLocation> *Back = &Stack->back(); 843 bool StartsWithPragma = Back->first != NoVisibility; 844 if (StartsWithPragma && IsNamespaceEnd) { 845 Diag(Back->second, diag::err_pragma_push_visibility_mismatch); 846 Diag(EndLoc, diag::note_surrounding_namespace_ends_here); 847 848 // For better error recovery, eat all pushes inside the namespace. 849 do { 850 Stack->pop_back(); 851 Back = &Stack->back(); 852 StartsWithPragma = Back->first != NoVisibility; 853 } while (StartsWithPragma); 854 } else if (!StartsWithPragma && !IsNamespaceEnd) { 855 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch); 856 Diag(Back->second, diag::note_surrounding_namespace_starts_here); 857 return; 858 } 859 860 Stack->pop_back(); 861 // To simplify the implementation, never keep around an empty stack. 862 if (Stack->empty()) 863 FreeVisContext(); 864 } 865