Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 6378f1a

Browse files
committed
Recommit r308327 3rd time: Add a warning for missing
'#pragma pack (pop)' and suspicious uses of '#pragma pack' in included files The second recommit (r309106) was reverted because the "non-default #pragma pack value chages the alignment of struct or union members in the included file" warning proved to be too aggressive for external projects like Chromium (https://bugs.chromium.org/p/chromium/issues/detail?id=749197). This recommit makes the problematic warning a non-default one, and gives it the -Wpragma-pack-suspicious-include warning option. The first recommit (r308441) caused a "non-default #pragma pack value might change the alignment of struct or union members in the included file" warning in LLVM itself. This recommit tweaks the added warning to avoid warnings for #includes that don't have any records that are affected by the non-default alignment. This tweak avoids the previously emitted warning in LLVM. Original message: This commit adds a new -Wpragma-pack warning. It warns in the following cases: - When a translation unit is missing terminating #pragma pack (pop) directives. - When entering an included file if the current alignment value as determined by '#pragma pack' directives is different from the default alignment value. - When leaving an included file that changed the state of the current alignment value. rdar://10184173 Differential Revision: https://reviews.llvm.org/D35484 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@309386 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 6f3fb93 commit 6378f1a

22 files changed

+296
-30
lines changed

include/clang/Basic/DiagnosticGroups.td

+3-1
Original file line numberDiff line numberDiff line change
@@ -471,8 +471,10 @@ def IgnoredPragmaIntrinsic : DiagGroup<"ignored-pragma-intrinsic">;
471471
def UnknownPragmas : DiagGroup<"unknown-pragmas">;
472472
def IgnoredPragmas : DiagGroup<"ignored-pragmas", [IgnoredPragmaIntrinsic]>;
473473
def PragmaClangAttribute : DiagGroup<"pragma-clang-attribute">;
474+
def PragmaPackSuspiciousInclude : DiagGroup<"pragma-pack-suspicious-include">;
475+
def PragmaPack : DiagGroup<"pragma-pack", [PragmaPackSuspiciousInclude]>;
474476
def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas,
475-
PragmaClangAttribute]>;
477+
PragmaClangAttribute, PragmaPack]>;
476478
def UnknownWarningOption : DiagGroup<"unknown-warning-option">;
477479
def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
478480
def IndependentClassAttribute : DiagGroup<"IndependentClass-attribute">;

include/clang/Basic/DiagnosticSemaKinds.td

+11
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,17 @@ def err_pragma_options_align_mac68k_target_unsupported : Error<
712712
def warn_pragma_pack_invalid_alignment : Warning<
713713
"expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">,
714714
InGroup<IgnoredPragmas>;
715+
def warn_pragma_pack_non_default_at_include : Warning<
716+
"non-default #pragma pack value changes the alignment of struct or union "
717+
"members in the included file">, InGroup<PragmaPackSuspiciousInclude>,
718+
DefaultIgnore;
719+
def warn_pragma_pack_modified_after_include : Warning<
720+
"the current #pragma pack aligment value is modified in the included "
721+
"file">, InGroup<PragmaPack>;
722+
def warn_pragma_pack_no_pop_eof : Warning<"unterminated "
723+
"'#pragma pack (push, ...)' at end of file">, InGroup<PragmaPack>;
724+
def note_pragma_pack_here : Note<
725+
"previous '#pragma pack' directive that modifies alignment is here">;
715726
// Follow the Microsoft implementation.
716727
def warn_pragma_pack_show : Warning<"value of #pragma pack(show) == %0">;
717728
def warn_pragma_pack_pop_identifer_and_alignment : Warning<

include/clang/Lex/PPCallbacks.h

+6
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,12 @@ class PPChainedCallbacks : public PPCallbacks {
381381
Second->Ident(Loc, str);
382382
}
383383

384+
void PragmaDirective(SourceLocation Loc,
385+
PragmaIntroducerKind Introducer) override {
386+
First->PragmaDirective(Loc, Introducer);
387+
Second->PragmaDirective(Loc, Introducer);
388+
}
389+
384390
void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind,
385391
StringRef Str) override {
386392
First->PragmaComment(Loc, Kind, Str);

include/clang/Sema/Sema.h

+31-5
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ namespace sema {
208208
class FunctionScopeInfo;
209209
class LambdaScopeInfo;
210210
class PossiblyUnreachableDiag;
211+
class SemaPPCallbacks;
211212
class TemplateDeductionInfo;
212213
}
213214

@@ -381,11 +382,12 @@ class Sema {
381382
llvm::StringRef StackSlotLabel;
382383
ValueType Value;
383384
SourceLocation PragmaLocation;
384-
Slot(llvm::StringRef StackSlotLabel,
385-
ValueType Value,
386-
SourceLocation PragmaLocation)
387-
: StackSlotLabel(StackSlotLabel), Value(Value),
388-
PragmaLocation(PragmaLocation) {}
385+
SourceLocation PragmaPushLocation;
386+
Slot(llvm::StringRef StackSlotLabel, ValueType Value,
387+
SourceLocation PragmaLocation, SourceLocation PragmaPushLocation)
388+
: StackSlotLabel(StackSlotLabel), Value(Value),
389+
PragmaLocation(PragmaLocation),
390+
PragmaPushLocation(PragmaPushLocation) {}
389391
};
390392
void Act(SourceLocation PragmaLocation,
391393
PragmaMsStackAction Action,
@@ -416,6 +418,8 @@ class Sema {
416418
explicit PragmaStack(const ValueType &Default)
417419
: DefaultValue(Default), CurrentValue(Default) {}
418420

421+
bool hasValue() const { return CurrentValue != DefaultValue; }
422+
419423
SmallVector<Slot, 2> Stack;
420424
ValueType DefaultValue; // Value used for PSK_Reset action.
421425
ValueType CurrentValue;
@@ -437,6 +441,13 @@ class Sema {
437441
// Sentinel to represent when the stack is set to mac68k alignment.
438442
static const unsigned kMac68kAlignmentSentinel = ~0U;
439443
PragmaStack<unsigned> PackStack;
444+
// The current #pragma pack values and locations at each #include.
445+
struct PackIncludeState {
446+
unsigned CurrentValue;
447+
SourceLocation CurrentPragmaLocation;
448+
bool HasNonDefaultValue, ShouldWarnOnInclude;
449+
};
450+
SmallVector<PackIncludeState, 8> PackIncludeStack;
440451
// Segment #pragmas.
441452
PragmaStack<StringLiteral *> DataSegStack;
442453
PragmaStack<StringLiteral *> BSSSegStack;
@@ -8182,6 +8193,15 @@ class Sema {
81828193
void ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action,
81838194
StringRef SlotLabel, Expr *Alignment);
81848195

8196+
enum class PragmaPackDiagnoseKind {
8197+
NonDefaultStateAtInclude,
8198+
ChangedStateAtExit
8199+
};
8200+
8201+
void DiagnoseNonDefaultPragmaPack(PragmaPackDiagnoseKind Kind,
8202+
SourceLocation IncludeLoc);
8203+
void DiagnoseUnterminatedPragmaPack();
8204+
81858205
/// ActOnPragmaMSStruct - Called on well formed \#pragma ms_struct [on|off].
81868206
void ActOnPragmaMSStruct(PragmaMSStructKind Kind);
81878207

@@ -10390,6 +10410,12 @@ class Sema {
1039010410

1039110411
IdentifierInfo *Ident_NSError = nullptr;
1039210412

10413+
/// \brief The handler for the FileChanged preprocessor events.
10414+
///
10415+
/// Used for diagnostics that implement custom semantic analysis for #include
10416+
/// directives, like -Wpragma-pack.
10417+
sema::SemaPPCallbacks *SemaPPCallbackHandler;
10418+
1039310419
protected:
1039410420
friend class Parser;
1039510421
friend class InitializationSequence;

include/clang/Serialization/ASTReader.h

+1
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@ class ASTReader
825825
struct PragmaPackStackEntry {
826826
unsigned Value;
827827
SourceLocation Location;
828+
SourceLocation PushLocation;
828829
StringRef SlotLabel;
829830
};
830831
llvm::SmallVector<PragmaPackStackEntry, 2> PragmaPackStack;

lib/Parse/ParsePragma.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -422,15 +422,20 @@ void Parser::HandlePragmaPack() {
422422
assert(Tok.is(tok::annot_pragma_pack));
423423
PragmaPackInfo *Info =
424424
static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
425-
SourceLocation PragmaLoc = ConsumeAnnotationToken();
425+
SourceLocation PragmaLoc = Tok.getLocation();
426426
ExprResult Alignment;
427427
if (Info->Alignment.is(tok::numeric_constant)) {
428428
Alignment = Actions.ActOnNumericConstant(Info->Alignment);
429-
if (Alignment.isInvalid())
429+
if (Alignment.isInvalid()) {
430+
ConsumeAnnotationToken();
430431
return;
432+
}
431433
}
432434
Actions.ActOnPragmaPack(PragmaLoc, Info->Action, Info->SlotLabel,
433435
Alignment.get());
436+
// Consume the token after processing the pragma to enable pragma-specific
437+
// #include warnings.
438+
ConsumeAnnotationToken();
434439
}
435440

436441
void Parser::HandlePragmaMSStruct() {

lib/Sema/Sema.cpp

+54
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,49 @@ void Sema::ActOnTranslationUnitScope(Scope *S) {
7070
PushDeclContext(S, Context.getTranslationUnitDecl());
7171
}
7272

73+
namespace clang {
74+
namespace sema {
75+
76+
class SemaPPCallbacks : public PPCallbacks {
77+
Sema *S = nullptr;
78+
llvm::SmallVector<SourceLocation, 8> IncludeStack;
79+
80+
public:
81+
void set(Sema &S) { this->S = &S; }
82+
83+
void reset() { S = nullptr; }
84+
85+
virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
86+
SrcMgr::CharacteristicKind FileType,
87+
FileID PrevFID) override {
88+
if (!S)
89+
return;
90+
switch (Reason) {
91+
case EnterFile: {
92+
SourceManager &SM = S->getSourceManager();
93+
SourceLocation IncludeLoc = SM.getIncludeLoc(SM.getFileID(Loc));
94+
if (IncludeLoc.isValid()) {
95+
IncludeStack.push_back(IncludeLoc);
96+
S->DiagnoseNonDefaultPragmaPack(
97+
Sema::PragmaPackDiagnoseKind::NonDefaultStateAtInclude, IncludeLoc);
98+
}
99+
break;
100+
}
101+
case ExitFile:
102+
if (!IncludeStack.empty())
103+
S->DiagnoseNonDefaultPragmaPack(
104+
Sema::PragmaPackDiagnoseKind::ChangedStateAtExit,
105+
IncludeStack.pop_back_val());
106+
break;
107+
default:
108+
break;
109+
}
110+
}
111+
};
112+
113+
} // end namespace sema
114+
} // end namespace clang
115+
73116
Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
74117
TranslationUnitKind TUKind, CodeCompleteConsumer *CodeCompleter)
75118
: ExternalSource(nullptr), isMultiplexExternalSource(false),
@@ -122,6 +165,12 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
122165

123166
// Initilization of data sharing attributes stack for OpenMP
124167
InitDataSharingAttributesStack();
168+
169+
std::unique_ptr<sema::SemaPPCallbacks> Callbacks =
170+
llvm::make_unique<sema::SemaPPCallbacks>();
171+
SemaPPCallbackHandler = Callbacks.get();
172+
PP.addPPCallbacks(std::move(Callbacks));
173+
SemaPPCallbackHandler->set(*this);
125174
}
126175

127176
void Sema::addImplicitTypedef(StringRef Name, QualType T) {
@@ -306,6 +355,10 @@ Sema::~Sema() {
306355
// Destroys data sharing attributes stack for OpenMP
307356
DestroyDataSharingAttributesStack();
308357

358+
// Detach from the PP callback handler which outlives Sema since it's owned
359+
// by the preprocessor.
360+
SemaPPCallbackHandler->reset();
361+
309362
assert(DelayedTypos.empty() && "Uncorrected typos!");
310363
}
311364

@@ -766,6 +819,7 @@ void Sema::ActOnEndOfTranslationUnit() {
766819
CheckDelayedMemberExceptionSpecs();
767820
}
768821

822+
DiagnoseUnterminatedPragmaPack();
769823
DiagnoseUnterminatedPragmaAttribute();
770824

771825
// All delayed member exception specs should be checked or we end up accepting

lib/Sema/SemaAttr.cpp

+54-1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
6161
RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(Context,
6262
Alignment * 8));
6363
}
64+
if (PackIncludeStack.empty())
65+
return;
66+
// The #pragma pack affected a record in an included file, so Clang should
67+
// warn when that pragma was written in a file that included the included
68+
// file.
69+
for (auto &PackedInclude : llvm::reverse(PackIncludeStack)) {
70+
if (PackedInclude.CurrentPragmaLocation != PackStack.CurrentPragmaLocation)
71+
break;
72+
if (PackedInclude.HasNonDefaultValue)
73+
PackedInclude.ShouldWarnOnInclude = true;
74+
}
6475
}
6576

6677
void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) {
@@ -202,6 +213,47 @@ void Sema::ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action,
202213
PackStack.Act(PragmaLoc, Action, SlotLabel, AlignmentVal);
203214
}
204215

216+
void Sema::DiagnoseNonDefaultPragmaPack(PragmaPackDiagnoseKind Kind,
217+
SourceLocation IncludeLoc) {
218+
if (Kind == PragmaPackDiagnoseKind::NonDefaultStateAtInclude) {
219+
SourceLocation PrevLocation = PackStack.CurrentPragmaLocation;
220+
// Warn about non-default alignment at #includes (without redundant
221+
// warnings for the same directive in nested includes).
222+
// The warning is delayed until the end of the file to avoid warnings
223+
// for files that don't have any records that are affected by the modified
224+
// alignment.
225+
bool HasNonDefaultValue =
226+
PackStack.hasValue() &&
227+
(PackIncludeStack.empty() ||
228+
PackIncludeStack.back().CurrentPragmaLocation != PrevLocation);
229+
PackIncludeStack.push_back(
230+
{PackStack.CurrentValue,
231+
PackStack.hasValue() ? PrevLocation : SourceLocation(),
232+
HasNonDefaultValue, /*ShouldWarnOnInclude*/ false});
233+
return;
234+
}
235+
236+
assert(Kind == PragmaPackDiagnoseKind::ChangedStateAtExit && "invalid kind");
237+
PackIncludeState PrevPackState = PackIncludeStack.pop_back_val();
238+
if (PrevPackState.ShouldWarnOnInclude) {
239+
// Emit the delayed non-default alignment at #include warning.
240+
Diag(IncludeLoc, diag::warn_pragma_pack_non_default_at_include);
241+
Diag(PrevPackState.CurrentPragmaLocation, diag::note_pragma_pack_here);
242+
}
243+
// Warn about modified alignment after #includes.
244+
if (PrevPackState.CurrentValue != PackStack.CurrentValue) {
245+
Diag(IncludeLoc, diag::warn_pragma_pack_modified_after_include);
246+
Diag(PackStack.CurrentPragmaLocation, diag::note_pragma_pack_here);
247+
}
248+
}
249+
250+
void Sema::DiagnoseUnterminatedPragmaPack() {
251+
if (PackStack.Stack.empty())
252+
return;
253+
for (const auto &StackSlot : llvm::reverse(PackStack.Stack))
254+
Diag(StackSlot.PragmaPushLocation, diag::warn_pragma_pack_no_pop_eof);
255+
}
256+
205257
void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) {
206258
MSStructPragmaOn = (Kind == PMSST_ON);
207259
}
@@ -249,7 +301,8 @@ void Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation,
249301
return;
250302
}
251303
if (Action & PSK_Push)
252-
Stack.push_back(Slot(StackSlotLabel, CurrentValue, CurrentPragmaLocation));
304+
Stack.emplace_back(StackSlotLabel, CurrentValue, CurrentPragmaLocation,
305+
PragmaLocation);
253306
else if (Action & PSK_Pop) {
254307
if (!StackSlotLabel.empty()) {
255308
// If we've got a label, try to find it and jump there.

lib/Serialization/ASTReader.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -3382,6 +3382,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
33823382
PragmaPackStackEntry Entry;
33833383
Entry.Value = Record[Idx++];
33843384
Entry.Location = ReadSourceLocation(F, Record[Idx++]);
3385+
Entry.PushLocation = ReadSourceLocation(F, Record[Idx++]);
33853386
PragmaPackStrings.push_back(ReadString(Record, Idx));
33863387
Entry.SlotLabel = PragmaPackStrings.back();
33873388
PragmaPackStack.push_back(Entry);
@@ -7570,13 +7571,14 @@ void ASTReader::UpdateSema() {
75707571
"Expected a default alignment value");
75717572
SemaObj->PackStack.Stack.emplace_back(
75727573
PragmaPackStack.front().SlotLabel, SemaObj->PackStack.CurrentValue,
7573-
SemaObj->PackStack.CurrentPragmaLocation);
7574+
SemaObj->PackStack.CurrentPragmaLocation,
7575+
PragmaPackStack.front().PushLocation);
75747576
DropFirst = true;
75757577
}
75767578
for (const auto &Entry :
75777579
llvm::makeArrayRef(PragmaPackStack).drop_front(DropFirst ? 1 : 0))
75787580
SemaObj->PackStack.Stack.emplace_back(Entry.SlotLabel, Entry.Value,
7579-
Entry.Location);
7581+
Entry.Location, Entry.PushLocation);
75807582
if (PragmaPackCurrentLocation.isInvalid()) {
75817583
assert(*PragmaPackCurrentValue == SemaObj->PackStack.DefaultValue &&
75827584
"Expected a default alignment value");

lib/Serialization/ASTWriter.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -4295,6 +4295,7 @@ void ASTWriter::WritePackPragmaOptions(Sema &SemaRef) {
42954295
for (const auto &StackEntry : SemaRef.PackStack.Stack) {
42964296
Record.push_back(StackEntry.Value);
42974297
AddSourceLocation(StackEntry.PragmaLocation, Record);
4298+
AddSourceLocation(StackEntry.PragmaPushLocation, Record);
42984299
AddString(StackEntry.StackSlotLabel, Record);
42994300
}
43004301
Stream.EmitRecord(PACK_PRAGMA_OPTIONS, Record);

test/OpenMP/declare_simd_messages.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp -x c++ -std=c++11 -fms-extensions %s
1+
// RUN: %clang_cc1 -triple=x86_64-pc-win32 -verify -fopenmp -x c++ -std=c++11 -fms-extensions -Wno-pragma-pack %s
22

33
// expected-error@+1 {{expected an OpenMP directive}}
44
#pragma omp declare

test/PCH/pragma-pack.c

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
// Test this without pch.
2-
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -DSET
3-
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -DRESET
4-
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -DPUSH
5-
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -DPUSH_POP
6-
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -DPUSH_POP_LABEL
2+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -Wno-pragma-pack -DSET
3+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -Wno-pragma-pack -DRESET
4+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -Wno-pragma-pack -DPUSH
5+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -Wno-pragma-pack -DPUSH_POP
6+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -Wno-pragma-pack -DPUSH_POP_LABEL
77

88
// Test with pch.
9-
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DSET -emit-pch -o %t
10-
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DSET -verify -include-pch %t
11-
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DRESET -emit-pch -o %t
12-
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DRESET -verify -include-pch %t
13-
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH -emit-pch -o %t
14-
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH -verify -include-pch %t
15-
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH_POP -emit-pch -o %t
16-
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH_POP -verify -include-pch %t
17-
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH_POP_LABEL -emit-pch -o %t
18-
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH_POP_LABEL -verify -include-pch %t
9+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DSET -emit-pch -o %t
10+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DSET -verify -include-pch %t
11+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DRESET -emit-pch -o %t
12+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DRESET -verify -include-pch %t
13+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DPUSH -emit-pch -o %t
14+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DPUSH -verify -include-pch %t
15+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DPUSH_POP -emit-pch -o %t
16+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DPUSH_POP -verify -include-pch %t
17+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DPUSH_POP_LABEL -emit-pch -o %t
18+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -Wno-pragma-pack -DPUSH_POP_LABEL -verify -include-pch %t
1919

2020
#ifndef HEADER
2121
#define HEADER

test/PCH/suspicious-pragma-pack.c

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -verify -emit-pch -o %t
2+
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -verify -include-pch %t
3+
4+
#ifndef HEADER
5+
#define HEADER
6+
#pragma pack (push, 1)
7+
#endif
8+
// expected-warning@-2 {{unterminated '#pragma pack (push, ...)' at end of file}}

0 commit comments

Comments
 (0)