diff options
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 3 | ||||
-rw-r--r-- | test/CodeGen/blocks.c | 18 |
2 files changed, 20 insertions, 1 deletions
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 379da11033..1a1fe65ff8 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -469,9 +469,10 @@ static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF, elementTypes.push_back(llvm::ArrayType::get(CGM.Int8Ty, padding.getQuantity())); blockSize = newBlockSize; - endAlign = maxFieldAlign; + endAlign = getLowBit(blockSize); // might be > maxFieldAlign } + assert(endAlign >= maxFieldAlign); assert(endAlign == getLowBit(blockSize)); // Slam everything else on now. This works because they have diff --git a/test/CodeGen/blocks.c b/test/CodeGen/blocks.c index 77fb0e1899..40bab5f63d 100644 --- a/test/CodeGen/blocks.c +++ b/test/CodeGen/blocks.c @@ -42,9 +42,27 @@ void f3() { } // rdar://problem/11322251 +// The bool can fill in between the header and the long long. +// Add the appropriate amount of padding between them. void f4_helper(long long (^)(void)); +// CHECK: define void @f4() void f4(void) { _Bool b = 0; long long ll = 0; + // CHECK: alloca <{ i8*, i32, i32, i8*, {{%.*}}*, i8, [3 x i8], i64 }>, align 8 f4_helper(^{ if (b) return ll; return 0LL; }); } + +// rdar://problem/11354538 +// The alignment after rounding up to the align of F5 is actually +// greater than the required alignment. Don't assert. +struct F5 { + char buffer[32] __attribute((aligned)); +}; +void f5_helper(void (^)(struct F5 *)); +// CHECK: define void @f5() +void f5(void) { + struct F5 value; + // CHECK: alloca <{ i8*, i32, i32, i8*, {{%.*}}*, [12 x i8], [[F5:%.*]] }>, align 16 + f5_helper(^(struct F5 *slot) { *slot = value; }); +} |