[PATCH] D11297: PR17829: Functions declared extern "C" with a name matching a mangled C++ function are allowed
Andrey Bokhanko
andreybokhanko at gmail.com
Fri Jul 17 07:26:48 PDT 2015
andreybokhanko created this revision.
andreybokhanko added reviewers: rjmccall, rsmith.
andreybokhanko added a subscriber: cfe-commits.
This patch fixes compiler crash described in the following thread: http://lists.cs.uiuc.edu/pipermail/cfe-dev/2015-July/thread.html#43852. It also fixes incorrect behavior described in PR17829.
In essence, I inserted a check in GetAddrOfFunction that verifies that no two different declarations correspond to the same mangled name. Given that clang defers everything, this is the best suitable place I managed to find for the check. Also, the check makes sense only if one of declarations is a C++ method, as there are some kinds of non-C++ declarations that can correctly have the same mangled name (inline assembly inserts is an example).
Yours,
Andrey Bokhanko
============
Software Engineer
Intel Compiler Team
Intel
http://reviews.llvm.org/D11297
Files:
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CodeGenModule.cpp
test/CodeGenCXX/duplicate-mangled-name.cpp
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -1666,6 +1666,21 @@
Ty = getTypes().ConvertType(cast<ValueDecl>(GD.getDecl())->getType());
StringRef MangledName = getMangledName(GD);
+
+ // Check that there are no declarations with the same mangled name. This check
+ // is valid only if one of declarations is a C++ method.
+ GlobalDecl OldGD;
+ if (lookupRepresentativeDecl(MangledName, OldGD) &&
+ (isa<CXXMethodDecl>(GD.getDecl()) ||
+ isa<CXXMethodDecl>(OldGD.getDecl())) &&
+ GD.getCanonicalDecl().getDecl() != OldGD.getCanonicalDecl().getDecl()) {
+ getDiags().Report(GD.getDecl()->getLocation(),
+ diag::err_duplicate_mangled_name);
+ getDiags().Report(OldGD.getDecl()->getLocation(),
+ diag::note_previous_definition);
+ return llvm::UndefValue::get(VoidPtrTy);
+ }
+
return GetOrCreateLLVMFunction(MangledName, Ty, GD, ForVTable, DontDefer);
}
@@ -2401,6 +2416,9 @@
llvm::Constant *C =
GetAddrOfFunction(GD, Ty, /*ForVTable=*/false, /*DontDefer*/ true);
+ if (isa<llvm::UndefValue>(C))
+ return;
+
// Strip off a bitcast if we got one back.
if (auto *CE = dyn_cast<llvm::ConstantExpr>(C)) {
assert(CE->getOpcode() == llvm::Instruction::BitCast);
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -3181,6 +3181,10 @@
}
llvm::Value *Callee = EmitScalarExpr(E->getCallee());
+
+ if (isa<llvm::UndefValue>(Callee))
+ return RValue::get(Callee);
+
return EmitCall(E->getCallee()->getType(), Callee, E, ReturnValue,
TargetDecl);
}
Index: test/CodeGenCXX/duplicate-mangled-name.cpp
===================================================================
--- test/CodeGenCXX/duplicate-mangled-name.cpp
+++ test/CodeGenCXX/duplicate-mangled-name.cpp
@@ -1,10 +1,31 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only -DTEST1 %s -verify
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only -DTEST2 %s -verify
// rdar://15522601
+#ifdef TEST1
class MyClass {
static void meth();
};
void MyClass::meth() { } // expected-note {{previous}}
extern "C" {
void _ZN7MyClass4methEv() { } // expected-error {{definition with same mangled name as another definition}}
}
+
+#elif TEST2
+
+extern "C" void _ZN1TD1Ev(); // expected-error {{definition with same mangled name as another definition}}
+struct T {
+ ~T() {} // expected-note {{previous}}
+};
+
+int main() {
+ _ZN1TD1Ev();
+ T t;
+}
+
+#else
+
+#error Unknown test mode
+
+#endif
+
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D11297.30000.patch
Type: text/x-patch
Size: 2844 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150717/2e2cefe8/attachment.bin>
More information about the cfe-commits
mailing list