Hi rnk,

This addresses PR21035. For now, we are unable to represent the
possibility of jumping between asm IR blocks in LLVM, so these kinds of
jumps don't play well with the SSA model. This patch adds a diagnostic
that detect those kinds of jumps, based on the information that the LLVM
side patch exposes from MC.

Note that this diagnostic is unable to differentiate between branches
versus other kinds of label access, so it covers them all.

http://reviews.llvm.org/D5694

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/SemaStmtAsm.cpp
  test/Parser/ms-inline-asm.c
  test/Sema/ms-inline-asm.c
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -4165,6 +4165,8 @@
   "cannot jump from this goto statement to label %0 inside an inline assembly block">;
 def note_goto_ms_asm_label : Note<
   "inline assembly label %0 declared here">;
+def err_cross_block_asm_label_use : Error<
+  "cannot use inline assembly label %0 defined outside of an inline assembly block">;
 def warn_unused_label : Warning<"unused label %0">,
   InGroup<UnusedLabel>, DefaultIgnore;
 
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -3166,6 +3166,7 @@
   LabelDecl *GetOrCreateMSAsmLabel(StringRef ExternalLabelName,
                                    SourceLocation Location,
                                    bool AlwaysCreate);
+  void DiagnoseCrossBlockLabelUse(const LabelDecl *Label);
 
   VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType,
                                   SourceLocation StartLoc,
Index: lib/Parse/ParseStmtAsm.cpp
===================================================================
--- lib/Parse/ParseStmtAsm.cpp
+++ lib/Parse/ParseStmtAsm.cpp
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include <set>
 #include "clang/Parse/Parser.h"
 #include "RAIIObjectsForParser.h"
 #include "clang/AST/ASTContext.h"
@@ -45,6 +46,9 @@
   /// The offset of each token in AsmToks within AsmString.
   ArrayRef<unsigned> AsmTokOffsets;
 
+  /// The LabelDecls encountered when parsing the asm block.
+  std::set<LabelDecl*> LabelDecls;
+
 public:
   ClangAsmParserCallback(Parser &P, SourceLocation Loc, StringRef AsmString,
                          ArrayRef<Token> Toks, ArrayRef<unsigned> Offsets)
@@ -99,6 +103,7 @@
     SourceLocation Loc = translateLocation(LSM, Location);
     LabelDecl *Label =
       TheParser.getActions().GetOrCreateMSAsmLabel(Identifier, Loc, Create);
+    LabelDecls.insert(Label);
     return Label->getMSAsmLabel();
   }
 
@@ -108,6 +113,14 @@
                                                        AsmLoc);
   }
 
+  void CheckExternalLabels() {
+    for (const auto *Label : LabelDecls) {
+      if (!Label->isResolvedMSAsmLabel()) {
+        TheParser.getActions().DiagnoseCrossBlockLabelUse(Label);
+      }
+    }
+  }
+
   static void DiagHandlerCallback(const llvm::SMDiagnostic &D, void *Context) {
     ((ClangAsmParserCallback *)Context)->handleDiagnostic(D);
   }
@@ -581,6 +594,8 @@
     Exprs[i] = OpExpr;
   }
 
+  Callback.CheckExternalLabels();
+
   // FIXME: We should be passing source locations for better diagnostics.
   return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLocs[0], AsmToks, AsmStringIR,
                                 NumOutputs, NumInputs, ConstraintRefs,
Index: lib/Sema/SemaStmtAsm.cpp
===================================================================
--- lib/Sema/SemaStmtAsm.cpp
+++ lib/Sema/SemaStmtAsm.cpp
@@ -585,3 +585,8 @@
 
   return Label;
 }
+
+void Sema::DiagnoseCrossBlockLabelUse(const LabelDecl *Label) {
+  Diag(Label->getLocStart(), diag::err_cross_block_asm_label_use)
+    << Label->getIdentifier();
+}
Index: test/Parser/ms-inline-asm.c
===================================================================
--- test/Parser/ms-inline-asm.c
+++ test/Parser/ms-inline-asm.c
@@ -49,7 +49,38 @@
   do { __asm mov eax, 0 __asm { __asm mov edx, 1 } } while(0);
 }
 void t12() {
-  __asm jmp label // expected-error {{use of undeclared label 'label'}}
+  __asm jmp label // expected-error {{use of undeclared label 'label'}} expected-error {{cannot use inline assembly label 'label' defined outside of an inline assembly block}}
+}
+void t13() {
+  __asm {
+    jmp lbl1 // expected-error {{cannot use inline assembly label 'lbl1' defined outside of an inline assembly block}}
+  }
+  __asm {
+    lbl1:
+    nop
+  }
+}
+void t14() {
+  __asm {
+    jmp lbl2 // expected-error {{cannot use inline assembly label 'lbl2' defined outside of an inline assembly block}}
+  }
+  for (;;) {
+    __asm {
+      lbl2:
+      nop
+    }
+  }
+}
+void t15() {
+  for (;;) {
+    __asm {
+      jmp lbl2 // expected-error {{cannot use inline assembly label 'lbl2' defined outside of an inline assembly block}}
+    }
+  }
+  __asm {
+    lbl2:
+    nop
+  }
 }
 int t_fail() { // expected-note {{to match this}}
   __asm 
Index: test/Sema/ms-inline-asm.c
===================================================================
--- test/Sema/ms-inline-asm.c
+++ test/Sema/ms-inline-asm.c
@@ -106,7 +106,7 @@
 }
 
 __declspec(naked) int t5(int x) { // expected-note {{attribute is here}}
-  asm { movl eax, x } // expected-error {{parameter references not allowed in naked functions}} expected-error {{use of undeclared label 'x'}}
+  asm { movl eax, x } // expected-error {{parameter references not allowed in naked functions}} expected-error {{use of undeclared label 'x'}} expected-error {{cannot use inline assembly label 'x' defined outside of an inline assembly block}}
   asm { retl }
 }
 
@@ -146,7 +146,7 @@
 
 void t11() {
 foo:
-  __asm mov eax, foo // expected-error {{use of undeclared label 'foo'}} expected-warning {{unused label 'foo'}}
+  __asm mov eax, foo // expected-error {{use of undeclared label 'foo'}} expected-error {{cannot use inline assembly label 'foo' defined outside of an inline assembly block}}
 }
 
 void t12() {
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to