]> granicus.if.org Git - clang/commitdiff
[CodeGen] When promoting a reference temporary to a global use the inner type to...
authorBenjamin Kramer <benny.kra@googlemail.com>
Thu, 9 Apr 2015 16:09:29 +0000 (16:09 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Thu, 9 Apr 2015 16:09:29 +0000 (16:09 +0000)
The MaterializeTemporaryExpr can have a different type than the inner
expression, miscompiling the constant. PR23165.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@234499 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExpr.cpp
test/CodeGenCXX/cxx0x-initializer-references.cpp

index f86e970c25aff053bf44dfe958ee2633f1efd969..dd66f6cc7a103ff7b1837664c5188db32e40810e 100644 (file)
@@ -309,12 +309,13 @@ createReferenceTemporary(CodeGenFunction &CGF,
         (M->getType()->isArrayType() || M->getType()->isRecordType()) &&
         CGF.CGM.isTypeConstant(M->getType(), true))
       if (llvm::Constant *Init =
-              CGF.CGM.EmitConstantExpr(Inner, M->getType(), &CGF)) {
+              CGF.CGM.EmitConstantExpr(Inner, Inner->getType(), &CGF)) {
         auto *GV = new llvm::GlobalVariable(
             CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
             llvm::GlobalValue::PrivateLinkage, Init, ".ref.tmp");
-        GV->setAlignment(
-            CGF.getContext().getTypeAlignInChars(M->getType()).getQuantity());
+        GV->setAlignment(CGF.getContext()
+                             .getTypeAlignInChars(Inner->getType())
+                             .getQuantity());
         // FIXME: Should we put the new global into a COMDAT?
         return GV;
       }
index d4a8f20f35730f6717d5bf0461312227735b439e..bdc97b5bd5018fbc8bdb498512234996c93a4440 100644 (file)
@@ -1,5 +1,7 @@
 // RUN: %clang_cc1 -std=c++11 -S -triple armv7-none-eabi -emit-llvm -o - %s | FileCheck %s
 
+// CHECK: private constant { i8** } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN7PR2316510ChildClassE, i64 0, i64 2) }, align 4
+
 namespace reference {
   struct A {
     int i1, i2;
@@ -79,3 +81,22 @@ namespace reference {
   }
 
 }
+
+namespace PR23165 {
+struct AbstractClass {
+  virtual void foo() const = 0;
+};
+
+struct ChildClass : public AbstractClass {
+  virtual void foo() const {}
+};
+
+void helper(const AbstractClass &param) {
+  param.foo();
+}
+
+void foo() {
+// CHECK: call void @_ZN7PR231656helperERKNS_13AbstractClassE(%{{.*}} bitcast ({ i8** }* @{{.*}} to %{{.*}}*))
+  helper(ChildClass());
+}
+}