Fix a couple of cases where we weren't generating the right kind of call
for a call to a virtual function.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@88891 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp
index 5a0cb16..a3ab476 100644
--- a/lib/CodeGen/CGCXX.cpp
+++ b/lib/CodeGen/CGCXX.cpp
@@ -282,14 +282,20 @@
   // We also don't emit a virtual call if the base expression has a record type
   // because then we know what the type is.
   llvm::Value *Callee;
-  if (MD->isVirtual() && !ME->hasQualifier() && 
-      !canDevirtualizeMemberFunctionCalls(ME->getBase()))
-    Callee = BuildVirtualCall(MD, This, Ty);
-  else if (const CXXDestructorDecl *Destructor
-             = dyn_cast<CXXDestructorDecl>(MD))
-    Callee = CGM.GetAddrOfFunction(GlobalDecl(Destructor, Dtor_Complete), Ty);
-  else
+  if (const CXXDestructorDecl *Destructor
+             = dyn_cast<CXXDestructorDecl>(MD)) {
+    if (MD->isVirtual() && !ME->hasQualifier() && 
+        !canDevirtualizeMemberFunctionCalls(ME->getBase())) {
+      Callee = BuildVirtualCall(Destructor, Dtor_Complete, This, Ty); 
+    } else {
+      Callee = CGM.GetAddrOfFunction(GlobalDecl(Destructor, Dtor_Complete), Ty);
+    }
+  } else if (MD->isVirtual() && !ME->hasQualifier() && 
+             !canDevirtualizeMemberFunctionCalls(ME->getBase())) {
+    Callee = BuildVirtualCall(MD, This, Ty); 
+  } else {
     Callee = CGM.GetAddrOfFunction(MD, Ty);
+  }
 
   return EmitCXXMemberCall(MD, Callee, This,
                            CE->arg_begin(), CE->arg_end());
@@ -425,10 +431,15 @@
   const llvm::Type *Ty =
     CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
                                    FPT->isVariadic());
-  llvm::Constant *Callee = CGM.GetAddrOfFunction(MD, Ty);
 
   llvm::Value *This = EmitLValue(E->getArg(0)).getAddress();
 
+  llvm::Value *Callee;
+  if (MD->isVirtual() && !canDevirtualizeMemberFunctionCalls(E->getArg(0)))
+    Callee = BuildVirtualCall(MD, This, Ty);
+  else
+    Callee = CGM.GetAddrOfFunction(MD, Ty);
+
   return EmitCXXMemberCall(MD, Callee, This,
                            E->arg_begin() + 1, E->arg_end());
 }
diff --git a/test/CodeGenCXX/virtual-operator-call.cpp b/test/CodeGenCXX/virtual-operator-call.cpp
new file mode 100644
index 0000000..018052b
--- /dev/null
+++ b/test/CodeGenCXX/virtual-operator-call.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s
+
+struct A {
+  virtual int operator-() = 0;
+};
+
+void f(A *a) {
+  // CHECK: call i32 %
+  -*a;
+}
diff --git a/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp b/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp
new file mode 100644
index 0000000..3d99a02
--- /dev/null
+++ b/test/CodeGenCXX/virtual-pseudo-destructor-call.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-cc %s -emit-llvm -o - | FileCheck %s
+
+struct A {
+  virtual ~A();
+};
+
+void f(A *a) {
+  // CHECK: call void %
+  a->~A();
+}