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