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