PR22830 shows a case where some code was adding an __asm__ label after the
first use of a function. GCC and Clang diverged on this code, GCC emitting
the name in the last __asm__ label for all uses while clang would switch in
the middle of the TU as the redeclaration was parsed. The attached patch
detects this case and issues an error on such a redeclaration. If this
breaks real code, we can turn it down to a warning.

Please review!

Nick
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 255303)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -4256,6 +4256,8 @@
 def err_conflicting_types : Error<"conflicting types for %0">;
 def err_different_pass_object_size_params : Error<
   "conflicting pass_object_size attributes on parameters">;
+def err_late_asm_label_name : Error<
+  "cannot apply asm label to %select{variable|function}0 after its first use">;
 def err_nested_redefinition : Error<"nested redefinition of %0">;
 def err_use_with_wrong_tag : Error<
   "use of %0 with tag type that does not match previous declaration">;
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp	(revision 255303)
+++ lib/Sema/SemaDecl.cpp	(working copy)
@@ -2379,9 +2379,17 @@
   if (!Old->hasAttrs() && !New->hasAttrs())
     return;
 
-  // attributes declared post-definition are currently ignored
+  // Attributes declared post-definition are currently ignored.
   checkNewAttributesAfterDef(*this, New, Old);
 
+  // Check whether this redeclaration adds an __asm__ label name to a
+  // declaration that has already been used.
+  if (Old->isUsed() && !Old->hasAttr<AsmLabelAttr>() &&
+      New->hasAttr<AsmLabelAttr>()) {
+    Diag(New->getLocation(), diag::err_late_asm_label_name)
+      << isa<FunctionDecl>(Old) << New->getAttr<AsmLabelAttr>()->getRange();
+  }
+
   if (!Old->hasAttrs())
     return;
 
Index: test/Sema/asm-label.c
===================================================================
--- test/Sema/asm-label.c	(revision 0)
+++ test/Sema/asm-label.c	(working copy)
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -verify %s
+
+void f();
+void g();
+void f() __asm__("fish");
+
+void f() {
+  g();
+}
+void g() __asm__("gold");  // expected-error{{cannot apply asm label to function after its first use}}
+
+int x;
+int y;
+int x __asm__("xenon");
+
+int test() { return y; }
+
+int y __asm__("yacht");   // expected-error{{cannot apply asm label to variable after its first use}}
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to