<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Thu, Apr 9, 2015 at 9:09 AM, Benjamin Kramer <span dir="ltr"><<a href="mailto:benny.kra@googlemail.com" target="_blank">benny.kra@googlemail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: d0k<br>
Date: Thu Apr  9 11:09:29 2015<br>
New Revision: 234499<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=234499&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=234499&view=rev</a><br>
Log:<br>
[CodeGen] When promoting a reference temporary to a global use the inner type to fold it.<br>
<br>
The MaterializeTemporaryExpr can have a different type than the inner<br>
expression, miscompiling the constant. PR23165.<br>
<br>
Modified:<br>
    cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
    cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=234499&r1=234498&r2=234499&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=234499&r1=234498&r2=234499&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Apr  9 11:09:29 2015<br>
@@ -309,12 +309,13 @@ createReferenceTemporary(CodeGenFunction<br>
         (M->getType()->isArrayType() || M->getType()->isRecordType()) &&<br>
         CGF.CGM.isTypeConstant(M->getType(), true))<br></blockquote><div><br></div><div>This reference to M->getType() should be changed to Inner->getType() too. Consider a case like:</div><div><br></div><div>  struct S { struct T { int a; } t; mutable int b; };</div><div>  void f() { const S::T &r = S().t; }<br></div><div><br></div><div>Here, we shouldn't emit the temporary as a global constant due to the mutable member.</div><div><br></div><div>The same is probably true of the array type / record type check -- if the reference temporary itself is of array or reference type, and we're binding a reference to a non-array/non-reference subobject, we should probably still promote to a global.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
       if (llvm::Constant *Init =<br>
-              CGF.CGM.EmitConstantExpr(Inner, M->getType(), &CGF)) {<br>
+              CGF.CGM.EmitConstantExpr(Inner, Inner->getType(), &CGF)) {<br>
         auto *GV = new llvm::GlobalVariable(<br>
             CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,<br>
             llvm::GlobalValue::PrivateLinkage, Init, ".ref.tmp");<br>
-        GV->setAlignment(<br>
-            CGF.getContext().getTypeAlignInChars(M->getType()).getQuantity());<br>
+        GV->setAlignment(CGF.getContext()<br>
+                             .getTypeAlignInChars(Inner->getType())<br>
+                             .getQuantity());<br>
         // FIXME: Should we put the new global into a COMDAT?<br>
         return GV;<br>
       }<br>
<br>
Modified: cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp?rev=234499&r1=234498&r2=234499&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp?rev=234499&r1=234498&r2=234499&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp (original)<br>
+++ cfe/trunk/test/CodeGenCXX/cxx0x-initializer-references.cpp Thu Apr  9 11:09:29 2015<br>
@@ -1,5 +1,7 @@<br>
 // RUN: %clang_cc1 -std=c++11 -S -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s<br>
<br>
+// CHECK: private constant { i8** } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN7PR2316510ChildClassE, i64 0, i64 2) }, align 4<br>
+<br>
 namespace reference {<br>
   struct A {<br>
     int i1, i2;<br>
@@ -79,3 +81,22 @@ namespace reference {<br>
   }<br>
<br>
 }<br>
+<br>
+namespace PR23165 {<br>
+struct AbstractClass {<br>
+  virtual void foo() const = 0;<br>
+};<br>
+<br>
+struct ChildClass : public AbstractClass {<br>
+  virtual void foo() const {}<br>
+};<br>
+<br>
+void helper(const AbstractClass &param) {<br>
+  param.foo();<br>
+}<br>
+<br>
+void foo() {<br>
+// CHECK: call void @_ZN7PR231656helperERKNS_13AbstractClassE(%{{.*}} bitcast ({ i8** }* @{{.*}} to %{{.*}}*))<br>
+  helper(ChildClass());<br>
+}<br>
+}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>