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