[clang] 955d7c3 - [clang] Add support for #pragma strict_gs_check
David Majnemer via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 19 13:09:43 PDT 2022
Author: David Majnemer
Date: 2022-09-19T20:07:14Z
New Revision: 955d7c39ff74868a28c848a0462ff41be972043e
URL: https://github.com/llvm/llvm-project/commit/955d7c39ff74868a28c848a0462ff41be972043e
DIFF: https://github.com/llvm/llvm-project/commit/955d7c39ff74868a28c848a0462ff41be972043e.diff
LOG: [clang] Add support for #pragma strict_gs_check
Added:
clang/test/CodeGenCXX/pragma-strict_gs_check.cpp
Modified:
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Parse/Parser.h
clang/include/clang/Sema/Sema.h
clang/lib/Parse/ParsePragma.cpp
clang/lib/Sema/Sema.cpp
clang/lib/Sema/SemaAttr.cpp
clang/lib/Sema/SemaDecl.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index ee9deef0dde1..0238b3877120 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -4454,8 +4454,8 @@ def NoStackProtectorDocs : Documentation {
let Category = DocCatFunction;
let Heading = "no_stack_protector, safebuffers";
let Content = [{
-Clang supports the ``__attribute__((no_stack_protector))`` and Microsoft style
-``__declspec(safebuffers)`` attribute which disables
+Clang supports the GNU style ``__attribute__((no_stack_protector))`` and Microsoft
+style ``__declspec(safebuffers)`` attribute which disables
the stack protector on the specified function. This attribute is useful for
selectively disabling the stack protector on some functions when building with
``-fstack-protector`` compiler option.
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 690a56bf6614..273af97ef241 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -194,6 +194,7 @@ class Parser : public CodeCompletionHandler {
std::unique_ptr<PragmaHandler> MSConstSeg;
std::unique_ptr<PragmaHandler> MSCodeSeg;
std::unique_ptr<PragmaHandler> MSSection;
+ std::unique_ptr<PragmaHandler> MSStrictGuardStackCheck;
std::unique_ptr<PragmaHandler> MSRuntimeChecks;
std::unique_ptr<PragmaHandler> MSIntrinsic;
std::unique_ptr<PragmaHandler> MSFunction;
@@ -725,6 +726,8 @@ class Parser : public CodeCompletionHandler {
SourceLocation PragmaLocation);
bool HandlePragmaMSInitSeg(StringRef PragmaName,
SourceLocation PragmaLocation);
+ bool HandlePragmaMSStrictGuardStackCheck(StringRef PragmaName,
+ SourceLocation PragmaLocation);
bool HandlePragmaMSFunction(StringRef PragmaName,
SourceLocation PragmaLocation);
bool HandlePragmaMSAllocText(StringRef PragmaName,
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index f1a4c8d914c0..6dd656e29559 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -691,6 +691,9 @@ class Sema final {
PragmaStack<StringLiteral *> ConstSegStack;
PragmaStack<StringLiteral *> CodeSegStack;
+ // #pragma strict_gs_check.
+ PragmaStack<bool> StrictGuardStackCheckStack;
+
// This stack tracks the current state of Sema.CurFPFeatures.
PragmaStack<FPOptionsOverride> FpPragmaStack;
FPOptionsOverride CurFPFeatureOverrides() {
@@ -10295,6 +10298,12 @@ class Sema final {
SourceLocation IncludeLoc);
void DiagnoseUnterminatedPragmaAlignPack();
+ /// ActOnPragmaMSStrictGuardStackCheck - Called on well formed \#pragma
+ /// strict_gs_check.
+ void ActOnPragmaMSStrictGuardStackCheck(SourceLocation PragmaLocation,
+ PragmaMsStackAction Action,
+ bool Value);
+
/// ActOnPragmaMSStruct - Called on well formed \#pragma ms_struct [on|off].
void ActOnPragmaMSStruct(PragmaMSStructKind Kind);
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index 74fa70379858..123d94ee703f 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -449,6 +449,9 @@ void Parser::initializePragmaHandlers() {
PP.AddPragmaHandler(MSCodeSeg.get());
MSSection = std::make_unique<PragmaMSPragma>("section");
PP.AddPragmaHandler(MSSection.get());
+ MSStrictGuardStackCheck =
+ std::make_unique<PragmaMSPragma>("strict_gs_check");
+ PP.AddPragmaHandler(MSStrictGuardStackCheck.get());
MSFunction = std::make_unique<PragmaMSPragma>("function");
PP.AddPragmaHandler(MSFunction.get());
MSAllocText = std::make_unique<PragmaMSPragma>("alloc_text");
@@ -567,6 +570,8 @@ void Parser::resetPragmaHandlers() {
MSCodeSeg.reset();
PP.RemovePragmaHandler(MSSection.get());
MSSection.reset();
+ PP.RemovePragmaHandler(MSStrictGuardStackCheck.get());
+ MSStrictGuardStackCheck.reset();
PP.RemovePragmaHandler(MSFunction.get());
MSFunction.reset();
PP.RemovePragmaHandler(MSAllocText.get());
@@ -936,6 +941,7 @@ void Parser::HandlePragmaMSPragma() {
.Case("code_seg", &Parser::HandlePragmaMSSegment)
.Case("section", &Parser::HandlePragmaMSSection)
.Case("init_seg", &Parser::HandlePragmaMSInitSeg)
+ .Case("strict_gs_check", &Parser::HandlePragmaMSStrictGuardStackCheck)
.Case("function", &Parser::HandlePragmaMSFunction)
.Case("alloc_text", &Parser::HandlePragmaMSAllocText)
.Case("optimize", &Parser::HandlePragmaMSOptimize);
@@ -1175,6 +1181,59 @@ bool Parser::HandlePragmaMSInitSeg(StringRef PragmaName,
return true;
}
+// #pragma strict_gs_check(pop)
+// #pragma strict_gs_check(push, "on" | "off")
+// #pragma strict_gs_check("on" | "off")
+bool Parser::HandlePragmaMSStrictGuardStackCheck(
+ StringRef PragmaName, SourceLocation PragmaLocation) {
+ if (ExpectAndConsume(tok::l_paren, diag::warn_pragma_expected_lparen,
+ PragmaName))
+ return false;
+
+ Sema::PragmaMsStackAction Action = Sema::PSK_Set;
+ if (Tok.is(tok::identifier)) {
+ StringRef PushPop = Tok.getIdentifierInfo()->getName();
+ if (PushPop == "push") {
+ PP.Lex(Tok);
+ Action = Sema::PSK_Push;
+ if (ExpectAndConsume(tok::comma, diag::warn_pragma_expected_punc,
+ PragmaName))
+ return false;
+ } else if (PushPop == "pop") {
+ PP.Lex(Tok);
+ Action = Sema::PSK_Pop;
+ }
+ }
+
+ bool Value = false;
+ if (Action & Sema::PSK_Push || Action & Sema::PSK_Set) {
+ const IdentifierInfo *II = Tok.getIdentifierInfo();
+ if (II && II->isStr("off")) {
+ PP.Lex(Tok);
+ Value = false;
+ } else if (II && II->isStr("on")) {
+ PP.Lex(Tok);
+ Value = true;
+ } else {
+ PP.Diag(Tok.getLocation(), diag::warn_pragma_invalid_action)
+ << PragmaName;
+ return false;
+ }
+ }
+
+ // Finish the pragma: ')' $
+ if (ExpectAndConsume(tok::r_paren, diag::warn_pragma_expected_rparen,
+ PragmaName))
+ return false;
+
+ if (ExpectAndConsume(tok::eof, diag::warn_pragma_extra_tokens_at_eol,
+ PragmaName))
+ return false;
+
+ Actions.ActOnPragmaMSStrictGuardStackCheck(PragmaLocation, Action, Value);
+ return true;
+}
+
bool Parser::HandlePragmaMSAllocText(StringRef PragmaName,
SourceLocation PragmaLocation) {
Token FirstTok = Tok;
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 7ccf6330b49b..9fdd5098e62d 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -195,9 +195,9 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
VtorDispStack(LangOpts.getVtorDispMode()),
AlignPackStack(AlignPackInfo(getLangOpts().XLPragmaPack)),
DataSegStack(nullptr), BSSSegStack(nullptr), ConstSegStack(nullptr),
- CodeSegStack(nullptr), FpPragmaStack(FPOptionsOverride()),
- CurInitSeg(nullptr), VisContext(nullptr),
- PragmaAttributeCurrentTargetDecl(nullptr),
+ CodeSegStack(nullptr), StrictGuardStackCheckStack(false),
+ FpPragmaStack(FPOptionsOverride()), CurInitSeg(nullptr),
+ VisContext(nullptr), PragmaAttributeCurrentTargetDecl(nullptr),
IsBuildingRecoveryCallExpr(false), LateTemplateParser(nullptr),
LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), IdResolver(pp),
StdExperimentalNamespaceCache(nullptr), StdInitializerList(nullptr),
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index c997d018a406..47611aed7957 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -34,6 +34,7 @@ Sema::PragmaStackSentinelRAII::PragmaStackSentinelRAII(Sema &S,
S.BSSSegStack.SentinelAction(PSK_Push, SlotLabel);
S.ConstSegStack.SentinelAction(PSK_Push, SlotLabel);
S.CodeSegStack.SentinelAction(PSK_Push, SlotLabel);
+ S.StrictGuardStackCheckStack.SentinelAction(PSK_Push, SlotLabel);
}
}
@@ -44,6 +45,7 @@ Sema::PragmaStackSentinelRAII::~PragmaStackSentinelRAII() {
S.BSSSegStack.SentinelAction(PSK_Pop, SlotLabel);
S.ConstSegStack.SentinelAction(PSK_Pop, SlotLabel);
S.CodeSegStack.SentinelAction(PSK_Pop, SlotLabel);
+ S.StrictGuardStackCheckStack.SentinelAction(PSK_Pop, SlotLabel);
}
}
@@ -774,6 +776,17 @@ void Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation,
Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
}
+/// Called on well formed \#pragma strict_gs_check().
+void Sema::ActOnPragmaMSStrictGuardStackCheck(SourceLocation PragmaLocation,
+ PragmaMsStackAction Action,
+ bool Value) {
+ if (Action & PSK_Pop && StrictGuardStackCheckStack.Stack.empty())
+ Diag(PragmaLocation, diag::warn_pragma_pop_failed) << "strict_gs_check"
+ << "stack empty";
+
+ StrictGuardStackCheckStack.Act(PragmaLocation, Action, StringRef(), Value);
+}
+
/// Called on well formed \#pragma bss_seg().
void Sema::ActOnPragmaMSSection(SourceLocation PragmaLocation,
int SectionFlags, StringLiteral *SegmentName) {
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index db0e2981aa82..0f567d91dc81 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -9997,6 +9997,14 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
NewFD->dropAttr<SectionAttr>();
}
+ // Apply an implicit StrictGuardStackCheckAttr if #pragma strict_gs_check is
+ // active.
+ if (StrictGuardStackCheckStack.CurrentValue && D.isFunctionDefinition() &&
+ !NewFD->hasAttr<StrictGuardStackCheckAttr>())
+ NewFD->addAttr(StrictGuardStackCheckAttr::CreateImplicit(
+ Context, PragmaClangTextSection.PragmaLocation,
+ AttributeCommonInfo::AS_Pragma));
+
// Apply an implicit CodeSegAttr from class declspec or
// apply an implicit SectionAttr from #pragma code_seg if active.
if (!NewFD->hasAttr<CodeSegAttr>()) {
diff --git a/clang/test/CodeGenCXX/pragma-strict_gs_check.cpp b/clang/test/CodeGenCXX/pragma-strict_gs_check.cpp
new file mode 100644
index 000000000000..9cfab47692ad
--- /dev/null
+++ b/clang/test/CodeGenCXX/pragma-strict_gs_check.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -stack-protector 2 -emit-llvm -o - | FileCheck %s
+
+#pragma strict_gs_check(on)
+
+extern "C" void test0() {
+}
+// CHECK: define {{.*}} @test0() #[[ATTR_TEST0:[0-9]*]] {
+
+
+// CHECK: attributes #[[ATTR_TEST0]] = {{.*}} sspstrong
+
More information about the cfe-commits
mailing list