[PATCH] Fixing a clang crash with duplicate mangled name
Yunzhong Gao
Yunzhong_Gao at playstation.sony.com
Tue Mar 17 18:48:31 PDT 2015
Hi,
The following test case crashes in different places depending on whether or not -femit-all-decls is passed
on the command-line. I am thinking that moving the err_duplicate_mangled_name diagnostic from
EmitGlobalFunctionDefinition() into EmitGlobal() should fix the issue.
$ clang -S -emit-llvm -o - test.cpp
$ clang -S -femit-all-decls -emit-llvm -o - test.cpp
// test.cpp
extern "C" int printf(const char *, ...);
void foo(void) __asm("_ZN1SC2Ev");
void foo(void) { }
struct S {
S() {
printf("S constructor\n");
};
} var;
// end test.cpp
What do you think?
- Gao
http://reviews.llvm.org/D8405
Files:
lib/CodeGen/CodeGenModule.cpp
test/CodeGenCXX/duplicate-mangled-name2.cpp
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -1370,6 +1370,31 @@
/*DontDefer=*/false);
return;
}
+
+ // Compute the function info and LLVM type.
+ const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(GD);
+ llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
+ llvm::GlobalValue *GV = nullptr;
+
+ // Get or create the prototype for the function.
+ llvm::Constant *C =
+ GetAddrOfFunction(GD, Ty, /*ForVTable=*/false, /*DontDefer*/true);
+
+ // Strip off a bitcast if we got one back.
+ if (auto *CE = dyn_cast<llvm::ConstantExpr>(C)) {
+ assert(CE->getOpcode() == llvm::Instruction::BitCast);
+ GV = cast<llvm::GlobalValue>(CE->getOperand(0));
+ } else {
+ GV = cast<llvm::GlobalValue>(C);
+ }
+
+ if (!GV->isDeclaration()) {
+ getDiags().Report(FD->getLocation(), diag::err_duplicate_mangled_name);
+ GlobalDecl OldGD = Manglings.lookup(GV->getName());
+ if (auto *Prev = OldGD.getDecl())
+ getDiags().Report(Prev->getLocation(), diag::note_previous_definition);
+ return;
+ }
} else {
const auto *VD = cast<VarDecl>(Global);
assert(VD->isFileVarDecl() && "Cannot emit local var decl as global.");
@@ -2412,14 +2437,6 @@
}
}
- if (!GV->isDeclaration()) {
- getDiags().Report(D->getLocation(), diag::err_duplicate_mangled_name);
- GlobalDecl OldGD = Manglings.lookup(GV->getName());
- if (auto *Prev = OldGD.getDecl())
- getDiags().Report(Prev->getLocation(), diag::note_previous_definition);
- return;
- }
-
if (GV->getType()->getElementType() != Ty) {
// If the types mismatch then we have to rewrite the definition.
assert(GV->isDeclaration() && "Shouldn't replace non-declaration");
Index: test/CodeGenCXX/duplicate-mangled-name2.cpp
===================================================================
--- test/CodeGenCXX/duplicate-mangled-name2.cpp
+++ test/CodeGenCXX/duplicate-mangled-name2.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify
+// RUN: %clang_cc1 -triple %itanium_abi_triple -femit-all-decls -emit-llvm-only %s -verify
+
+void foo(void) __asm("_ZN1SC2Ev");
+void foo(void) { } // expected-note {{previous}}
+
+struct S {
+ S() {} // expected-error {{definition with same mangled name as another definition}}
+} s;
\ No newline at end of file
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D8405.22151.patch
Type: text/x-patch
Size: 2539 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150318/81db1f48/attachment.bin>
More information about the cfe-commits
mailing list