SemaAttr.cpp revision 360784
1//===--- SemaAttr.cpp - Semantic Analysis for Attributes ------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements semantic analysis for non-trivial attributes and
10// pragmas.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/ASTConsumer.h"
15#include "clang/AST/Attr.h"
16#include "clang/AST/Expr.h"
17#include "clang/Basic/TargetInfo.h"
18#include "clang/Lex/Preprocessor.h"
19#include "clang/Sema/Lookup.h"
20#include "clang/Sema/SemaInternal.h"
21using namespace clang;
22
23//===----------------------------------------------------------------------===//
24// Pragma 'pack' and 'options align'
25//===----------------------------------------------------------------------===//
26
27Sema::PragmaStackSentinelRAII::PragmaStackSentinelRAII(Sema &S,
28                                                       StringRef SlotLabel,
29                                                       bool ShouldAct)
30    : S(S), SlotLabel(SlotLabel), ShouldAct(ShouldAct) {
31  if (ShouldAct) {
32    S.VtorDispStack.SentinelAction(PSK_Push, SlotLabel);
33    S.DataSegStack.SentinelAction(PSK_Push, SlotLabel);
34    S.BSSSegStack.SentinelAction(PSK_Push, SlotLabel);
35    S.ConstSegStack.SentinelAction(PSK_Push, SlotLabel);
36    S.CodeSegStack.SentinelAction(PSK_Push, SlotLabel);
37  }
38}
39
40Sema::PragmaStackSentinelRAII::~PragmaStackSentinelRAII() {
41  if (ShouldAct) {
42    S.VtorDispStack.SentinelAction(PSK_Pop, SlotLabel);
43    S.DataSegStack.SentinelAction(PSK_Pop, SlotLabel);
44    S.BSSSegStack.SentinelAction(PSK_Pop, SlotLabel);
45    S.ConstSegStack.SentinelAction(PSK_Pop, SlotLabel);
46    S.CodeSegStack.SentinelAction(PSK_Pop, SlotLabel);
47  }
48}
49
50void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
51  // If there is no pack value, we don't need any attributes.
52  if (!PackStack.CurrentValue)
53    return;
54
55  // Otherwise, check to see if we need a max field alignment attribute.
56  if (unsigned Alignment = PackStack.CurrentValue) {
57    if (Alignment == Sema::kMac68kAlignmentSentinel)
58      RD->addAttr(AlignMac68kAttr::CreateImplicit(Context));
59    else
60      RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(Context,
61                                                        Alignment * 8));
62  }
63  if (PackIncludeStack.empty())
64    return;
65  // The #pragma pack affected a record in an included file,  so Clang should
66  // warn when that pragma was written in a file that included the included
67  // file.
68  for (auto &PackedInclude : llvm::reverse(PackIncludeStack)) {
69    if (PackedInclude.CurrentPragmaLocation != PackStack.CurrentPragmaLocation)
70      break;
71    if (PackedInclude.HasNonDefaultValue)
72      PackedInclude.ShouldWarnOnInclude = true;
73  }
74}
75
76void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) {
77  if (MSStructPragmaOn)
78    RD->addAttr(MSStructAttr::CreateImplicit(Context));
79
80  // FIXME: We should merge AddAlignmentAttributesForRecord with
81  // AddMsStructLayoutForRecord into AddPragmaAttributesForRecord, which takes
82  // all active pragmas and applies them as attributes to class definitions.
83  if (VtorDispStack.CurrentValue != getLangOpts().getVtorDispMode())
84    RD->addAttr(MSVtorDispAttr::CreateImplicit(
85        Context, unsigned(VtorDispStack.CurrentValue)));
86}
87
88template <typename Attribute>
89static void addGslOwnerPointerAttributeIfNotExisting(ASTContext &Context,
90                                                     CXXRecordDecl *Record) {
91  if (Record->hasAttr<OwnerAttr>() || Record->hasAttr<PointerAttr>())
92    return;
93
94  for (Decl *Redecl : Record->redecls())
95    Redecl->addAttr(Attribute::CreateImplicit(Context, /*DerefType=*/nullptr));
96}
97
98void Sema::inferGslPointerAttribute(NamedDecl *ND,
99                                    CXXRecordDecl *UnderlyingRecord) {
100  if (!UnderlyingRecord)
101    return;
102
103  const auto *Parent = dyn_cast<CXXRecordDecl>(ND->getDeclContext());
104  if (!Parent)
105    return;
106
107  static llvm::StringSet<> Containers{
108      "array",
109      "basic_string",
110      "deque",
111      "forward_list",
112      "vector",
113      "list",
114      "map",
115      "multiset",
116      "multimap",
117      "priority_queue",
118      "queue",
119      "set",
120      "stack",
121      "unordered_set",
122      "unordered_map",
123      "unordered_multiset",
124      "unordered_multimap",
125  };
126
127  static llvm::StringSet<> Iterators{"iterator", "const_iterator",
128                                     "reverse_iterator",
129                                     "const_reverse_iterator"};
130
131  if (Parent->isInStdNamespace() && Iterators.count(ND->getName()) &&
132      Containers.count(Parent->getName()))
133    addGslOwnerPointerAttributeIfNotExisting<PointerAttr>(Context,
134                                                          UnderlyingRecord);
135}
136
137void Sema::inferGslPointerAttribute(TypedefNameDecl *TD) {
138
139  QualType Canonical = TD->getUnderlyingType().getCanonicalType();
140
141  CXXRecordDecl *RD = Canonical->getAsCXXRecordDecl();
142  if (!RD) {
143    if (auto *TST =
144            dyn_cast<TemplateSpecializationType>(Canonical.getTypePtr())) {
145
146      RD = dyn_cast_or_null<CXXRecordDecl>(
147          TST->getTemplateName().getAsTemplateDecl()->getTemplatedDecl());
148    }
149  }
150
151  inferGslPointerAttribute(TD, RD);
152}
153
154void Sema::inferGslOwnerPointerAttribute(CXXRecordDecl *Record) {
155  static llvm::StringSet<> StdOwners{
156      "any",
157      "array",
158      "basic_regex",
159      "basic_string",
160      "deque",
161      "forward_list",
162      "vector",
163      "list",
164      "map",
165      "multiset",
166      "multimap",
167      "optional",
168      "priority_queue",
169      "queue",
170      "set",
171      "stack",
172      "unique_ptr",
173      "unordered_set",
174      "unordered_map",
175      "unordered_multiset",
176      "unordered_multimap",
177      "variant",
178  };
179  static llvm::StringSet<> StdPointers{
180      "basic_string_view",
181      "reference_wrapper",
182      "regex_iterator",
183  };
184
185  if (!Record->getIdentifier())
186    return;
187
188  // Handle classes that directly appear in std namespace.
189  if (Record->isInStdNamespace()) {
190    if (Record->hasAttr<OwnerAttr>() || Record->hasAttr<PointerAttr>())
191      return;
192
193    if (StdOwners.count(Record->getName()))
194      addGslOwnerPointerAttributeIfNotExisting<OwnerAttr>(Context, Record);
195    else if (StdPointers.count(Record->getName()))
196      addGslOwnerPointerAttributeIfNotExisting<PointerAttr>(Context, Record);
197
198    return;
199  }
200
201  // Handle nested classes that could be a gsl::Pointer.
202  inferGslPointerAttribute(Record, Record);
203}
204
205void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
206                                   SourceLocation PragmaLoc) {
207  PragmaMsStackAction Action = Sema::PSK_Reset;
208  unsigned Alignment = 0;
209  switch (Kind) {
210    // For all targets we support native and natural are the same.
211    //
212    // FIXME: This is not true on Darwin/PPC.
213  case POAK_Native:
214  case POAK_Power:
215  case POAK_Natural:
216    Action = Sema::PSK_Push_Set;
217    Alignment = 0;
218    break;
219
220    // Note that '#pragma options align=packed' is not equivalent to attribute
221    // packed, it has a different precedence relative to attribute aligned.
222  case POAK_Packed:
223    Action = Sema::PSK_Push_Set;
224    Alignment = 1;
225    break;
226
227  case POAK_Mac68k:
228    // Check if the target supports this.
229    if (!this->Context.getTargetInfo().hasAlignMac68kSupport()) {
230      Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported);
231      return;
232    }
233    Action = Sema::PSK_Push_Set;
234    Alignment = Sema::kMac68kAlignmentSentinel;
235    break;
236
237  case POAK_Reset:
238    // Reset just pops the top of the stack, or resets the current alignment to
239    // default.
240    Action = Sema::PSK_Pop;
241    if (PackStack.Stack.empty()) {
242      if (PackStack.CurrentValue) {
243        Action = Sema::PSK_Reset;
244      } else {
245        Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
246            << "stack empty";
247        return;
248      }
249    }
250    break;
251  }
252
253  PackStack.Act(PragmaLoc, Action, StringRef(), Alignment);
254}
255
256void Sema::ActOnPragmaClangSection(SourceLocation PragmaLoc, PragmaClangSectionAction Action,
257                                   PragmaClangSectionKind SecKind, StringRef SecName) {
258  PragmaClangSection *CSec;
259  switch (SecKind) {
260    case PragmaClangSectionKind::PCSK_BSS:
261      CSec = &PragmaClangBSSSection;
262      break;
263    case PragmaClangSectionKind::PCSK_Data:
264      CSec = &PragmaClangDataSection;
265      break;
266    case PragmaClangSectionKind::PCSK_Rodata:
267      CSec = &PragmaClangRodataSection;
268      break;
269    case PragmaClangSectionKind::PCSK_Relro:
270      CSec = &PragmaClangRelroSection;
271      break;
272    case PragmaClangSectionKind::PCSK_Text:
273      CSec = &PragmaClangTextSection;
274      break;
275    default:
276      llvm_unreachable("invalid clang section kind");
277  }
278
279  if (Action == PragmaClangSectionAction::PCSA_Clear) {
280    CSec->Valid = false;
281    return;
282  }
283
284  CSec->Valid = true;
285  CSec->SectionName = SecName;
286  CSec->PragmaLocation = PragmaLoc;
287}
288
289void Sema::ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action,
290                           StringRef SlotLabel, Expr *alignment) {
291  Expr *Alignment = static_cast<Expr *>(alignment);
292
293  // If specified then alignment must be a "small" power of two.
294  unsigned AlignmentVal = 0;
295  if (Alignment) {
296    llvm::APSInt Val;
297
298    // pack(0) is like pack(), which just works out since that is what
299    // we use 0 for in PackAttr.
300    if (Alignment->isTypeDependent() ||
301        Alignment->isValueDependent() ||
302        !Alignment->isIntegerConstantExpr(Val, Context) ||
303        !(Val == 0 || Val.isPowerOf2()) ||
304        Val.getZExtValue() > 16) {
305      Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
306      return; // Ignore
307    }
308
309    AlignmentVal = (unsigned) Val.getZExtValue();
310  }
311  if (Action == Sema::PSK_Show) {
312    // Show the current alignment, making sure to show the right value
313    // for the default.
314    // FIXME: This should come from the target.
315    AlignmentVal = PackStack.CurrentValue;
316    if (AlignmentVal == 0)
317      AlignmentVal = 8;
318    if (AlignmentVal == Sema::kMac68kAlignmentSentinel)
319      Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k";
320    else
321      Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
322  }
323  // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
324  // "#pragma pack(pop, identifier, n) is undefined"
325  if (Action & Sema::PSK_Pop) {
326    if (Alignment && !SlotLabel.empty())
327      Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifier_and_alignment);
328    if (PackStack.Stack.empty())
329      Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "pack" << "stack empty";
330  }
331
332  PackStack.Act(PragmaLoc, Action, SlotLabel, AlignmentVal);
333}
334
335void Sema::DiagnoseNonDefaultPragmaPack(PragmaPackDiagnoseKind Kind,
336                                        SourceLocation IncludeLoc) {
337  if (Kind == PragmaPackDiagnoseKind::NonDefaultStateAtInclude) {
338    SourceLocation PrevLocation = PackStack.CurrentPragmaLocation;
339    // Warn about non-default alignment at #includes (without redundant
340    // warnings for the same directive in nested includes).
341    // The warning is delayed until the end of the file to avoid warnings
342    // for files that don't have any records that are affected by the modified
343    // alignment.
344    bool HasNonDefaultValue =
345        PackStack.hasValue() &&
346        (PackIncludeStack.empty() ||
347         PackIncludeStack.back().CurrentPragmaLocation != PrevLocation);
348    PackIncludeStack.push_back(
349        {PackStack.CurrentValue,
350         PackStack.hasValue() ? PrevLocation : SourceLocation(),
351         HasNonDefaultValue, /*ShouldWarnOnInclude*/ false});
352    return;
353  }
354
355  assert(Kind == PragmaPackDiagnoseKind::ChangedStateAtExit && "invalid kind");
356  PackIncludeState PrevPackState = PackIncludeStack.pop_back_val();
357  if (PrevPackState.ShouldWarnOnInclude) {
358    // Emit the delayed non-default alignment at #include warning.
359    Diag(IncludeLoc, diag::warn_pragma_pack_non_default_at_include);
360    Diag(PrevPackState.CurrentPragmaLocation, diag::note_pragma_pack_here);
361  }
362  // Warn about modified alignment after #includes.
363  if (PrevPackState.CurrentValue != PackStack.CurrentValue) {
364    Diag(IncludeLoc, diag::warn_pragma_pack_modified_after_include);
365    Diag(PackStack.CurrentPragmaLocation, diag::note_pragma_pack_here);
366  }
367}
368
369void Sema::DiagnoseUnterminatedPragmaPack() {
370  if (PackStack.Stack.empty())
371    return;
372  bool IsInnermost = true;
373  for (const auto &StackSlot : llvm::reverse(PackStack.Stack)) {
374    Diag(StackSlot.PragmaPushLocation, diag::warn_pragma_pack_no_pop_eof);
375    // The user might have already reset the alignment, so suggest replacing
376    // the reset with a pop.
377    if (IsInnermost && PackStack.CurrentValue == PackStack.DefaultValue) {
378      DiagnosticBuilder DB = Diag(PackStack.CurrentPragmaLocation,
379                                  diag::note_pragma_pack_pop_instead_reset);
380      SourceLocation FixItLoc = Lexer::findLocationAfterToken(
381          PackStack.CurrentPragmaLocation, tok::l_paren, SourceMgr, LangOpts,
382          /*SkipTrailing=*/false);
383      if (FixItLoc.isValid())
384        DB << FixItHint::CreateInsertion(FixItLoc, "pop");
385    }
386    IsInnermost = false;
387  }
388}
389
390void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) {
391  MSStructPragmaOn = (Kind == PMSST_ON);
392}
393
394void Sema::ActOnPragmaMSComment(SourceLocation CommentLoc,
395                                PragmaMSCommentKind Kind, StringRef Arg) {
396  auto *PCD = PragmaCommentDecl::Create(
397      Context, Context.getTranslationUnitDecl(), CommentLoc, Kind, Arg);
398  Context.getTranslationUnitDecl()->addDecl(PCD);
399  Consumer.HandleTopLevelDecl(DeclGroupRef(PCD));
400}
401
402void Sema::ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name,
403                                     StringRef Value) {
404  auto *PDMD = PragmaDetectMismatchDecl::Create(
405      Context, Context.getTranslationUnitDecl(), Loc, Name, Value);
406  Context.getTranslationUnitDecl()->addDecl(PDMD);
407  Consumer.HandleTopLevelDecl(DeclGroupRef(PDMD));
408}
409
410void Sema::ActOnPragmaMSPointersToMembers(
411    LangOptions::PragmaMSPointersToMembersKind RepresentationMethod,
412    SourceLocation PragmaLoc) {
413  MSPointerToMemberRepresentationMethod = RepresentationMethod;
414  ImplicitMSInheritanceAttrLoc = PragmaLoc;
415}
416
417void Sema::ActOnPragmaMSVtorDisp(PragmaMsStackAction Action,
418                                 SourceLocation PragmaLoc,
419                                 MSVtorDispMode Mode) {
420  if (Action & PSK_Pop && VtorDispStack.Stack.empty())
421    Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp"
422                                                  << "stack empty";
423  VtorDispStack.Act(PragmaLoc, Action, StringRef(), Mode);
424}
425
426template<typename ValueType>
427void Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation,
428                                       PragmaMsStackAction Action,
429                                       llvm::StringRef StackSlotLabel,
430                                       ValueType Value) {
431  if (Action == PSK_Reset) {
432    CurrentValue = DefaultValue;
433    CurrentPragmaLocation = PragmaLocation;
434    return;
435  }
436  if (Action & PSK_Push)
437    Stack.emplace_back(StackSlotLabel, CurrentValue, CurrentPragmaLocation,
438                       PragmaLocation);
439  else if (Action & PSK_Pop) {
440    if (!StackSlotLabel.empty()) {
441      // If we've got a label, try to find it and jump there.
442      auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) {
443        return x.StackSlotLabel == StackSlotLabel;
444      });
445      // If we found the label so pop from there.
446      if (I != Stack.rend()) {
447        CurrentValue = I->Value;
448        CurrentPragmaLocation = I->PragmaLocation;
449        Stack.erase(std::prev(I.base()), Stack.end());
450      }
451    } else if (!Stack.empty()) {
452      // We do not have a label, just pop the last entry.
453      CurrentValue = Stack.back().Value;
454      CurrentPragmaLocation = Stack.back().PragmaLocation;
455      Stack.pop_back();
456    }
457  }
458  if (Action & PSK_Set) {
459    CurrentValue = Value;
460    CurrentPragmaLocation = PragmaLocation;
461  }
462}
463
464bool Sema::UnifySection(StringRef SectionName,
465                        int SectionFlags,
466                        DeclaratorDecl *Decl) {
467  auto Section = Context.SectionInfos.find(SectionName);
468  if (Section == Context.SectionInfos.end()) {
469    Context.SectionInfos[SectionName] =
470        ASTContext::SectionInfo(Decl, SourceLocation(), SectionFlags);
471    return false;
472  }
473  // A pre-declared section takes precedence w/o diagnostic.
474  if (Section->second.SectionFlags == SectionFlags ||
475      !(Section->second.SectionFlags & ASTContext::PSF_Implicit))
476    return false;
477  auto OtherDecl = Section->second.Decl;
478  Diag(Decl->getLocation(), diag::err_section_conflict)
479      << Decl << OtherDecl;
480  Diag(OtherDecl->getLocation(), diag::note_declared_at)
481      << OtherDecl->getName();
482  if (auto A = Decl->getAttr<SectionAttr>())
483    if (A->isImplicit())
484      Diag(A->getLocation(), diag::note_pragma_entered_here);
485  if (auto A = OtherDecl->getAttr<SectionAttr>())
486    if (A->isImplicit())
487      Diag(A->getLocation(), diag::note_pragma_entered_here);
488  return true;
489}
490
491bool Sema::UnifySection(StringRef SectionName,
492                        int SectionFlags,
493                        SourceLocation PragmaSectionLocation) {
494  auto Section = Context.SectionInfos.find(SectionName);
495  if (Section != Context.SectionInfos.end()) {
496    if (Section->second.SectionFlags == SectionFlags)
497      return false;
498    if (!(Section->second.SectionFlags & ASTContext::PSF_Implicit)) {
499      Diag(PragmaSectionLocation, diag::err_section_conflict)
500          << "this" << "a prior #pragma section";
501      Diag(Section->second.PragmaSectionLocation,
502           diag::note_pragma_entered_here);
503      return true;
504    }
505  }
506  Context.SectionInfos[SectionName] =
507      ASTContext::SectionInfo(nullptr, PragmaSectionLocation, SectionFlags);
508  return false;
509}
510
511/// Called on well formed \#pragma bss_seg().
512void Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation,
513                            PragmaMsStackAction Action,
514                            llvm::StringRef StackSlotLabel,
515                            StringLiteral *SegmentName,
516                            llvm::StringRef PragmaName) {
517  PragmaStack<StringLiteral *> *Stack =
518    llvm::StringSwitch<PragmaStack<StringLiteral *> *>(PragmaName)
519        .Case("data_seg", &DataSegStack)
520        .Case("bss_seg", &BSSSegStack)
521        .Case("const_seg", &ConstSegStack)
522        .Case("code_seg", &CodeSegStack);
523  if (Action & PSK_Pop && Stack->Stack.empty())
524    Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName
525        << "stack empty";
526  if (SegmentName) {
527    if (!checkSectionName(SegmentName->getBeginLoc(), SegmentName->getString()))
528      return;
529
530    if (SegmentName->getString() == ".drectve" &&
531        Context.getTargetInfo().getCXXABI().isMicrosoft())
532      Diag(PragmaLocation, diag::warn_attribute_section_drectve) << PragmaName;
533  }
534
535  Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
536}
537
538/// Called on well formed \#pragma bss_seg().
539void Sema::ActOnPragmaMSSection(SourceLocation PragmaLocation,
540                                int SectionFlags, StringLiteral *SegmentName) {
541  UnifySection(SegmentName->getString(), SectionFlags, PragmaLocation);
542}
543
544void Sema::ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
545                                StringLiteral *SegmentName) {
546  // There's no stack to maintain, so we just have a current section.  When we
547  // see the default section, reset our current section back to null so we stop
548  // tacking on unnecessary attributes.
549  CurInitSeg = SegmentName->getString() == ".CRT$XCU" ? nullptr : SegmentName;
550  CurInitSegLoc = PragmaLocation;
551}
552
553void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,
554                             SourceLocation PragmaLoc) {
555
556  IdentifierInfo *Name = IdTok.getIdentifierInfo();
557  LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName);
558  LookupParsedName(Lookup, curScope, nullptr, true);
559
560  if (Lookup.empty()) {
561    Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
562      << Name << SourceRange(IdTok.getLocation());
563    return;
564  }
565
566  VarDecl *VD = Lookup.getAsSingle<VarDecl>();
567  if (!VD) {
568    Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg)
569      << Name << SourceRange(IdTok.getLocation());
570    return;
571  }
572
573  // Warn if this was used before being marked unused.
574  if (VD->isUsed())
575    Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name;
576
577  VD->addAttr(UnusedAttr::CreateImplicit(Context, IdTok.getLocation(),
578                                         AttributeCommonInfo::AS_Pragma,
579                                         UnusedAttr::GNU_unused));
580}
581
582void Sema::AddCFAuditedAttribute(Decl *D) {
583  IdentifierInfo *Ident;
584  SourceLocation Loc;
585  std::tie(Ident, Loc) = PP.getPragmaARCCFCodeAuditedInfo();
586  if (!Loc.isValid()) return;
587
588  // Don't add a redundant or conflicting attribute.
589  if (D->hasAttr<CFAuditedTransferAttr>() ||
590      D->hasAttr<CFUnknownTransferAttr>())
591    return;
592
593  AttributeCommonInfo Info(Ident, SourceRange(Loc),
594                           AttributeCommonInfo::AS_Pragma);
595  D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Info));
596}
597
598namespace {
599
600Optional<attr::SubjectMatchRule>
601getParentAttrMatcherRule(attr::SubjectMatchRule Rule) {
602  using namespace attr;
603  switch (Rule) {
604  default:
605    return None;
606#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
607#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated)    \
608  case Value:                                                                  \
609    return Parent;
610#include "clang/Basic/AttrSubMatchRulesList.inc"
611  }
612}
613
614bool isNegatedAttrMatcherSubRule(attr::SubjectMatchRule Rule) {
615  using namespace attr;
616  switch (Rule) {
617  default:
618    return false;
619#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
620#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated)    \
621  case Value:                                                                  \
622    return IsNegated;
623#include "clang/Basic/AttrSubMatchRulesList.inc"
624  }
625}
626
627CharSourceRange replacementRangeForListElement(const Sema &S,
628                                               SourceRange Range) {
629  // Make sure that the ',' is removed as well.
630  SourceLocation AfterCommaLoc = Lexer::findLocationAfterToken(
631      Range.getEnd(), tok::comma, S.getSourceManager(), S.getLangOpts(),
632      /*SkipTrailingWhitespaceAndNewLine=*/false);
633  if (AfterCommaLoc.isValid())
634    return CharSourceRange::getCharRange(Range.getBegin(), AfterCommaLoc);
635  else
636    return CharSourceRange::getTokenRange(Range);
637}
638
639std::string
640attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) {
641  std::string Result;
642  llvm::raw_string_ostream OS(Result);
643  for (const auto &I : llvm::enumerate(Rules)) {
644    if (I.index())
645      OS << (I.index() == Rules.size() - 1 ? ", and " : ", ");
646    OS << "'" << attr::getSubjectMatchRuleSpelling(I.value()) << "'";
647  }
648  return OS.str();
649}
650
651} // end anonymous namespace
652
653void Sema::ActOnPragmaAttributeAttribute(
654    ParsedAttr &Attribute, SourceLocation PragmaLoc,
655    attr::ParsedSubjectMatchRuleSet Rules) {
656  Attribute.setIsPragmaClangAttribute();
657  SmallVector<attr::SubjectMatchRule, 4> SubjectMatchRules;
658  // Gather the subject match rules that are supported by the attribute.
659  SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4>
660      StrictSubjectMatchRuleSet;
661  Attribute.getMatchRules(LangOpts, StrictSubjectMatchRuleSet);
662
663  // Figure out which subject matching rules are valid.
664  if (StrictSubjectMatchRuleSet.empty()) {
665    // Check for contradicting match rules. Contradicting match rules are
666    // either:
667    //  - a top-level rule and one of its sub-rules. E.g. variable and
668    //    variable(is_parameter).
669    //  - a sub-rule and a sibling that's negated. E.g.
670    //    variable(is_thread_local) and variable(unless(is_parameter))
671    llvm::SmallDenseMap<int, std::pair<int, SourceRange>, 2>
672        RulesToFirstSpecifiedNegatedSubRule;
673    for (const auto &Rule : Rules) {
674      attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
675      Optional<attr::SubjectMatchRule> ParentRule =
676          getParentAttrMatcherRule(MatchRule);
677      if (!ParentRule)
678        continue;
679      auto It = Rules.find(*ParentRule);
680      if (It != Rules.end()) {
681        // A sub-rule contradicts a parent rule.
682        Diag(Rule.second.getBegin(),
683             diag::err_pragma_attribute_matcher_subrule_contradicts_rule)
684            << attr::getSubjectMatchRuleSpelling(MatchRule)
685            << attr::getSubjectMatchRuleSpelling(*ParentRule) << It->second
686            << FixItHint::CreateRemoval(
687                   replacementRangeForListElement(*this, Rule.second));
688        // Keep going without removing this rule as it won't change the set of
689        // declarations that receive the attribute.
690        continue;
691      }
692      if (isNegatedAttrMatcherSubRule(MatchRule))
693        RulesToFirstSpecifiedNegatedSubRule.insert(
694            std::make_pair(*ParentRule, Rule));
695    }
696    bool IgnoreNegatedSubRules = false;
697    for (const auto &Rule : Rules) {
698      attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
699      Optional<attr::SubjectMatchRule> ParentRule =
700          getParentAttrMatcherRule(MatchRule);
701      if (!ParentRule)
702        continue;
703      auto It = RulesToFirstSpecifiedNegatedSubRule.find(*ParentRule);
704      if (It != RulesToFirstSpecifiedNegatedSubRule.end() &&
705          It->second != Rule) {
706        // Negated sub-rule contradicts another sub-rule.
707        Diag(
708            It->second.second.getBegin(),
709            diag::
710                err_pragma_attribute_matcher_negated_subrule_contradicts_subrule)
711            << attr::getSubjectMatchRuleSpelling(
712                   attr::SubjectMatchRule(It->second.first))
713            << attr::getSubjectMatchRuleSpelling(MatchRule) << Rule.second
714            << FixItHint::CreateRemoval(
715                   replacementRangeForListElement(*this, It->second.second));
716        // Keep going but ignore all of the negated sub-rules.
717        IgnoreNegatedSubRules = true;
718        RulesToFirstSpecifiedNegatedSubRule.erase(It);
719      }
720    }
721
722    if (!IgnoreNegatedSubRules) {
723      for (const auto &Rule : Rules)
724        SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
725    } else {
726      for (const auto &Rule : Rules) {
727        if (!isNegatedAttrMatcherSubRule(attr::SubjectMatchRule(Rule.first)))
728          SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
729      }
730    }
731    Rules.clear();
732  } else {
733    for (const auto &Rule : StrictSubjectMatchRuleSet) {
734      if (Rules.erase(Rule.first)) {
735        // Add the rule to the set of attribute receivers only if it's supported
736        // in the current language mode.
737        if (Rule.second)
738          SubjectMatchRules.push_back(Rule.first);
739      }
740    }
741  }
742
743  if (!Rules.empty()) {
744    auto Diagnostic =
745        Diag(PragmaLoc, diag::err_pragma_attribute_invalid_matchers)
746        << Attribute;
747    SmallVector<attr::SubjectMatchRule, 2> ExtraRules;
748    for (const auto &Rule : Rules) {
749      ExtraRules.push_back(attr::SubjectMatchRule(Rule.first));
750      Diagnostic << FixItHint::CreateRemoval(
751          replacementRangeForListElement(*this, Rule.second));
752    }
753    Diagnostic << attrMatcherRuleListToString(ExtraRules);
754  }
755
756  if (PragmaAttributeStack.empty()) {
757    Diag(PragmaLoc, diag::err_pragma_attr_attr_no_push);
758    return;
759  }
760
761  PragmaAttributeStack.back().Entries.push_back(
762      {PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false});
763}
764
765void Sema::ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc,
766                                         const IdentifierInfo *Namespace) {
767  PragmaAttributeStack.emplace_back();
768  PragmaAttributeStack.back().Loc = PragmaLoc;
769  PragmaAttributeStack.back().Namespace = Namespace;
770}
771
772void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc,
773                                   const IdentifierInfo *Namespace) {
774  if (PragmaAttributeStack.empty()) {
775    Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1;
776    return;
777  }
778
779  // Dig back through the stack trying to find the most recently pushed group
780  // that in Namespace. Note that this works fine if no namespace is present,
781  // think of push/pops without namespaces as having an implicit "nullptr"
782  // namespace.
783  for (size_t Index = PragmaAttributeStack.size(); Index;) {
784    --Index;
785    if (PragmaAttributeStack[Index].Namespace == Namespace) {
786      for (const PragmaAttributeEntry &Entry :
787           PragmaAttributeStack[Index].Entries) {
788        if (!Entry.IsUsed) {
789          assert(Entry.Attribute && "Expected an attribute");
790          Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused)
791              << *Entry.Attribute;
792          Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here);
793        }
794      }
795      PragmaAttributeStack.erase(PragmaAttributeStack.begin() + Index);
796      return;
797    }
798  }
799
800  if (Namespace)
801    Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch)
802        << 0 << Namespace->getName();
803  else
804    Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1;
805}
806
807void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
808  if (PragmaAttributeStack.empty())
809    return;
810  for (auto &Group : PragmaAttributeStack) {
811    for (auto &Entry : Group.Entries) {
812      ParsedAttr *Attribute = Entry.Attribute;
813      assert(Attribute && "Expected an attribute");
814      assert(Attribute->isPragmaClangAttribute() &&
815             "expected #pragma clang attribute");
816
817      // Ensure that the attribute can be applied to the given declaration.
818      bool Applies = false;
819      for (const auto &Rule : Entry.MatchRules) {
820        if (Attribute->appliesToDecl(D, Rule)) {
821          Applies = true;
822          break;
823        }
824      }
825      if (!Applies)
826        continue;
827      Entry.IsUsed = true;
828      PragmaAttributeCurrentTargetDecl = D;
829      ParsedAttributesView Attrs;
830      Attrs.addAtEnd(Attribute);
831      ProcessDeclAttributeList(S, D, Attrs);
832      PragmaAttributeCurrentTargetDecl = nullptr;
833    }
834  }
835}
836
837void Sema::PrintPragmaAttributeInstantiationPoint() {
838  assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration");
839  Diags.Report(PragmaAttributeCurrentTargetDecl->getBeginLoc(),
840               diag::note_pragma_attribute_applied_decl_here);
841}
842
843void Sema::DiagnoseUnterminatedPragmaAttribute() {
844  if (PragmaAttributeStack.empty())
845    return;
846  Diag(PragmaAttributeStack.back().Loc, diag::err_pragma_attribute_no_pop_eof);
847}
848
849void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) {
850  if(On)
851    OptimizeOffPragmaLocation = SourceLocation();
852  else
853    OptimizeOffPragmaLocation = PragmaLoc;
854}
855
856void Sema::AddRangeBasedOptnone(FunctionDecl *FD) {
857  // In the future, check other pragmas if they're implemented (e.g. pragma
858  // optimize 0 will probably map to this functionality too).
859  if(OptimizeOffPragmaLocation.isValid())
860    AddOptnoneAttributeIfNoConflicts(FD, OptimizeOffPragmaLocation);
861}
862
863void Sema::AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD,
864                                            SourceLocation Loc) {
865  // Don't add a conflicting attribute. No diagnostic is needed.
866  if (FD->hasAttr<MinSizeAttr>() || FD->hasAttr<AlwaysInlineAttr>())
867    return;
868
869  // Add attributes only if required. Optnone requires noinline as well, but if
870  // either is already present then don't bother adding them.
871  if (!FD->hasAttr<OptimizeNoneAttr>())
872    FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc));
873  if (!FD->hasAttr<NoInlineAttr>())
874    FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc));
875}
876
877typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;
878enum : unsigned { NoVisibility = ~0U };
879
880void Sema::AddPushedVisibilityAttribute(Decl *D) {
881  if (!VisContext)
882    return;
883
884  NamedDecl *ND = dyn_cast<NamedDecl>(D);
885  if (ND && ND->getExplicitVisibility(NamedDecl::VisibilityForValue))
886    return;
887
888  VisStack *Stack = static_cast<VisStack*>(VisContext);
889  unsigned rawType = Stack->back().first;
890  if (rawType == NoVisibility) return;
891
892  VisibilityAttr::VisibilityType type
893    = (VisibilityAttr::VisibilityType) rawType;
894  SourceLocation loc = Stack->back().second;
895
896  D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc));
897}
898
899/// FreeVisContext - Deallocate and null out VisContext.
900void Sema::FreeVisContext() {
901  delete static_cast<VisStack*>(VisContext);
902  VisContext = nullptr;
903}
904
905static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) {
906  // Put visibility on stack.
907  if (!S.VisContext)
908    S.VisContext = new VisStack;
909
910  VisStack *Stack = static_cast<VisStack*>(S.VisContext);
911  Stack->push_back(std::make_pair(type, loc));
912}
913
914void Sema::ActOnPragmaVisibility(const IdentifierInfo* VisType,
915                                 SourceLocation PragmaLoc) {
916  if (VisType) {
917    // Compute visibility to use.
918    VisibilityAttr::VisibilityType T;
919    if (!VisibilityAttr::ConvertStrToVisibilityType(VisType->getName(), T)) {
920      Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << VisType;
921      return;
922    }
923    PushPragmaVisibility(*this, T, PragmaLoc);
924  } else {
925    PopPragmaVisibility(false, PragmaLoc);
926  }
927}
928
929void Sema::ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC) {
930  switch (FPC) {
931  case LangOptions::FPC_On:
932    FPFeatures.setAllowFPContractWithinStatement();
933    break;
934  case LangOptions::FPC_Fast:
935    FPFeatures.setAllowFPContractAcrossStatement();
936    break;
937  case LangOptions::FPC_Off:
938    FPFeatures.setDisallowFPContract();
939    break;
940  }
941}
942
943void Sema::ActOnPragmaFEnvAccess(LangOptions::FEnvAccessModeKind FPC) {
944  switch (FPC) {
945  case LangOptions::FEA_On:
946    FPFeatures.setAllowFEnvAccess();
947    break;
948  case LangOptions::FEA_Off:
949    FPFeatures.setDisallowFEnvAccess();
950    break;
951  }
952}
953
954
955void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
956                                       SourceLocation Loc) {
957  // Visibility calculations will consider the namespace's visibility.
958  // Here we just want to note that we're in a visibility context
959  // which overrides any enclosing #pragma context, but doesn't itself
960  // contribute visibility.
961  PushPragmaVisibility(*this, NoVisibility, Loc);
962}
963
964void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) {
965  if (!VisContext) {
966    Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
967    return;
968  }
969
970  // Pop visibility from stack
971  VisStack *Stack = static_cast<VisStack*>(VisContext);
972
973  const std::pair<unsigned, SourceLocation> *Back = &Stack->back();
974  bool StartsWithPragma = Back->first != NoVisibility;
975  if (StartsWithPragma && IsNamespaceEnd) {
976    Diag(Back->second, diag::err_pragma_push_visibility_mismatch);
977    Diag(EndLoc, diag::note_surrounding_namespace_ends_here);
978
979    // For better error recovery, eat all pushes inside the namespace.
980    do {
981      Stack->pop_back();
982      Back = &Stack->back();
983      StartsWithPragma = Back->first != NoVisibility;
984    } while (StartsWithPragma);
985  } else if (!StartsWithPragma && !IsNamespaceEnd) {
986    Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
987    Diag(Back->second, diag::note_surrounding_namespace_starts_here);
988    return;
989  }
990
991  Stack->pop_back();
992  // To simplify the implementation, never keep around an empty stack.
993  if (Stack->empty())
994    FreeVisContext();
995}
996