summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Musman <alexander.musman@gmail.com>2015-06-10 11:20:26 +0000
committerAlexander Musman <alexander.musman@gmail.com>2015-06-10 11:20:26 +0000
commit70e9f5fcb3f757a5e4f6f712cce8ef72d9f61003 (patch)
tree9a25be31d6490fdce9283d24c974555cf9019bc9
parent9aa7e38bf89987bb10f0eaafb32f410c452355a1 (diff)
downloadbcm5719-llvm-70e9f5fcb3f757a5e4f6f712cce8ef72d9f61003.tar.gz
bcm5719-llvm-70e9f5fcb3f757a5e4f6f712cce8ef72d9f61003.zip
PR5172: Fix for a bug in pragma redefine_extname implementation:
it doesn't work correctly when a structure is declared before pragma and then a function with the same name declared after pragma. Patch by Andrey Bokhanko Differential Revision: http://reviews.llvm.org/D10187 llvm-svn: 239466
-rw-r--r--clang/lib/Sema/SemaDecl.cpp24
-rw-r--r--clang/test/CodeGenCXX/redefine_extname.cpp18
2 files changed, 33 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 89f4b3a0c1f..047958e2fc2 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -14197,16 +14197,22 @@ void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name,
SourceLocation PragmaLoc,
SourceLocation NameLoc,
SourceLocation AliasNameLoc) {
- Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc,
- LookupOrdinaryName);
- AsmLabelAttr *Attr = ::new (Context) AsmLabelAttr(AliasNameLoc, Context,
- AliasName->getName(), 0);
-
- if (PrevDecl)
+ NamedDecl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc,
+ LookupOrdinaryName);
+ AsmLabelAttr *Attr =
+ AsmLabelAttr::CreateImplicit(Context, AliasName->getName(), AliasNameLoc);
+
+ // If a declaration that:
+ // 1) declares a function or a variable
+ // 2) has external linkage
+ // already exists, add a label attribute to it.
+ if (PrevDecl &&
+ (isa<FunctionDecl>(PrevDecl) || isa<VarDecl>(PrevDecl)) &&
+ PrevDecl->hasExternalFormalLinkage())
PrevDecl->addAttr(Attr);
- else
- (void)ExtnameUndeclaredIdentifiers.insert(
- std::pair<IdentifierInfo*,AsmLabelAttr*>(Name, Attr));
+ // Otherwise, add a label atttibute to ExtnameUndeclaredIdentifiers.
+ else
+ (void)ExtnameUndeclaredIdentifiers.insert(std::make_pair(Name, Attr));
}
void Sema::ActOnPragmaWeakID(IdentifierInfo* Name,
diff --git a/clang/test/CodeGenCXX/redefine_extname.cpp b/clang/test/CodeGenCXX/redefine_extname.cpp
new file mode 100644
index 00000000000..2b6b703a1b8
--- /dev/null
+++ b/clang/test/CodeGenCXX/redefine_extname.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple=i386-pc-solaris2.11 -w -emit-llvm %s -o - | FileCheck %s
+
+extern "C" {
+ struct statvfs64 {
+ int f;
+ };
+#pragma redefine_extname statvfs64 statvfs
+ int statvfs64(struct statvfs64 *);
+}
+
+void foo() {
+ struct statvfs64 st;
+ statvfs64(&st);
+// Check that even if there is a structure with redefined name before the
+// pragma, subsequent function name redefined properly. PR5172, Comment 11.
+// CHECK: call i32 @statvfs(%struct.statvfs64* %st)
+}
+
OpenPOWER on IntegriCloud