]> granicus.if.org Git - clang/commitdiff
Error on redeclaring with a conflicting asm label and on redeclaring with an asm...
authorNick Lewycky <nicholas@mxc.ca>
Fri, 11 Dec 2015 21:28:55 +0000 (21:28 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Fri, 11 Dec 2015 21:28:55 +0000 (21:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@255371 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/Sema/asm-label.c [new file with mode: 0644]

index f1a8c279dc5e5684b1c5883770be28c4c2e1b306..c008888f74ef3d2b944ae7700d5afbb937039603 100644 (file)
@@ -4259,6 +4259,9 @@ def err_tag_definition_of_typedef : Error<
 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_different_asm_label : Error<"conflicting asm label">;
 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 af5fdc95c9091df9c538222041aae6ce516bfe60..6a61ac0e44ce0de55052d5314f8975c89144d922 100644 (file)
@@ -2379,9 +2379,24 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old,
   if (!Old->hasAttrs() && !New->hasAttrs())
     return;
 
-  // attributes declared post-definition are currently ignored
+  // Attributes declared post-definition are currently ignored.
   checkNewAttributesAfterDef(*this, New, Old);
 
+  if (AsmLabelAttr *NewA = New->getAttr<AsmLabelAttr>()) {
+    if (AsmLabelAttr *OldA = Old->getAttr<AsmLabelAttr>()) {
+      if (OldA->getLabel() != NewA->getLabel()) {
+        // This redeclaration changes __asm__ label.
+        Diag(New->getLocation(), diag::err_different_asm_label);
+        Diag(OldA->getLocation(), diag::note_previous_declaration);
+      }
+    } else if (Old->isUsed()) {
+      // This redeclaration adds an __asm__ label to a declaration that has
+      // already been ODR-used.
+      Diag(New->getLocation(), diag::err_late_asm_label_name)
+        << isa<FunctionDecl>(Old) << New->getAttr<AsmLabelAttr>()->getRange();
+    }
+  }
+
   if (!Old->hasAttrs())
     return;
 
diff --git a/test/Sema/asm-label.c b/test/Sema/asm-label.c
new file mode 100644 (file)
index 0000000..87cda2f
--- /dev/null
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -verify %s
+
+void f();
+void f() __asm__("fish");
+void g();
+
+void f() {
+  g();
+}
+void g() __asm__("gold");  // expected-error{{cannot apply asm label to function after its first use}}
+
+void h() __asm__("hose");  // expected-note{{previous declaration is here}}
+void h() __asm__("hair");  // expected-error{{conflicting asm label}}
+
+int x;
+int x __asm__("xenon");
+int y;
+
+int test() { return y; }
+
+int y __asm__("yacht");  // expected-error{{cannot apply asm label to variable after its first use}}
+
+int z __asm__("zebra");  // expected-note{{previous declaration is here}}
+int z __asm__("zooms");  // expected-error{{conflicting asm label}}
+
+
+// No diagnostics on the following.
+void __real_readlink() __asm("readlink");
+void readlink() __asm("__protected_readlink");
+void readlink() { __real_readlink(); }