mirror of https://github.com/microsoft/clang.git
Error on redeclaring with a conflicting asm label and on redeclaring with an asm label after the first ODR-use. Detects problems like the one in PR22830 where gcc and clang both compiled the file but with different behaviour.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@255371 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
96e7b7f14b
commit
7271e6a357
|
@ -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">;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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(); }
|
Loading…
Reference in New Issue