Coverage Report

Created: 2021-01-23 06:44

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