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