PR25910: clang allows two var definitions with the same mangled name

Proper diagnostic and resolution of mangled names' conflicts in variables.
When there is a declaration and a definition using the same name but different
types, we emit what is in the definition. When there are two conflicting
definitions, we issue an error.

Differential Revision: http://reviews.llvm.org/D15686

llvm-svn: 257754
diff --git a/clang/test/CodeGenCXX/duplicate-mangled-name.cpp b/clang/test/CodeGenCXX/duplicate-mangled-name.cpp
index 104bb6e..9019214 100644
--- a/clang/test/CodeGenCXX/duplicate-mangled-name.cpp
+++ b/clang/test/CodeGenCXX/duplicate-mangled-name.cpp
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify -DTEST1
-// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify -DTEST2
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify -DTEST2 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify -DTEST3
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only %s -verify -DTEST4
 
 #ifdef TEST1
 
@@ -14,28 +16,61 @@
 
 #elif TEST2
 
-// We expect no warnings here, as there is only declaration of _ZN1TD1Ev function, no definitions.
+// expected-no-diagnostics
+
+// We expect no warnings here, as there is only declaration of _ZN1TD1Ev
+// function, no definitions.
 extern "C" void _ZN1TD1Ev();
 struct T {
   ~T() {}
 };
 
-void foo() {
-  _ZN1TD1Ev();
-  T t;
+// We expect no warnings here, as there is only declaration of _ZN2nm3abcE
+// global, no definitions.
+extern "C" {
+  int _ZN2nm3abcE;
 }
 
+namespace nm {
+  float abc = 2;
+}
+// CHECK: @_ZN2nm3abcE = global float
+
+float foo() {
+  _ZN1TD1Ev();
+// CHECK: call void bitcast (void (%struct.T*)* @_ZN1TD1Ev to void ()*)()
+  T t;
+// CHECK: call void @_ZN1TD1Ev(%struct.T* %t)
+  return _ZN2nm3abcE + nm::abc;
+}
+
+#elif TEST3
+
 extern "C" void _ZN2T2D2Ev() {}; // expected-note {{previous definition is here}}
 
 struct T2 {
   ~T2() {} // expected-error {{definition with same mangled name as another definition}}
 };
 
-void bar() {
+void foo() {
   _ZN2T2D2Ev();
   T2 t;
 }
 
+#elif TEST4
+
+extern "C" {
+  int _ZN2nm3abcE = 1; // expected-note {{previous definition is here}}
+}
+
+namespace nm {
+  float abc = 2; // expected-error {{definition with same mangled name as another definition}}
+}
+
+float foo() {
+  return _ZN2nm3abcE + nm::abc;
+}
+
 #else
 
 #error Unknwon test