<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, May 2, 2016 at 2:52 PM, Akira Hatanaka via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: ahatanak<br>
Date: Mon May  2 16:52:57 2016<br>
New Revision: 268314<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=268314&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=268314&view=rev</a><br>
Log:<br>
[CodeGenObjCXX] Don't rematerialize default arguments of function<br>
parameters in the body of a block.<br>
<br>
This fixes a bug where clang would materialize the default argument<br>
inside the body of a block instead of passing the value via the block<br>
descriptor.<br>
<br>
For example, in the code below, foo1 would always print 42 regardless<br>
of the value of argument "a" passed to foo1.<br>
<br>
void foo1(const int a = 42 ) {<br>
  auto block = ^{<br>
    printf("%d\n", a);<br>
  };<br>
  block();<br>
}<br>
<br>
rdar://problem/24449235<br>
<br>
Added:<br>
    cfe/trunk/test/CodeGenObjCXX/<a href="http://block-default-arg.mm" rel="noreferrer" target="_blank">block-default-arg.mm</a><br>
Modified:<br>
    cfe/trunk/lib/CodeGen/CGBlocks.cpp<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=268314&r1=268313&r2=268314&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=268314&r1=268313&r2=268314&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Mon May  2 16:52:57 2016<br>
@@ -262,6 +262,11 @@ static bool isSafeForCXXConstantCapture(<br>
 static llvm::Constant *tryCaptureAsConstant(CodeGenModule &CGM,<br>
                                             CodeGenFunction *CGF,<br>
                                             const VarDecl *var) {<br>
+  // Don't rematerialize default arguments of function parameters.<br>
+  if (auto *PD = dyn_cast<ParmVarDecl>(var))<br>
+    if (PD->hasDefaultArg())<br></blockquote><div><br></div><div>I don't think you need this test, and I think it somewhat confuses the intent here. (A reader would wonder why you want to keep going for ParmVarDecls that don't have default arguments.)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+      return nullptr;<br>
+<br>
   QualType type = var->getType();<br>
<br>
   // We can only do this if the variable is const.<br>
<br>
Added: cfe/trunk/test/CodeGenObjCXX/<a href="http://block-default-arg.mm" rel="noreferrer" target="_blank">block-default-arg.mm</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/block-default-arg.mm?rev=268314&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/block-default-arg.mm?rev=268314&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenObjCXX/<a href="http://block-default-arg.mm" rel="noreferrer" target="_blank">block-default-arg.mm</a> (added)<br>
+++ cfe/trunk/test/CodeGenObjCXX/<a href="http://block-default-arg.mm" rel="noreferrer" target="_blank">block-default-arg.mm</a> Mon May  2 16:52:57 2016<br>
@@ -0,0 +1,16 @@<br>
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10.0.0 -emit-llvm -o - %s -std=c++11 -fblocks -fobjc-arc | FileCheck  %s<br>
+<br>
+// CHECK: define internal void @___Z16test_default_argi_block_invoke(i8* %[[BLOCK_DESCRIPTOR:.*]])<br>
+// CHECK: %[[BLOCK:.*]] = bitcast i8* %[[BLOCK_DESCRIPTOR]] to <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>*<br>
+// 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<br>
+// CHECK: %[[V0:.*]] = load i32, i32* %[[BLOCK_CAPTURE_ADDR]]<br>
+// CHECK: call void @_Z4foo1i(i32 %[[V0]])<br>
+<br>
+void foo1(int);<br>
+<br>
+void test_default_arg(const int a = 42) {<br>
+  auto block = ^{<br>
+    foo1(a);<br>
+  };<br>
+  block();<br>
+}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>