]> granicus.if.org Git - clang/commitdiff
Relax assertion in x86_64 byval argument handling for 32-bit pointers
authorDerek Schuff <dschuff@google.com>
Wed, 24 Jun 2015 22:36:36 +0000 (22:36 +0000)
committerDerek Schuff <dschuff@google.com>
Wed, 24 Jun 2015 22:36:36 +0000 (22:36 +0000)
Summary:
Byval argument pair formation assumes that if a type is less than 8 bytes
it must be an integer and not a pointer, which is not true for x32 and NaCl.

Relax the assertion and add a test for a codegen case that triggered it.

Reviewers: jvoung

Subscribers: jfb, cfe-commits

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@240600 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/TargetInfo.cpp
test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp

index 05eafb9abac5c0ae616103dadc14a470cf5a9a17..4268f00459320a31b7c331bd04d0d175a660dc7b 100644 (file)
@@ -2504,7 +2504,8 @@ GetX86_64ByValArgumentPair(llvm::Type *Lo, llvm::Type *Hi,
     if (Lo->isFloatTy())
       Lo = llvm::Type::getDoubleTy(Lo->getContext());
     else {
-      assert(Lo->isIntegerTy() && "Invalid/unknown lo type");
+      assert((Lo->isIntegerTy() || Lo->isPointerTy())
+             && "Invalid/unknown lo type");
       Lo = llvm::Type::getInt64Ty(Lo->getContext());
     }
   }
index bb9bd888b20f21b0646d25f8aec7787acbe27e5e..3392b32bd2b6fea1c5cef77c85fb62da9659a84f 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-nacl -emit-llvm -o - %s | FileCheck %s
-// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnux32 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-nacl -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple=x86_64-unknown-linux-gnux32 -emit-llvm -o - %s | FileCheck %s
 
 struct test_struct {};
 typedef int test_struct::* test_struct_mdp;
@@ -42,3 +42,16 @@ struct struct_with_mfp_too_much {
 void f_struct_with_mfp_too_much(struct_with_mfp_too_much a, int x) {
   (void)a;
 }
+
+/* Struct containing an empty struct */
+typedef struct { int* a; test_struct x; double *b; } struct_with_empty;
+
+// CHECK-LABEL: define void @{{.*}}f_pass_struct_with_empty{{.*}}(i64 %x{{.*}}, double* %x
+void f_pass_struct_with_empty(struct_with_empty x) {
+  (void) x;
+}
+
+// CHECK-LABEL: define { i64, double* } @{{.*}}f_return_struct_with_empty
+struct_with_empty f_return_struct_with_empty() {
+  return {0, {}, 0};
+}