mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-08 09:03:18 +00:00
[CodeGenObjCXX] Don't rematerialize default arguments of function
parameters in the body of a block. This fixes a bug where clang would materialize the default argument inside the body of a block instead of passing the value via the block descriptor. For example, in the code below, foo1 would always print 42 regardless of the value of argument "a" passed to foo1. void foo1(const int a = 42 ) { auto block = ^{ printf("%d\n", a); }; block(); } rdar://problem/24449235 llvm-svn: 268314
This commit is contained in:
parent
64f7a995b0
commit
3ba6535096
@ -262,6 +262,11 @@ static bool isSafeForCXXConstantCapture(QualType type) {
|
||||
static llvm::Constant *tryCaptureAsConstant(CodeGenModule &CGM,
|
||||
CodeGenFunction *CGF,
|
||||
const VarDecl *var) {
|
||||
// Don't rematerialize default arguments of function parameters.
|
||||
if (auto *PD = dyn_cast<ParmVarDecl>(var))
|
||||
if (PD->hasDefaultArg())
|
||||
return nullptr;
|
||||
|
||||
QualType type = var->getType();
|
||||
|
||||
// We can only do this if the variable is const.
|
||||
|
16
clang/test/CodeGenObjCXX/block-default-arg.mm
Normal file
16
clang/test/CodeGenObjCXX/block-default-arg.mm
Normal file
@ -0,0 +1,16 @@
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -std=c++11 -fblocks -fobjc-arc | FileCheck %s
|
||||
|
||||
// CHECK: define internal void @___Z16test_default_argi_block_invoke(i8* %[[BLOCK_DESCRIPTOR:.*]])
|
||||
// CHECK: %[[BLOCK:.*]] = bitcast i8* %[[BLOCK_DESCRIPTOR]] to <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>*
|
||||
// CHECK: %[[BLOCK_CAPTURE_ADDR:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %[[BLOCK]], i32 0, i32 5
|
||||
// CHECK: %[[V0:.*]] = load i32, i32* %[[BLOCK_CAPTURE_ADDR]]
|
||||
// CHECK: call void @_Z4foo1i(i32 %[[V0]])
|
||||
|
||||
void foo1(int);
|
||||
|
||||
void test_default_arg(const int a = 42) {
|
||||
auto block = ^{
|
||||
foo1(a);
|
||||
};
|
||||
block();
|
||||
}
|
Loading…
Reference in New Issue
Block a user