From 3981431fb19eef89a0fa54a71e645977a6335a27 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 3 Apr 2014 19:04:24 +0000 Subject: [PATCH] -fms-extensions: Error out on #pragma init_seg By ignoring this pragma with a warning, we're essentially miscompiling the user's program. WebKit / Blink use this pragma to disable dynamic initialization and finalization of some static data, and running the dtors crashes the program. Error out for now, so that /fallback compiles the TU correctly with MSVC. This pragma should be implemented some time this month, and we can remove this hack. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@205554 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Parse/Parser.h | 1 + lib/Parse/ParsePragma.cpp | 18 ++++++++++++++++++ test/CodeGenCXX/pragma-init_seg.cpp | 16 ++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 test/CodeGenCXX/pragma-init_seg.cpp diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 44f7cb1e05..db527f6e45 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -154,6 +154,7 @@ class Parser : public CodeCompletionHandler { std::unique_ptr MSDetectMismatchHandler; std::unique_ptr MSPointersToMembers; std::unique_ptr MSVtorDisp; + std::unique_ptr MSInitSeg; std::unique_ptr CommentSemaHandler; diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index 29e17715b3..33c1f0b628 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -124,6 +124,12 @@ struct PragmaMSVtorDisp : public PragmaHandler { Token &FirstToken) override; }; +struct PragmaMSInitSeg : public PragmaHandler { + explicit PragmaMSInitSeg() : PragmaHandler("init_seg") {} + void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, + Token &FirstToken) override; +}; + } // end namespace void Parser::initializePragmaHandlers() { @@ -175,6 +181,8 @@ void Parser::initializePragmaHandlers() { PP.AddPragmaHandler(MSPointersToMembers.get()); MSVtorDisp.reset(new PragmaMSVtorDisp()); PP.AddPragmaHandler(MSVtorDisp.get()); + MSInitSeg.reset(new PragmaMSInitSeg()); + PP.AddPragmaHandler(MSInitSeg.get()); } } @@ -214,6 +222,8 @@ void Parser::resetPragmaHandlers() { MSPointersToMembers.reset(); PP.RemovePragmaHandler(MSVtorDisp.get()); MSVtorDisp.reset(); + PP.RemovePragmaHandler(MSInitSeg.get()); + MSInitSeg.reset(); } PP.RemovePragmaHandler("STDC", FPContractHandler.get()); @@ -1204,6 +1214,14 @@ void PragmaMSVtorDisp::HandlePragma(Preprocessor &PP, PP.EnterToken(AnnotTok); } +void PragmaMSInitSeg::HandlePragma(Preprocessor &PP, + PragmaIntroducerKind Introducer, + Token &Tok) { + unsigned ID = PP.getDiagnostics().getCustomDiagID( + DiagnosticsEngine::Error, "'#pragma init_seg' not implemented"); + PP.Diag(Tok.getLocation(), ID); +} + /// \brief Handle the Microsoft \#pragma detect_mismatch extension. /// /// The syntax is: diff --git a/test/CodeGenCXX/pragma-init_seg.cpp b/test/CodeGenCXX/pragma-init_seg.cpp new file mode 100644 index 0000000000..7356c52aa3 --- /dev/null +++ b/test/CodeGenCXX/pragma-init_seg.cpp @@ -0,0 +1,16 @@ +// RUN: not %clang_cc1 %s -triple=i686-pc-win32 -fms-extensions -emit-llvm-only 2>&1 | FileCheck %s + +// Reduced from WebKit. + +// FIXME: Implement this pragma and test the codegen. We probably want to +// completely skip @llvm.global_ctors and just create global function pointers +// to the initializer with the right section. + +// CHECK: '#pragma init_seg' not implemented +#pragma init_seg(".unwantedstaticinits") +struct A { + A(); + ~A(); + int a; +}; +A a; -- 2.40.0