From b6cfa3dd320ec64c7b21f6b3a88373f4db63d6a6 Mon Sep 17 00:00:00 2001
From: David Majnemer <david.majnemer@gmail.com>
Date: Wed, 9 Sep 2015 20:57:59 +0000
Subject: [PATCH] [MS ABI] Don't crash on references to pointers to members in
 args

We know that a reference can always be dereferenced.  However, we don't
always know the number of bytes if the reference's pointee type is
incomplete.  This case was correctly handled but we didn't consider the
case where the type is complete but we cannot calculate its size for ABI
specific reasons.  In this specific case, a member pointer's size is
available only under certain conditions.

This fixes PR24703.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@247188 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CGCall.cpp                            | 4 ++--
 test/CodeGenCXX/microsoft-abi-member-pointers.cpp | 6 ++++++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index ef9095291cd..b54264b5054 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -1586,7 +1586,7 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
 
   if (const auto *RefTy = RetTy->getAs<ReferenceType>()) {
     QualType PTy = RefTy->getPointeeType();
-    if (!PTy->isIncompleteType() && PTy->isConstantSizeType())
+    if (getCXXABI().isTypeInfoCalculable(PTy) && PTy->isConstantSizeType())
       RetAttrs.addDereferenceableAttr(getContext().getTypeSizeInChars(PTy)
                                         .getQuantity());
     else if (getContext().getTargetAddressSpace(PTy) == 0)
@@ -1698,7 +1698,7 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
 
     if (const auto *RefTy = ParamType->getAs<ReferenceType>()) {
       QualType PTy = RefTy->getPointeeType();
-      if (!PTy->isIncompleteType() && PTy->isConstantSizeType())
+      if (getCXXABI().isTypeInfoCalculable(PTy) && PTy->isConstantSizeType())
         Attrs.addDereferenceableAttr(getContext().getTypeSizeInChars(PTy)
                                        .getQuantity());
       else if (getContext().getTargetAddressSpace(PTy) == 0)
diff --git a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
index 27a2a5fc9c1..25d7c7702da 100644
--- a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
+++ b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
@@ -745,4 +745,10 @@ void foo_fun() {
   // CHECK: store i8* bitcast (void (%class.CA*)* @"\01?OnHelp@CA@@QAEXXZ" to i8*), i8**
   f func = (f)&CA::OnHelp;
 }
+namespace PR24703 {
+struct S;
+
+void f(int S::*&p) {}
+// CHECK-LABEL: define void @"\01?f@PR24703@@YAXAAPQS@1@H@Z"(
+}
 
-- 
GitLab