From 3c6a48d1193e4745f36db9ce7faf859a8cc407ad Mon Sep 17 00:00:00 2001 From: Derek Schuff Date: Wed, 24 Jun 2015 22:36:36 +0000 Subject: [PATCH] Relax assertion in x86_64 byval argument handling for 32-bit pointers 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 llvm-svn: 240600 --- clang/lib/CodeGen/TargetInfo.cpp | 3 ++- clang/test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 05eafb9..4268f00 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -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()); } } diff --git a/clang/test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp b/clang/test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp index bb9bd88..3392b32 100644 --- a/clang/test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp +++ b/clang/test/CodeGenCXX/x86_64-arguments-nacl-x32.cpp @@ -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}; +} -- 2.7.4