Recover instead of crashing on MS assembly when no target is loaded
authorAlp Toker <alp@nuanti.com>
Wed, 30 Oct 2013 14:29:28 +0000 (14:29 +0000)
committerAlp Toker <alp@nuanti.com>
Wed, 30 Oct 2013 14:29:28 +0000 (14:29 +0000)
It's possible to embed the frontend in applications that haven't initialized
backend targets so we need to handle this condition gracefully.

llvm-svn: 193685

clang/include/clang/Basic/DiagnosticParseKinds.td
clang/lib/Parse/ParseStmt.cpp
clang/test/Index/ms-asm-no-target.cpp [new file with mode: 0644]

index 774e9e9..a45e89e 100644 (file)
@@ -23,6 +23,8 @@ def err_asm_empty : Error<"__asm used with no assembly instructions">;
 def err_inline_ms_asm_parsing : Error<"%0">;
 def err_msasm_unsupported_arch : Error<
   "Unsupported architecture '%0' for MS-style inline assembly">;
+def err_msasm_unable_to_create_target : Error<
+  "MS-style inline assembly is not available: %0">;
 }
 
 let CategoryName = "Parse Issue" in {
index caf0011..2ff83cb 100644 (file)
@@ -2104,9 +2104,15 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
   if (UnsupportedArch)
     Diag(AsmLoc, diag::err_msasm_unsupported_arch) << TheTriple.getArchName();
     
+  std::string Error;
+  const std::string &TT = TheTriple.getTriple();
+  const llvm::Target *TheTarget = llvm::TargetRegistry::lookupTarget(TT, Error);
+  if (!TheTarget)
+    Diag(AsmLoc, diag::err_msasm_unable_to_create_target) << Error;
+
   // If we don't support assembly, or the assembly is empty, we don't
   // need to instantiate the AsmParser, etc.
-  if (UnsupportedArch || AsmToks.empty()) {
+  if (UnsupportedArch || !TheTarget || AsmToks.empty()) {
     return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, StringRef(),
                                   /*NumOutputs*/ 0, /*NumInputs*/ 0,
                                   ConstraintRefs, ClobberRefs, Exprs, EndLoc);
@@ -2118,11 +2124,6 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
   if (buildMSAsmString(PP, AsmLoc, AsmToks, TokOffsets, AsmString))
     return StmtError();
 
-  // Find the target and create the target specific parser.
-  std::string Error;
-  const std::string &TT = TheTriple.getTriple();
-  const llvm::Target *TheTarget = llvm::TargetRegistry::lookupTarget(TT, Error);
-
   OwningPtr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT));
   OwningPtr<llvm::MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TT));
   // Get the instruction descriptor.
diff --git a/clang/test/Index/ms-asm-no-target.cpp b/clang/test/Index/ms-asm-no-target.cpp
new file mode 100644 (file)
index 0000000..acc555b
--- /dev/null
@@ -0,0 +1,9 @@
+// RUN: c-index-test -test-load-source all -triple x86_64-apple-darwin10 -fasm-blocks -Wno-microsoft %s 2>&1 | FileCheck %s
+
+// Test that we diagnose when the application hasn't initialized LLVM targets
+// supporting the MS-style inline asm parser.
+
+void Break() {
+  __asm { int 3 }
+}
+// CHECK: error: MS-style inline assembly is not available