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