1 //===--- SemaAttr.cpp - Semantic Analysis for Attributes ------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements semantic analysis for non-trivial attributes and
12 //===----------------------------------------------------------------------===//
14 #include "CheckExprLifetime.h"
15 #include "clang/AST/ASTConsumer.h"
16 #include "clang/AST/Attr.h"
17 #include "clang/AST/Expr.h"
18 #include "clang/Basic/TargetInfo.h"
19 #include "clang/Lex/Preprocessor.h"
20 #include "clang/Sema/Lookup.h"
22 using namespace clang
;
24 //===----------------------------------------------------------------------===//
25 // Pragma 'pack' and 'options align'
26 //===----------------------------------------------------------------------===//
28 Sema::PragmaStackSentinelRAII::PragmaStackSentinelRAII(Sema
&S
,
31 : S(S
), SlotLabel(SlotLabel
), ShouldAct(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
);
42 Sema::PragmaStackSentinelRAII::~PragmaStackSentinelRAII() {
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
);
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
;
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
)
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));
72 if (IsXLPragma
&& M
== AlignPackInfo::Natural
)
73 RD
->addAttr(AlignNaturalAttr::CreateImplicit(Context
));
75 if (AlignPackIncludeStack
.empty())
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
80 for (auto &AlignPackedInclude
: llvm::reverse(AlignPackIncludeStack
)) {
81 if (AlignPackedInclude
.CurrentPragmaLocation
!=
82 AlignPackStack
.CurrentPragmaLocation
)
84 if (AlignPackedInclude
.HasNonDefaultValue
)
85 AlignPackedInclude
.ShouldWarnOnInclude
= true;
89 void Sema::AddMsStructLayoutForRecord(RecordDecl
*RD
) {
91 RD
->addAttr(MSStructAttr::CreateImplicit(Context
));
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
)));
101 template <typename Attribute
>
102 static void addGslOwnerPointerAttributeIfNotExisting(ASTContext
&Context
,
103 CXXRecordDecl
*Record
) {
104 if (Record
->hasAttr
<OwnerAttr
>() || Record
->hasAttr
<PointerAttr
>())
107 for (Decl
*Redecl
: Record
->redecls())
108 Redecl
->addAttr(Attribute::CreateImplicit(Context
, /*DerefType=*/nullptr));
111 void Sema::inferGslPointerAttribute(NamedDecl
*ND
,
112 CXXRecordDecl
*UnderlyingRecord
) {
113 if (!UnderlyingRecord
)
116 const auto *Parent
= dyn_cast
<CXXRecordDecl
>(ND
->getDeclContext());
120 static const llvm::StringSet
<> Containers
{
136 "unordered_multiset",
137 "unordered_multimap",
140 static const llvm::StringSet
<> Iterators
{"iterator", "const_iterator",
142 "const_reverse_iterator"};
144 if (Parent
->isInStdNamespace() && Iterators
.count(ND
->getName()) &&
145 Containers
.count(Parent
->getName()))
146 addGslOwnerPointerAttributeIfNotExisting
<PointerAttr
>(Context
,
150 void Sema::inferGslPointerAttribute(TypedefNameDecl
*TD
) {
152 QualType Canonical
= TD
->getUnderlyingType().getCanonicalType();
154 CXXRecordDecl
*RD
= Canonical
->getAsCXXRecordDecl();
157 dyn_cast
<TemplateSpecializationType
>(Canonical
.getTypePtr())) {
159 RD
= dyn_cast_or_null
<CXXRecordDecl
>(
160 TST
->getTemplateName().getAsTemplateDecl()->getTemplatedDecl());
164 inferGslPointerAttribute(TD
, RD
);
167 void Sema::inferGslOwnerPointerAttribute(CXXRecordDecl
*Record
) {
168 static const llvm::StringSet
<> StdOwners
{
188 "unordered_multiset",
189 "unordered_multimap",
192 static const llvm::StringSet
<> StdPointers
{
199 if (!Record
->getIdentifier())
202 // Handle classes that directly appear in std namespace.
203 if (Record
->isInStdNamespace()) {
204 if (Record
->hasAttr
<OwnerAttr
>() || Record
->hasAttr
<PointerAttr
>())
207 if (StdOwners
.count(Record
->getName()))
208 addGslOwnerPointerAttributeIfNotExisting
<OwnerAttr
>(Context
, Record
);
209 else if (StdPointers
.count(Record
->getName()))
210 addGslOwnerPointerAttributeIfNotExisting
<PointerAttr
>(Context
, Record
);
215 // Handle nested classes that could be a gsl::Pointer.
216 inferGslPointerAttribute(Record
, Record
);
219 void Sema::inferLifetimeBoundAttribute(FunctionDecl
*FD
) {
220 if (FD
->getNumParams() == 0)
223 if (unsigned BuiltinID
= FD
->getBuiltinID()) {
224 // Add lifetime attribute to std::move, std::fowrard et al.
226 case Builtin::BIaddressof
:
227 case Builtin::BI__addressof
:
228 case Builtin::BI__builtin_addressof
:
229 case Builtin::BIas_const
:
230 case Builtin::BIforward
:
231 case Builtin::BIforward_like
:
232 case Builtin::BImove
:
233 case Builtin::BImove_if_noexcept
:
234 if (ParmVarDecl
*P
= FD
->getParamDecl(0u);
235 !P
->hasAttr
<LifetimeBoundAttr
>())
237 LifetimeBoundAttr::CreateImplicit(Context
, FD
->getLocation()));
244 if (auto *CMD
= dyn_cast
<CXXMethodDecl
>(FD
)) {
245 const auto *CRD
= CMD
->getParent();
246 if (!CRD
->isInStdNamespace() || !CRD
->getIdentifier())
249 if (isa
<CXXConstructorDecl
>(CMD
)) {
250 auto *Param
= CMD
->getParamDecl(0);
251 if (Param
->hasAttr
<LifetimeBoundAttr
>())
253 if (CRD
->getName() == "basic_string_view" &&
254 Param
->getType()->isPointerType()) {
255 // construct from a char array pointed by a pointer.
256 // basic_string_view(const CharT* s);
257 // basic_string_view(const CharT* s, size_type count);
259 LifetimeBoundAttr::CreateImplicit(Context
, FD
->getLocation()));
260 } else if (CRD
->getName() == "span") {
261 // construct from a reference of array.
262 // span(std::type_identity_t<element_type> (&arr)[N]);
263 const auto *LRT
= Param
->getType()->getAs
<LValueReferenceType
>();
264 if (LRT
&& LRT
->getPointeeType().IgnoreParens()->isArrayType())
266 LifetimeBoundAttr::CreateImplicit(Context
, FD
->getLocation()));
272 void Sema::inferLifetimeCaptureByAttribute(FunctionDecl
*FD
) {
273 auto *MD
= dyn_cast_if_present
<CXXMethodDecl
>(FD
);
274 if (!MD
|| !MD
->getParent()->isInStdNamespace())
276 auto Annotate
= [this](const FunctionDecl
*MD
) {
277 // Do not infer if any parameter is explicitly annotated.
278 for (ParmVarDecl
*PVD
: MD
->parameters())
279 if (PVD
->hasAttr
<LifetimeCaptureByAttr
>())
281 for (ParmVarDecl
*PVD
: MD
->parameters()) {
282 // Methods in standard containers that capture values typically accept
283 // reference-type parameters, e.g., `void push_back(const T& value)`.
284 // We only apply the lifetime_capture_by attribute to parameters of
285 // pointer-like reference types (`const T&`, `T&&`).
286 if (PVD
->getType()->isReferenceType() &&
287 sema::isPointerLikeType(PVD
->getType().getNonReferenceType())) {
288 int CaptureByThis
[] = {LifetimeCaptureByAttr::THIS
};
290 LifetimeCaptureByAttr::CreateImplicit(Context
, CaptureByThis
, 1));
295 if (!MD
->getIdentifier()) {
296 static const llvm::StringSet
<> MapLikeContainer
{
300 "unordered_multimap",
302 // Infer for the map's operator []:
303 // std::map<string_view, ...> m;
304 // m[ReturnString(..)] = ...; // !dangling references in m.
305 if (MD
->getOverloadedOperator() == OO_Subscript
&&
306 MapLikeContainer
.contains(MD
->getParent()->getName()))
310 static const llvm::StringSet
<> CapturingMethods
{"insert", "push",
311 "push_front", "push_back"};
312 if (!CapturingMethods
.contains(MD
->getName()))
317 void Sema::inferNullableClassAttribute(CXXRecordDecl
*CRD
) {
318 static const llvm::StringSet
<> Nullable
{
319 "auto_ptr", "shared_ptr", "unique_ptr", "exception_ptr",
320 "coroutine_handle", "function", "move_only_function",
323 if (CRD
->isInStdNamespace() && Nullable
.count(CRD
->getName()) &&
324 !CRD
->hasAttr
<TypeNullableAttr
>())
325 for (Decl
*Redecl
: CRD
->redecls())
326 Redecl
->addAttr(TypeNullableAttr::CreateImplicit(Context
));
329 void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind
,
330 SourceLocation PragmaLoc
) {
331 PragmaMsStackAction Action
= Sema::PSK_Reset
;
332 AlignPackInfo::Mode ModeVal
= AlignPackInfo::Native
;
335 // For most of the platforms we support, native and natural are the same.
336 // With XL, native is the same as power, natural means something else.
339 Action
= Sema::PSK_Push_Set
;
342 Action
= Sema::PSK_Push_Set
;
343 ModeVal
= AlignPackInfo::Natural
;
346 // Note that '#pragma options align=packed' is not equivalent to attribute
347 // packed, it has a different precedence relative to attribute aligned.
349 Action
= Sema::PSK_Push_Set
;
350 ModeVal
= AlignPackInfo::Packed
;
354 // Check if the target supports this.
355 if (!this->Context
.getTargetInfo().hasAlignMac68kSupport()) {
356 Diag(PragmaLoc
, diag::err_pragma_options_align_mac68k_target_unsupported
);
359 Action
= Sema::PSK_Push_Set
;
360 ModeVal
= AlignPackInfo::Mac68k
;
363 // Reset just pops the top of the stack, or resets the current alignment to
365 Action
= Sema::PSK_Pop
;
366 if (AlignPackStack
.Stack
.empty()) {
367 if (AlignPackStack
.CurrentValue
.getAlignMode() != AlignPackInfo::Native
||
368 AlignPackStack
.CurrentValue
.IsPackAttr()) {
369 Action
= Sema::PSK_Reset
;
371 Diag(PragmaLoc
, diag::warn_pragma_options_align_reset_failed
)
379 AlignPackInfo
Info(ModeVal
, getLangOpts().XLPragmaPack
);
381 AlignPackStack
.Act(PragmaLoc
, Action
, StringRef(), Info
);
384 void Sema::ActOnPragmaClangSection(SourceLocation PragmaLoc
,
385 PragmaClangSectionAction Action
,
386 PragmaClangSectionKind SecKind
,
388 PragmaClangSection
*CSec
;
389 int SectionFlags
= ASTContext::PSF_Read
;
391 case PragmaClangSectionKind::PCSK_BSS
:
392 CSec
= &PragmaClangBSSSection
;
393 SectionFlags
|= ASTContext::PSF_Write
| ASTContext::PSF_ZeroInit
;
395 case PragmaClangSectionKind::PCSK_Data
:
396 CSec
= &PragmaClangDataSection
;
397 SectionFlags
|= ASTContext::PSF_Write
;
399 case PragmaClangSectionKind::PCSK_Rodata
:
400 CSec
= &PragmaClangRodataSection
;
402 case PragmaClangSectionKind::PCSK_Relro
:
403 CSec
= &PragmaClangRelroSection
;
405 case PragmaClangSectionKind::PCSK_Text
:
406 CSec
= &PragmaClangTextSection
;
407 SectionFlags
|= ASTContext::PSF_Execute
;
410 llvm_unreachable("invalid clang section kind");
413 if (Action
== PragmaClangSectionAction::PCSA_Clear
) {
418 if (llvm::Error E
= isValidSectionSpecifier(SecName
)) {
419 Diag(PragmaLoc
, diag::err_pragma_section_invalid_for_target
)
420 << toString(std::move(E
));
425 if (UnifySection(SecName
, SectionFlags
, PragmaLoc
))
429 CSec
->SectionName
= std::string(SecName
);
430 CSec
->PragmaLocation
= PragmaLoc
;
433 void Sema::ActOnPragmaPack(SourceLocation PragmaLoc
, PragmaMsStackAction Action
,
434 StringRef SlotLabel
, Expr
*alignment
) {
435 bool IsXLPragma
= getLangOpts().XLPragmaPack
;
436 // XL pragma pack does not support identifier syntax.
437 if (IsXLPragma
&& !SlotLabel
.empty()) {
438 Diag(PragmaLoc
, diag::err_pragma_pack_identifer_not_supported
);
442 const AlignPackInfo CurVal
= AlignPackStack
.CurrentValue
;
443 Expr
*Alignment
= static_cast<Expr
*>(alignment
);
445 // If specified then alignment must be a "small" power of two.
446 unsigned AlignmentVal
= 0;
447 AlignPackInfo::Mode ModeVal
= CurVal
.getAlignMode();
450 std::optional
<llvm::APSInt
> Val
;
451 Val
= Alignment
->getIntegerConstantExpr(Context
);
453 // pack(0) is like pack(), which just works out since that is what
454 // we use 0 for in PackAttr.
455 if (Alignment
->isTypeDependent() || !Val
||
456 !(*Val
== 0 || Val
->isPowerOf2()) || Val
->getZExtValue() > 16) {
457 Diag(PragmaLoc
, diag::warn_pragma_pack_invalid_alignment
);
461 if (IsXLPragma
&& *Val
== 0) {
462 // pack(0) does not work out with XL.
463 Diag(PragmaLoc
, diag::err_pragma_pack_invalid_alignment
);
467 AlignmentVal
= (unsigned)Val
->getZExtValue();
470 if (Action
== Sema::PSK_Show
) {
471 // Show the current alignment, making sure to show the right value
473 // FIXME: This should come from the target.
474 AlignmentVal
= CurVal
.IsPackSet() ? CurVal
.getPackNumber() : 8;
475 if (ModeVal
== AlignPackInfo::Mac68k
&&
476 (IsXLPragma
|| CurVal
.IsAlignAttr()))
477 Diag(PragmaLoc
, diag::warn_pragma_pack_show
) << "mac68k";
479 Diag(PragmaLoc
, diag::warn_pragma_pack_show
) << AlignmentVal
;
482 // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
483 // "#pragma pack(pop, identifier, n) is undefined"
484 if (Action
& Sema::PSK_Pop
) {
485 if (Alignment
&& !SlotLabel
.empty())
486 Diag(PragmaLoc
, diag::warn_pragma_pack_pop_identifier_and_alignment
);
487 if (AlignPackStack
.Stack
.empty()) {
488 assert(CurVal
.getAlignMode() == AlignPackInfo::Native
&&
489 "Empty pack stack can only be at Native alignment mode.");
490 Diag(PragmaLoc
, diag::warn_pragma_pop_failed
) << "pack" << "stack empty";
494 AlignPackInfo
Info(ModeVal
, AlignmentVal
, IsXLPragma
);
496 AlignPackStack
.Act(PragmaLoc
, Action
, SlotLabel
, Info
);
499 bool Sema::ConstantFoldAttrArgs(const AttributeCommonInfo
&CI
,
500 MutableArrayRef
<Expr
*> Args
) {
501 llvm::SmallVector
<PartialDiagnosticAt
, 8> Notes
;
502 for (unsigned Idx
= 0; Idx
< Args
.size(); Idx
++) {
503 Expr
*&E
= Args
.begin()[Idx
];
504 assert(E
&& "error are handled before");
505 if (E
->isValueDependent() || E
->isTypeDependent())
508 // FIXME: Use DefaultFunctionArrayLValueConversion() in place of the logic
509 // that adds implicit casts here.
510 if (E
->getType()->isArrayType())
511 E
= ImpCastExprToType(E
, Context
.getPointerType(E
->getType()),
512 clang::CK_ArrayToPointerDecay
)
514 if (E
->getType()->isFunctionType())
515 E
= ImplicitCastExpr::Create(Context
,
516 Context
.getPointerType(E
->getType()),
517 clang::CK_FunctionToPointerDecay
, E
, nullptr,
518 VK_PRValue
, FPOptionsOverride());
520 E
= ImplicitCastExpr::Create(Context
, E
->getType().getNonReferenceType(),
521 clang::CK_LValueToRValue
, E
, nullptr,
522 VK_PRValue
, FPOptionsOverride());
524 Expr::EvalResult Eval
;
528 bool Result
= E
->EvaluateAsConstantExpr(Eval
, Context
);
530 /// Result means the expression can be folded to a constant.
531 /// Note.empty() means the expression is a valid constant expression in the
532 /// current language mode.
533 if (!Result
|| !Notes
.empty()) {
534 Diag(E
->getBeginLoc(), diag::err_attribute_argument_n_type
)
535 << CI
<< (Idx
+ 1) << AANT_ArgumentConstantExpr
;
536 for (auto &Note
: Notes
)
537 Diag(Note
.first
, Note
.second
);
540 assert(Eval
.Val
.hasValue());
541 E
= ConstantExpr::Create(Context
, E
, Eval
.Val
);
547 void Sema::DiagnoseNonDefaultPragmaAlignPack(PragmaAlignPackDiagnoseKind Kind
,
548 SourceLocation IncludeLoc
) {
549 if (Kind
== PragmaAlignPackDiagnoseKind::NonDefaultStateAtInclude
) {
550 SourceLocation PrevLocation
= AlignPackStack
.CurrentPragmaLocation
;
551 // Warn about non-default alignment at #includes (without redundant
552 // warnings for the same directive in nested includes).
553 // The warning is delayed until the end of the file to avoid warnings
554 // for files that don't have any records that are affected by the modified
556 bool HasNonDefaultValue
=
557 AlignPackStack
.hasValue() &&
558 (AlignPackIncludeStack
.empty() ||
559 AlignPackIncludeStack
.back().CurrentPragmaLocation
!= PrevLocation
);
560 AlignPackIncludeStack
.push_back(
561 {AlignPackStack
.CurrentValue
,
562 AlignPackStack
.hasValue() ? PrevLocation
: SourceLocation(),
563 HasNonDefaultValue
, /*ShouldWarnOnInclude*/ false});
567 assert(Kind
== PragmaAlignPackDiagnoseKind::ChangedStateAtExit
&&
569 AlignPackIncludeState PrevAlignPackState
=
570 AlignPackIncludeStack
.pop_back_val();
571 // FIXME: AlignPackStack may contain both #pragma align and #pragma pack
572 // information, diagnostics below might not be accurate if we have mixed
574 if (PrevAlignPackState
.ShouldWarnOnInclude
) {
575 // Emit the delayed non-default alignment at #include warning.
576 Diag(IncludeLoc
, diag::warn_pragma_pack_non_default_at_include
);
577 Diag(PrevAlignPackState
.CurrentPragmaLocation
, diag::note_pragma_pack_here
);
579 // Warn about modified alignment after #includes.
580 if (PrevAlignPackState
.CurrentValue
!= AlignPackStack
.CurrentValue
) {
581 Diag(IncludeLoc
, diag::warn_pragma_pack_modified_after_include
);
582 Diag(AlignPackStack
.CurrentPragmaLocation
, diag::note_pragma_pack_here
);
586 void Sema::DiagnoseUnterminatedPragmaAlignPack() {
587 if (AlignPackStack
.Stack
.empty())
589 bool IsInnermost
= true;
591 // FIXME: AlignPackStack may contain both #pragma align and #pragma pack
592 // information, diagnostics below might not be accurate if we have mixed
594 for (const auto &StackSlot
: llvm::reverse(AlignPackStack
.Stack
)) {
595 Diag(StackSlot
.PragmaPushLocation
, diag::warn_pragma_pack_no_pop_eof
);
596 // The user might have already reset the alignment, so suggest replacing
597 // the reset with a pop.
599 AlignPackStack
.CurrentValue
== AlignPackStack
.DefaultValue
) {
600 auto DB
= Diag(AlignPackStack
.CurrentPragmaLocation
,
601 diag::note_pragma_pack_pop_instead_reset
);
602 SourceLocation FixItLoc
=
603 Lexer::findLocationAfterToken(AlignPackStack
.CurrentPragmaLocation
,
604 tok::l_paren
, SourceMgr
, LangOpts
,
605 /*SkipTrailing=*/false);
606 if (FixItLoc
.isValid())
607 DB
<< FixItHint::CreateInsertion(FixItLoc
, "pop");
613 void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind
) {
614 MSStructPragmaOn
= (Kind
== PMSST_ON
);
617 void Sema::ActOnPragmaMSComment(SourceLocation CommentLoc
,
618 PragmaMSCommentKind Kind
, StringRef Arg
) {
619 auto *PCD
= PragmaCommentDecl::Create(
620 Context
, Context
.getTranslationUnitDecl(), CommentLoc
, Kind
, Arg
);
621 Context
.getTranslationUnitDecl()->addDecl(PCD
);
622 Consumer
.HandleTopLevelDecl(DeclGroupRef(PCD
));
625 void Sema::ActOnPragmaDetectMismatch(SourceLocation Loc
, StringRef Name
,
627 auto *PDMD
= PragmaDetectMismatchDecl::Create(
628 Context
, Context
.getTranslationUnitDecl(), Loc
, Name
, Value
);
629 Context
.getTranslationUnitDecl()->addDecl(PDMD
);
630 Consumer
.HandleTopLevelDecl(DeclGroupRef(PDMD
));
633 void Sema::ActOnPragmaFPEvalMethod(SourceLocation Loc
,
634 LangOptions::FPEvalMethodKind Value
) {
635 FPOptionsOverride NewFPFeatures
= CurFPFeatureOverrides();
638 llvm_unreachable("invalid pragma eval_method kind");
639 case LangOptions::FEM_Source
:
640 NewFPFeatures
.setFPEvalMethodOverride(LangOptions::FEM_Source
);
642 case LangOptions::FEM_Double
:
643 NewFPFeatures
.setFPEvalMethodOverride(LangOptions::FEM_Double
);
645 case LangOptions::FEM_Extended
:
646 NewFPFeatures
.setFPEvalMethodOverride(LangOptions::FEM_Extended
);
649 if (getLangOpts().ApproxFunc
)
650 Diag(Loc
, diag::err_setting_eval_method_used_in_unsafe_context
) << 0 << 0;
651 if (getLangOpts().AllowFPReassoc
)
652 Diag(Loc
, diag::err_setting_eval_method_used_in_unsafe_context
) << 0 << 1;
653 if (getLangOpts().AllowRecip
)
654 Diag(Loc
, diag::err_setting_eval_method_used_in_unsafe_context
) << 0 << 2;
655 FpPragmaStack
.Act(Loc
, PSK_Set
, StringRef(), NewFPFeatures
);
656 CurFPFeatures
= NewFPFeatures
.applyOverrides(getLangOpts());
657 PP
.setCurrentFPEvalMethod(Loc
, Value
);
660 void Sema::ActOnPragmaFloatControl(SourceLocation Loc
,
661 PragmaMsStackAction Action
,
662 PragmaFloatControlKind Value
) {
663 FPOptionsOverride NewFPFeatures
= CurFPFeatureOverrides();
664 if ((Action
== PSK_Push_Set
|| Action
== PSK_Push
|| Action
== PSK_Pop
) &&
665 !CurContext
->getRedeclContext()->isFileContext()) {
666 // Push and pop can only occur at file or namespace scope, or within a
667 // language linkage declaration.
668 Diag(Loc
, diag::err_pragma_fc_pp_scope
);
673 llvm_unreachable("invalid pragma float_control kind");
675 NewFPFeatures
.setFPPreciseEnabled(true);
676 FpPragmaStack
.Act(Loc
, Action
, StringRef(), NewFPFeatures
);
679 if (CurFPFeatures
.getExceptionMode() == LangOptions::FPE_Strict
)
680 Diag(Loc
, diag::err_pragma_fc_noprecise_requires_noexcept
);
681 else if (CurFPFeatures
.getAllowFEnvAccess())
682 Diag(Loc
, diag::err_pragma_fc_noprecise_requires_nofenv
);
684 NewFPFeatures
.setFPPreciseEnabled(false);
685 FpPragmaStack
.Act(Loc
, Action
, StringRef(), NewFPFeatures
);
688 if (!isPreciseFPEnabled())
689 Diag(Loc
, diag::err_pragma_fc_except_requires_precise
);
691 NewFPFeatures
.setSpecifiedExceptionModeOverride(LangOptions::FPE_Strict
);
692 FpPragmaStack
.Act(Loc
, Action
, StringRef(), NewFPFeatures
);
695 NewFPFeatures
.setSpecifiedExceptionModeOverride(LangOptions::FPE_Ignore
);
696 FpPragmaStack
.Act(Loc
, Action
, StringRef(), NewFPFeatures
);
699 FpPragmaStack
.Act(Loc
, Sema::PSK_Push_Set
, StringRef(), NewFPFeatures
);
702 if (FpPragmaStack
.Stack
.empty()) {
703 Diag(Loc
, diag::warn_pragma_pop_failed
) << "float_control"
707 FpPragmaStack
.Act(Loc
, Action
, StringRef(), NewFPFeatures
);
708 NewFPFeatures
= FpPragmaStack
.CurrentValue
;
711 CurFPFeatures
= NewFPFeatures
.applyOverrides(getLangOpts());
714 void Sema::ActOnPragmaMSPointersToMembers(
715 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod
,
716 SourceLocation PragmaLoc
) {
717 MSPointerToMemberRepresentationMethod
= RepresentationMethod
;
718 ImplicitMSInheritanceAttrLoc
= PragmaLoc
;
721 void Sema::ActOnPragmaMSVtorDisp(PragmaMsStackAction Action
,
722 SourceLocation PragmaLoc
,
723 MSVtorDispMode Mode
) {
724 if (Action
& PSK_Pop
&& VtorDispStack
.Stack
.empty())
725 Diag(PragmaLoc
, diag::warn_pragma_pop_failed
) << "vtordisp"
727 VtorDispStack
.Act(PragmaLoc
, Action
, StringRef(), Mode
);
731 void Sema::PragmaStack
<Sema::AlignPackInfo
>::Act(SourceLocation PragmaLocation
,
732 PragmaMsStackAction Action
,
733 llvm::StringRef StackSlotLabel
,
734 AlignPackInfo Value
) {
735 if (Action
== PSK_Reset
) {
736 CurrentValue
= DefaultValue
;
737 CurrentPragmaLocation
= PragmaLocation
;
740 if (Action
& PSK_Push
)
741 Stack
.emplace_back(Slot(StackSlotLabel
, CurrentValue
, CurrentPragmaLocation
,
743 else if (Action
& PSK_Pop
) {
744 if (!StackSlotLabel
.empty()) {
745 // If we've got a label, try to find it and jump there.
746 auto I
= llvm::find_if(llvm::reverse(Stack
), [&](const Slot
&x
) {
747 return x
.StackSlotLabel
== StackSlotLabel
;
749 // We found the label, so pop from there.
750 if (I
!= Stack
.rend()) {
751 CurrentValue
= I
->Value
;
752 CurrentPragmaLocation
= I
->PragmaLocation
;
753 Stack
.erase(std::prev(I
.base()), Stack
.end());
755 } else if (Value
.IsXLStack() && Value
.IsAlignAttr() &&
756 CurrentValue
.IsPackAttr()) {
757 // XL '#pragma align(reset)' would pop the stack until
758 // a current in effect pragma align is popped.
759 auto I
= llvm::find_if(llvm::reverse(Stack
), [&](const Slot
&x
) {
760 return x
.Value
.IsAlignAttr();
762 // If we found pragma align so pop from there.
763 if (I
!= Stack
.rend()) {
764 Stack
.erase(std::prev(I
.base()), Stack
.end());
766 CurrentValue
= DefaultValue
;
767 CurrentPragmaLocation
= PragmaLocation
;
769 CurrentValue
= Stack
.back().Value
;
770 CurrentPragmaLocation
= Stack
.back().PragmaLocation
;
774 } else if (!Stack
.empty()) {
775 // xl '#pragma align' sets the baseline, and `#pragma pack` cannot pop
776 // over the baseline.
777 if (Value
.IsXLStack() && Value
.IsPackAttr() && CurrentValue
.IsAlignAttr())
780 // We don't have a label, just pop the last entry.
781 CurrentValue
= Stack
.back().Value
;
782 CurrentPragmaLocation
= Stack
.back().PragmaLocation
;
786 if (Action
& PSK_Set
) {
787 CurrentValue
= Value
;
788 CurrentPragmaLocation
= PragmaLocation
;
792 bool Sema::UnifySection(StringRef SectionName
, int SectionFlags
,
794 SourceLocation PragmaLocation
;
795 if (auto A
= Decl
->getAttr
<SectionAttr
>())
797 PragmaLocation
= A
->getLocation();
798 auto [SectionIt
, Inserted
] = Context
.SectionInfos
.try_emplace(
799 SectionName
, Decl
, PragmaLocation
, SectionFlags
);
802 // A pre-declared section takes precedence w/o diagnostic.
803 const auto &Section
= SectionIt
->second
;
804 if (Section
.SectionFlags
== SectionFlags
||
805 ((SectionFlags
& ASTContext::PSF_Implicit
) &&
806 !(Section
.SectionFlags
& ASTContext::PSF_Implicit
)))
808 Diag(Decl
->getLocation(), diag::err_section_conflict
) << Decl
<< Section
;
810 Diag(Section
.Decl
->getLocation(), diag::note_declared_at
)
811 << Section
.Decl
->getName();
812 if (PragmaLocation
.isValid())
813 Diag(PragmaLocation
, diag::note_pragma_entered_here
);
814 if (Section
.PragmaSectionLocation
.isValid())
815 Diag(Section
.PragmaSectionLocation
, diag::note_pragma_entered_here
);
819 bool Sema::UnifySection(StringRef SectionName
,
821 SourceLocation PragmaSectionLocation
) {
822 auto SectionIt
= Context
.SectionInfos
.find(SectionName
);
823 if (SectionIt
!= Context
.SectionInfos
.end()) {
824 const auto &Section
= SectionIt
->second
;
825 if (Section
.SectionFlags
== SectionFlags
)
827 if (!(Section
.SectionFlags
& ASTContext::PSF_Implicit
)) {
828 Diag(PragmaSectionLocation
, diag::err_section_conflict
)
829 << "this" << Section
;
831 Diag(Section
.Decl
->getLocation(), diag::note_declared_at
)
832 << Section
.Decl
->getName();
833 if (Section
.PragmaSectionLocation
.isValid())
834 Diag(Section
.PragmaSectionLocation
, diag::note_pragma_entered_here
);
838 Context
.SectionInfos
[SectionName
] =
839 ASTContext::SectionInfo(nullptr, PragmaSectionLocation
, SectionFlags
);
843 /// Called on well formed \#pragma bss_seg().
844 void Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation
,
845 PragmaMsStackAction Action
,
846 llvm::StringRef StackSlotLabel
,
847 StringLiteral
*SegmentName
,
848 llvm::StringRef PragmaName
) {
849 PragmaStack
<StringLiteral
*> *Stack
=
850 llvm::StringSwitch
<PragmaStack
<StringLiteral
*> *>(PragmaName
)
851 .Case("data_seg", &DataSegStack
)
852 .Case("bss_seg", &BSSSegStack
)
853 .Case("const_seg", &ConstSegStack
)
854 .Case("code_seg", &CodeSegStack
);
855 if (Action
& PSK_Pop
&& Stack
->Stack
.empty())
856 Diag(PragmaLocation
, diag::warn_pragma_pop_failed
) << PragmaName
859 if (!checkSectionName(SegmentName
->getBeginLoc(), SegmentName
->getString()))
862 if (SegmentName
->getString() == ".drectve" &&
863 Context
.getTargetInfo().getCXXABI().isMicrosoft())
864 Diag(PragmaLocation
, diag::warn_attribute_section_drectve
) << PragmaName
;
867 Stack
->Act(PragmaLocation
, Action
, StackSlotLabel
, SegmentName
);
870 /// Called on well formed \#pragma strict_gs_check().
871 void Sema::ActOnPragmaMSStrictGuardStackCheck(SourceLocation PragmaLocation
,
872 PragmaMsStackAction Action
,
874 if (Action
& PSK_Pop
&& StrictGuardStackCheckStack
.Stack
.empty())
875 Diag(PragmaLocation
, diag::warn_pragma_pop_failed
) << "strict_gs_check"
878 StrictGuardStackCheckStack
.Act(PragmaLocation
, Action
, StringRef(), Value
);
881 /// Called on well formed \#pragma bss_seg().
882 void Sema::ActOnPragmaMSSection(SourceLocation PragmaLocation
,
883 int SectionFlags
, StringLiteral
*SegmentName
) {
884 UnifySection(SegmentName
->getString(), SectionFlags
, PragmaLocation
);
887 void Sema::ActOnPragmaMSInitSeg(SourceLocation PragmaLocation
,
888 StringLiteral
*SegmentName
) {
889 // There's no stack to maintain, so we just have a current section. When we
890 // see the default section, reset our current section back to null so we stop
891 // tacking on unnecessary attributes.
892 CurInitSeg
= SegmentName
->getString() == ".CRT$XCU" ? nullptr : SegmentName
;
893 CurInitSegLoc
= PragmaLocation
;
896 void Sema::ActOnPragmaMSAllocText(
897 SourceLocation PragmaLocation
, StringRef Section
,
898 const SmallVector
<std::tuple
<IdentifierInfo
*, SourceLocation
>>
900 if (!CurContext
->getRedeclContext()->isFileContext()) {
901 Diag(PragmaLocation
, diag::err_pragma_expected_file_scope
) << "alloc_text";
905 for (auto &Function
: Functions
) {
908 std::tie(II
, Loc
) = Function
;
910 DeclarationName
DN(II
);
911 NamedDecl
*ND
= LookupSingleName(TUScope
, DN
, Loc
, LookupOrdinaryName
);
913 Diag(Loc
, diag::err_undeclared_use
) << II
->getName();
917 auto *FD
= dyn_cast
<FunctionDecl
>(ND
->getCanonicalDecl());
919 Diag(Loc
, diag::err_pragma_alloc_text_not_function
);
923 if (getLangOpts().CPlusPlus
&& !FD
->isInExternCContext()) {
924 Diag(Loc
, diag::err_pragma_alloc_text_c_linkage
);
928 FunctionToSectionMap
[II
->getName()] = std::make_tuple(Section
, Loc
);
932 void Sema::ActOnPragmaUnused(const Token
&IdTok
, Scope
*curScope
,
933 SourceLocation PragmaLoc
) {
935 IdentifierInfo
*Name
= IdTok
.getIdentifierInfo();
936 LookupResult
Lookup(*this, Name
, IdTok
.getLocation(), LookupOrdinaryName
);
937 LookupName(Lookup
, curScope
, /*AllowBuiltinCreation=*/true);
939 if (Lookup
.empty()) {
940 Diag(PragmaLoc
, diag::warn_pragma_unused_undeclared_var
)
941 << Name
<< SourceRange(IdTok
.getLocation());
945 VarDecl
*VD
= Lookup
.getAsSingle
<VarDecl
>();
947 Diag(PragmaLoc
, diag::warn_pragma_unused_expected_var_arg
)
948 << Name
<< SourceRange(IdTok
.getLocation());
952 // Warn if this was used before being marked unused.
954 Diag(PragmaLoc
, diag::warn_used_but_marked_unused
) << Name
;
956 VD
->addAttr(UnusedAttr::CreateImplicit(Context
, IdTok
.getLocation(),
957 UnusedAttr::GNU_unused
));
962 std::optional
<attr::SubjectMatchRule
>
963 getParentAttrMatcherRule(attr::SubjectMatchRule Rule
) {
964 using namespace attr
;
968 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
969 #define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \
972 #include "clang/Basic/AttrSubMatchRulesList.inc"
976 bool isNegatedAttrMatcherSubRule(attr::SubjectMatchRule Rule
) {
977 using namespace attr
;
981 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
982 #define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \
985 #include "clang/Basic/AttrSubMatchRulesList.inc"
989 CharSourceRange
replacementRangeForListElement(const Sema
&S
,
991 // Make sure that the ',' is removed as well.
992 SourceLocation AfterCommaLoc
= Lexer::findLocationAfterToken(
993 Range
.getEnd(), tok::comma
, S
.getSourceManager(), S
.getLangOpts(),
994 /*SkipTrailingWhitespaceAndNewLine=*/false);
995 if (AfterCommaLoc
.isValid())
996 return CharSourceRange::getCharRange(Range
.getBegin(), AfterCommaLoc
);
998 return CharSourceRange::getTokenRange(Range
);
1002 attrMatcherRuleListToString(ArrayRef
<attr::SubjectMatchRule
> Rules
) {
1004 llvm::raw_string_ostream
OS(Result
);
1005 for (const auto &I
: llvm::enumerate(Rules
)) {
1007 OS
<< (I
.index() == Rules
.size() - 1 ? ", and " : ", ");
1008 OS
<< "'" << attr::getSubjectMatchRuleSpelling(I
.value()) << "'";
1013 } // end anonymous namespace
1015 void Sema::ActOnPragmaAttributeAttribute(
1016 ParsedAttr
&Attribute
, SourceLocation PragmaLoc
,
1017 attr::ParsedSubjectMatchRuleSet Rules
) {
1018 Attribute
.setIsPragmaClangAttribute();
1019 SmallVector
<attr::SubjectMatchRule
, 4> SubjectMatchRules
;
1020 // Gather the subject match rules that are supported by the attribute.
1021 SmallVector
<std::pair
<attr::SubjectMatchRule
, bool>, 4>
1022 StrictSubjectMatchRuleSet
;
1023 Attribute
.getMatchRules(LangOpts
, StrictSubjectMatchRuleSet
);
1025 // Figure out which subject matching rules are valid.
1026 if (StrictSubjectMatchRuleSet
.empty()) {
1027 // Check for contradicting match rules. Contradicting match rules are
1029 // - a top-level rule and one of its sub-rules. E.g. variable and
1030 // variable(is_parameter).
1031 // - a sub-rule and a sibling that's negated. E.g.
1032 // variable(is_thread_local) and variable(unless(is_parameter))
1033 llvm::SmallDenseMap
<int, std::pair
<int, SourceRange
>, 2>
1034 RulesToFirstSpecifiedNegatedSubRule
;
1035 for (const auto &Rule
: Rules
) {
1036 attr::SubjectMatchRule MatchRule
= attr::SubjectMatchRule(Rule
.first
);
1037 std::optional
<attr::SubjectMatchRule
> ParentRule
=
1038 getParentAttrMatcherRule(MatchRule
);
1041 auto It
= Rules
.find(*ParentRule
);
1042 if (It
!= Rules
.end()) {
1043 // A sub-rule contradicts a parent rule.
1044 Diag(Rule
.second
.getBegin(),
1045 diag::err_pragma_attribute_matcher_subrule_contradicts_rule
)
1046 << attr::getSubjectMatchRuleSpelling(MatchRule
)
1047 << attr::getSubjectMatchRuleSpelling(*ParentRule
) << It
->second
1048 << FixItHint::CreateRemoval(
1049 replacementRangeForListElement(*this, Rule
.second
));
1050 // Keep going without removing this rule as it won't change the set of
1051 // declarations that receive the attribute.
1054 if (isNegatedAttrMatcherSubRule(MatchRule
))
1055 RulesToFirstSpecifiedNegatedSubRule
.insert(
1056 std::make_pair(*ParentRule
, Rule
));
1058 bool IgnoreNegatedSubRules
= false;
1059 for (const auto &Rule
: Rules
) {
1060 attr::SubjectMatchRule MatchRule
= attr::SubjectMatchRule(Rule
.first
);
1061 std::optional
<attr::SubjectMatchRule
> ParentRule
=
1062 getParentAttrMatcherRule(MatchRule
);
1065 auto It
= RulesToFirstSpecifiedNegatedSubRule
.find(*ParentRule
);
1066 if (It
!= RulesToFirstSpecifiedNegatedSubRule
.end() &&
1067 It
->second
!= Rule
) {
1068 // Negated sub-rule contradicts another sub-rule.
1070 It
->second
.second
.getBegin(),
1072 err_pragma_attribute_matcher_negated_subrule_contradicts_subrule
)
1073 << attr::getSubjectMatchRuleSpelling(
1074 attr::SubjectMatchRule(It
->second
.first
))
1075 << attr::getSubjectMatchRuleSpelling(MatchRule
) << Rule
.second
1076 << FixItHint::CreateRemoval(
1077 replacementRangeForListElement(*this, It
->second
.second
));
1078 // Keep going but ignore all of the negated sub-rules.
1079 IgnoreNegatedSubRules
= true;
1080 RulesToFirstSpecifiedNegatedSubRule
.erase(It
);
1084 if (!IgnoreNegatedSubRules
) {
1085 for (const auto &Rule
: Rules
)
1086 SubjectMatchRules
.push_back(attr::SubjectMatchRule(Rule
.first
));
1088 for (const auto &Rule
: Rules
) {
1089 if (!isNegatedAttrMatcherSubRule(attr::SubjectMatchRule(Rule
.first
)))
1090 SubjectMatchRules
.push_back(attr::SubjectMatchRule(Rule
.first
));
1095 // Each rule in Rules must be a strict subset of the attribute's
1096 // SubjectMatch rules. I.e. we're allowed to use
1097 // `apply_to=variables(is_global)` on an attrubute with SubjectList<[Var]>,
1098 // but should not allow `apply_to=variables` on an attribute which has
1099 // `SubjectList<[GlobalVar]>`.
1100 for (const auto &StrictRule
: StrictSubjectMatchRuleSet
) {
1101 // First, check for exact match.
1102 if (Rules
.erase(StrictRule
.first
)) {
1103 // Add the rule to the set of attribute receivers only if it's supported
1104 // in the current language mode.
1105 if (StrictRule
.second
)
1106 SubjectMatchRules
.push_back(StrictRule
.first
);
1109 // Check remaining rules for subset matches.
1110 auto RulesToCheck
= Rules
;
1111 for (const auto &Rule
: RulesToCheck
) {
1112 attr::SubjectMatchRule MatchRule
= attr::SubjectMatchRule(Rule
.first
);
1113 if (auto ParentRule
= getParentAttrMatcherRule(MatchRule
)) {
1114 if (llvm::any_of(StrictSubjectMatchRuleSet
,
1115 [ParentRule
](const auto &StrictRule
) {
1116 return StrictRule
.first
== *ParentRule
&&
1117 StrictRule
.second
; // IsEnabled
1119 SubjectMatchRules
.push_back(MatchRule
);
1120 Rules
.erase(MatchRule
);
1126 if (!Rules
.empty()) {
1128 Diag(PragmaLoc
, diag::err_pragma_attribute_invalid_matchers
)
1130 SmallVector
<attr::SubjectMatchRule
, 2> ExtraRules
;
1131 for (const auto &Rule
: Rules
) {
1132 ExtraRules
.push_back(attr::SubjectMatchRule(Rule
.first
));
1133 Diagnostic
<< FixItHint::CreateRemoval(
1134 replacementRangeForListElement(*this, Rule
.second
));
1136 Diagnostic
<< attrMatcherRuleListToString(ExtraRules
);
1139 if (PragmaAttributeStack
.empty()) {
1140 Diag(PragmaLoc
, diag::err_pragma_attr_attr_no_push
);
1144 PragmaAttributeStack
.back().Entries
.push_back(
1145 {PragmaLoc
, &Attribute
, std::move(SubjectMatchRules
), /*IsUsed=*/false});
1148 void Sema::ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc
,
1149 const IdentifierInfo
*Namespace
) {
1150 PragmaAttributeStack
.emplace_back();
1151 PragmaAttributeStack
.back().Loc
= PragmaLoc
;
1152 PragmaAttributeStack
.back().Namespace
= Namespace
;
1155 void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc
,
1156 const IdentifierInfo
*Namespace
) {
1157 if (PragmaAttributeStack
.empty()) {
1158 Diag(PragmaLoc
, diag::err_pragma_attribute_stack_mismatch
) << 1;
1162 // Dig back through the stack trying to find the most recently pushed group
1163 // that in Namespace. Note that this works fine if no namespace is present,
1164 // think of push/pops without namespaces as having an implicit "nullptr"
1166 for (size_t Index
= PragmaAttributeStack
.size(); Index
;) {
1168 if (PragmaAttributeStack
[Index
].Namespace
== Namespace
) {
1169 for (const PragmaAttributeEntry
&Entry
:
1170 PragmaAttributeStack
[Index
].Entries
) {
1171 if (!Entry
.IsUsed
) {
1172 assert(Entry
.Attribute
&& "Expected an attribute");
1173 Diag(Entry
.Attribute
->getLoc(), diag::warn_pragma_attribute_unused
)
1174 << *Entry
.Attribute
;
1175 Diag(PragmaLoc
, diag::note_pragma_attribute_region_ends_here
);
1178 PragmaAttributeStack
.erase(PragmaAttributeStack
.begin() + Index
);
1184 Diag(PragmaLoc
, diag::err_pragma_attribute_stack_mismatch
)
1185 << 0 << Namespace
->getName();
1187 Diag(PragmaLoc
, diag::err_pragma_attribute_stack_mismatch
) << 1;
1190 void Sema::AddPragmaAttributes(Scope
*S
, Decl
*D
) {
1191 if (PragmaAttributeStack
.empty())
1193 for (auto &Group
: PragmaAttributeStack
) {
1194 for (auto &Entry
: Group
.Entries
) {
1195 ParsedAttr
*Attribute
= Entry
.Attribute
;
1196 assert(Attribute
&& "Expected an attribute");
1197 assert(Attribute
->isPragmaClangAttribute() &&
1198 "expected #pragma clang attribute");
1200 // Ensure that the attribute can be applied to the given declaration.
1201 bool Applies
= false;
1202 for (const auto &Rule
: Entry
.MatchRules
) {
1203 if (Attribute
->appliesToDecl(D
, Rule
)) {
1210 Entry
.IsUsed
= true;
1211 PragmaAttributeCurrentTargetDecl
= D
;
1212 ParsedAttributesView Attrs
;
1213 Attrs
.addAtEnd(Attribute
);
1214 ProcessDeclAttributeList(S
, D
, Attrs
);
1215 PragmaAttributeCurrentTargetDecl
= nullptr;
1220 void Sema::PrintPragmaAttributeInstantiationPoint() {
1221 assert(PragmaAttributeCurrentTargetDecl
&& "Expected an active declaration");
1222 Diags
.Report(PragmaAttributeCurrentTargetDecl
->getBeginLoc(),
1223 diag::note_pragma_attribute_applied_decl_here
);
1226 void Sema::DiagnosePrecisionLossInComplexDivision() {
1227 for (auto &[Type
, Num
] : ExcessPrecisionNotSatisfied
) {
1228 assert(LocationOfExcessPrecisionNotSatisfied
.isValid() &&
1229 "expected a valid source location");
1230 Diag(LocationOfExcessPrecisionNotSatisfied
,
1231 diag::warn_excess_precision_not_supported
)
1232 << static_cast<bool>(Num
);
1236 void Sema::DiagnoseUnterminatedPragmaAttribute() {
1237 if (PragmaAttributeStack
.empty())
1239 Diag(PragmaAttributeStack
.back().Loc
, diag::err_pragma_attribute_no_pop_eof
);
1242 void Sema::ActOnPragmaOptimize(bool On
, SourceLocation PragmaLoc
) {
1244 OptimizeOffPragmaLocation
= SourceLocation();
1246 OptimizeOffPragmaLocation
= PragmaLoc
;
1249 void Sema::ActOnPragmaMSOptimize(SourceLocation Loc
, bool IsOn
) {
1250 if (!CurContext
->getRedeclContext()->isFileContext()) {
1251 Diag(Loc
, diag::err_pragma_expected_file_scope
) << "optimize";
1255 MSPragmaOptimizeIsOn
= IsOn
;
1258 void Sema::ActOnPragmaMSFunction(
1259 SourceLocation Loc
, const llvm::SmallVectorImpl
<StringRef
> &NoBuiltins
) {
1260 if (!CurContext
->getRedeclContext()->isFileContext()) {
1261 Diag(Loc
, diag::err_pragma_expected_file_scope
) << "function";
1265 MSFunctionNoBuiltins
.insert(NoBuiltins
.begin(), NoBuiltins
.end());
1268 void Sema::AddRangeBasedOptnone(FunctionDecl
*FD
) {
1269 // In the future, check other pragmas if they're implemented (e.g. pragma
1270 // optimize 0 will probably map to this functionality too).
1271 if(OptimizeOffPragmaLocation
.isValid())
1272 AddOptnoneAttributeIfNoConflicts(FD
, OptimizeOffPragmaLocation
);
1275 void Sema::AddSectionMSAllocText(FunctionDecl
*FD
) {
1276 if (!FD
->getIdentifier())
1279 StringRef Name
= FD
->getName();
1280 auto It
= FunctionToSectionMap
.find(Name
);
1281 if (It
!= FunctionToSectionMap
.end()) {
1284 std::tie(Section
, Loc
) = It
->second
;
1286 if (!FD
->hasAttr
<SectionAttr
>())
1287 FD
->addAttr(SectionAttr::CreateImplicit(Context
, Section
));
1291 void Sema::ModifyFnAttributesMSPragmaOptimize(FunctionDecl
*FD
) {
1292 // Don't modify the function attributes if it's "on". "on" resets the
1293 // optimizations to the ones listed on the command line
1294 if (!MSPragmaOptimizeIsOn
)
1295 AddOptnoneAttributeIfNoConflicts(FD
, FD
->getBeginLoc());
1298 void Sema::AddOptnoneAttributeIfNoConflicts(FunctionDecl
*FD
,
1299 SourceLocation Loc
) {
1300 // Don't add a conflicting attribute. No diagnostic is needed.
1301 if (FD
->hasAttr
<MinSizeAttr
>() || FD
->hasAttr
<AlwaysInlineAttr
>())
1304 // Add attributes only if required. Optnone requires noinline as well, but if
1305 // either is already present then don't bother adding them.
1306 if (!FD
->hasAttr
<OptimizeNoneAttr
>())
1307 FD
->addAttr(OptimizeNoneAttr::CreateImplicit(Context
, Loc
));
1308 if (!FD
->hasAttr
<NoInlineAttr
>())
1309 FD
->addAttr(NoInlineAttr::CreateImplicit(Context
, Loc
));
1312 void Sema::AddImplicitMSFunctionNoBuiltinAttr(FunctionDecl
*FD
) {
1313 SmallVector
<StringRef
> V(MSFunctionNoBuiltins
.begin(),
1314 MSFunctionNoBuiltins
.end());
1315 if (!MSFunctionNoBuiltins
.empty())
1316 FD
->addAttr(NoBuiltinAttr::CreateImplicit(Context
, V
.data(), V
.size()));
1319 typedef std::vector
<std::pair
<unsigned, SourceLocation
> > VisStack
;
1320 enum : unsigned { NoVisibility
= ~0U };
1322 void Sema::AddPushedVisibilityAttribute(Decl
*D
) {
1326 NamedDecl
*ND
= dyn_cast
<NamedDecl
>(D
);
1327 if (ND
&& ND
->getExplicitVisibility(NamedDecl::VisibilityForValue
))
1330 VisStack
*Stack
= static_cast<VisStack
*>(VisContext
);
1331 unsigned rawType
= Stack
->back().first
;
1332 if (rawType
== NoVisibility
) return;
1334 VisibilityAttr::VisibilityType type
1335 = (VisibilityAttr::VisibilityType
) rawType
;
1336 SourceLocation loc
= Stack
->back().second
;
1338 D
->addAttr(VisibilityAttr::CreateImplicit(Context
, type
, loc
));
1341 void Sema::FreeVisContext() {
1342 delete static_cast<VisStack
*>(VisContext
);
1343 VisContext
= nullptr;
1346 static void PushPragmaVisibility(Sema
&S
, unsigned type
, SourceLocation loc
) {
1347 // Put visibility on stack.
1349 S
.VisContext
= new VisStack
;
1351 VisStack
*Stack
= static_cast<VisStack
*>(S
.VisContext
);
1352 Stack
->push_back(std::make_pair(type
, loc
));
1355 void Sema::ActOnPragmaVisibility(const IdentifierInfo
* VisType
,
1356 SourceLocation PragmaLoc
) {
1358 // Compute visibility to use.
1359 VisibilityAttr::VisibilityType T
;
1360 if (!VisibilityAttr::ConvertStrToVisibilityType(VisType
->getName(), T
)) {
1361 Diag(PragmaLoc
, diag::warn_attribute_unknown_visibility
) << VisType
;
1364 PushPragmaVisibility(*this, T
, PragmaLoc
);
1366 PopPragmaVisibility(false, PragmaLoc
);
1370 void Sema::ActOnPragmaFPContract(SourceLocation Loc
,
1371 LangOptions::FPModeKind FPC
) {
1372 FPOptionsOverride NewFPFeatures
= CurFPFeatureOverrides();
1374 case LangOptions::FPM_On
:
1375 NewFPFeatures
.setAllowFPContractWithinStatement();
1377 case LangOptions::FPM_Fast
:
1378 case LangOptions::FPM_FastHonorPragmas
:
1379 NewFPFeatures
.setAllowFPContractAcrossStatement();
1381 case LangOptions::FPM_Off
:
1382 NewFPFeatures
.setDisallowFPContract();
1385 FpPragmaStack
.Act(Loc
, Sema::PSK_Set
, StringRef(), NewFPFeatures
);
1386 CurFPFeatures
= NewFPFeatures
.applyOverrides(getLangOpts());
1389 void Sema::ActOnPragmaFPValueChangingOption(SourceLocation Loc
,
1390 PragmaFPKind Kind
, bool IsEnabled
) {
1392 // For value unsafe context, combining this pragma with eval method
1393 // setting is not recommended. See comment in function FixupInvocation#506.
1395 if (getLangOpts().getFPEvalMethod() != LangOptions::FEM_UnsetOnCommandLine
)
1396 // Eval method set using the option 'ffp-eval-method'.
1398 if (PP
.getLastFPEvalPragmaLocation().isValid())
1399 // Eval method set using the '#pragma clang fp eval_method'.
1400 // We could have both an option and a pragma used to the set the eval
1401 // method. The pragma overrides the option in the command line. The Reason
1402 // of the diagnostic is overriden too.
1405 Diag(Loc
, diag::err_setting_eval_method_used_in_unsafe_context
)
1406 << Reason
<< (Kind
== PFK_Reassociate
? 4 : 5);
1409 FPOptionsOverride NewFPFeatures
= CurFPFeatureOverrides();
1411 case PFK_Reassociate
:
1412 NewFPFeatures
.setAllowFPReassociateOverride(IsEnabled
);
1414 case PFK_Reciprocal
:
1415 NewFPFeatures
.setAllowReciprocalOverride(IsEnabled
);
1418 llvm_unreachable("unhandled value changing pragma fp");
1421 FpPragmaStack
.Act(Loc
, PSK_Set
, StringRef(), NewFPFeatures
);
1422 CurFPFeatures
= NewFPFeatures
.applyOverrides(getLangOpts());
1425 void Sema::ActOnPragmaFEnvRound(SourceLocation Loc
, llvm::RoundingMode FPR
) {
1426 FPOptionsOverride NewFPFeatures
= CurFPFeatureOverrides();
1427 NewFPFeatures
.setConstRoundingModeOverride(FPR
);
1428 FpPragmaStack
.Act(Loc
, PSK_Set
, StringRef(), NewFPFeatures
);
1429 CurFPFeatures
= NewFPFeatures
.applyOverrides(getLangOpts());
1432 void Sema::setExceptionMode(SourceLocation Loc
,
1433 LangOptions::FPExceptionModeKind FPE
) {
1434 FPOptionsOverride NewFPFeatures
= CurFPFeatureOverrides();
1435 NewFPFeatures
.setSpecifiedExceptionModeOverride(FPE
);
1436 FpPragmaStack
.Act(Loc
, PSK_Set
, StringRef(), NewFPFeatures
);
1437 CurFPFeatures
= NewFPFeatures
.applyOverrides(getLangOpts());
1440 void Sema::ActOnPragmaFEnvAccess(SourceLocation Loc
, bool IsEnabled
) {
1441 FPOptionsOverride NewFPFeatures
= CurFPFeatureOverrides();
1443 // Verify Microsoft restriction:
1444 // You can't enable fenv_access unless precise semantics are enabled.
1445 // Precise semantics can be enabled either by the float_control
1446 // pragma, or by using the /fp:precise or /fp:strict compiler options
1447 if (!isPreciseFPEnabled())
1448 Diag(Loc
, diag::err_pragma_fenv_requires_precise
);
1450 NewFPFeatures
.setAllowFEnvAccessOverride(IsEnabled
);
1451 NewFPFeatures
.setRoundingMathOverride(IsEnabled
);
1452 FpPragmaStack
.Act(Loc
, PSK_Set
, StringRef(), NewFPFeatures
);
1453 CurFPFeatures
= NewFPFeatures
.applyOverrides(getLangOpts());
1456 void Sema::ActOnPragmaCXLimitedRange(SourceLocation Loc
,
1457 LangOptions::ComplexRangeKind Range
) {
1458 FPOptionsOverride NewFPFeatures
= CurFPFeatureOverrides();
1459 NewFPFeatures
.setComplexRangeOverride(Range
);
1460 FpPragmaStack
.Act(Loc
, PSK_Set
, StringRef(), NewFPFeatures
);
1461 CurFPFeatures
= NewFPFeatures
.applyOverrides(getLangOpts());
1464 void Sema::ActOnPragmaFPExceptions(SourceLocation Loc
,
1465 LangOptions::FPExceptionModeKind FPE
) {
1466 setExceptionMode(Loc
, FPE
);
1469 void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr
*Attr
,
1470 SourceLocation Loc
) {
1471 // Visibility calculations will consider the namespace's visibility.
1472 // Here we just want to note that we're in a visibility context
1473 // which overrides any enclosing #pragma context, but doesn't itself
1474 // contribute visibility.
1475 PushPragmaVisibility(*this, NoVisibility
, Loc
);
1478 void Sema::PopPragmaVisibility(bool IsNamespaceEnd
, SourceLocation EndLoc
) {
1480 Diag(EndLoc
, diag::err_pragma_pop_visibility_mismatch
);
1484 // Pop visibility from stack
1485 VisStack
*Stack
= static_cast<VisStack
*>(VisContext
);
1487 const std::pair
<unsigned, SourceLocation
> *Back
= &Stack
->back();
1488 bool StartsWithPragma
= Back
->first
!= NoVisibility
;
1489 if (StartsWithPragma
&& IsNamespaceEnd
) {
1490 Diag(Back
->second
, diag::err_pragma_push_visibility_mismatch
);
1491 Diag(EndLoc
, diag::note_surrounding_namespace_ends_here
);
1493 // For better error recovery, eat all pushes inside the namespace.
1496 Back
= &Stack
->back();
1497 StartsWithPragma
= Back
->first
!= NoVisibility
;
1498 } while (StartsWithPragma
);
1499 } else if (!StartsWithPragma
&& !IsNamespaceEnd
) {
1500 Diag(EndLoc
, diag::err_pragma_pop_visibility_mismatch
);
1501 Diag(Back
->second
, diag::note_surrounding_namespace_starts_here
);
1506 // To simplify the implementation, never keep around an empty stack.
1511 template <typename Ty
>
1512 static bool checkCommonAttributeFeatures(Sema
&S
, const Ty
*Node
,
1513 const ParsedAttr
&A
,
1514 bool SkipArgCountCheck
) {
1515 // Several attributes carry different semantics than the parsing requires, so
1516 // those are opted out of the common argument checks.
1518 // We also bail on unknown and ignored attributes because those are handled
1519 // as part of the target-specific handling logic.
1520 if (A
.getKind() == ParsedAttr::UnknownAttribute
)
1522 // Check whether the attribute requires specific language extensions to be
1524 if (!A
.diagnoseLangOpts(S
))
1526 // Check whether the attribute appertains to the given subject.
1527 if (!A
.diagnoseAppertainsTo(S
, Node
))
1529 // Check whether the attribute is mutually exclusive with other attributes
1530 // that have already been applied to the declaration.
1531 if (!A
.diagnoseMutualExclusion(S
, Node
))
1533 // Check whether the attribute exists in the target architecture.
1534 if (S
.CheckAttrTarget(A
))
1537 if (A
.hasCustomParsing())
1540 if (!SkipArgCountCheck
) {
1541 if (A
.getMinArgs() == A
.getMaxArgs()) {
1542 // If there are no optional arguments, then checking for the argument
1543 // count is trivial.
1544 if (!A
.checkExactlyNumArgs(S
, A
.getMinArgs()))
1547 // There are optional arguments, so checking is slightly more involved.
1548 if (A
.getMinArgs() && !A
.checkAtLeastNumArgs(S
, A
.getMinArgs()))
1550 else if (!A
.hasVariadicArg() && A
.getMaxArgs() &&
1551 !A
.checkAtMostNumArgs(S
, A
.getMaxArgs()))
1559 bool Sema::checkCommonAttributeFeatures(const Decl
*D
, const ParsedAttr
&A
,
1560 bool SkipArgCountCheck
) {
1561 return ::checkCommonAttributeFeatures(*this, D
, A
, SkipArgCountCheck
);
1563 bool Sema::checkCommonAttributeFeatures(const Stmt
*S
, const ParsedAttr
&A
,
1564 bool SkipArgCountCheck
) {
1565 return ::checkCommonAttributeFeatures(*this, S
, A
, SkipArgCountCheck
);