]> granicus.if.org Git - clang/commitdiff
-fms-extensions: Error out on #pragma init_seg
authorReid Kleckner <reid@kleckner.net>
Thu, 3 Apr 2014 19:04:24 +0000 (19:04 +0000)
committerReid Kleckner <reid@kleckner.net>
Thu, 3 Apr 2014 19:04:24 +0000 (19:04 +0000)
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
lib/Parse/ParsePragma.cpp
test/CodeGenCXX/pragma-init_seg.cpp [new file with mode: 0644]

index 44f7cb1e05c27af5a31bd9424f9d43738c3d15d1..db527f6e45368842101844002c52527e99263682 100644 (file)
@@ -154,6 +154,7 @@ class Parser : public CodeCompletionHandler {
   std::unique_ptr<PragmaHandler> MSDetectMismatchHandler;
   std::unique_ptr<PragmaHandler> MSPointersToMembers;
   std::unique_ptr<PragmaHandler> MSVtorDisp;
+  std::unique_ptr<PragmaHandler> MSInitSeg;
 
   std::unique_ptr<CommentHandler> CommentSemaHandler;
 
index 29e17715b3b11fe59e58a8605822c141e841ac53..33c1f0b628fb47b23e65589a7a41ef61644e8209 100644 (file)
@@ -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 (file)
index 0000000..7356c52
--- /dev/null
@@ -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;