[llvm-branch-commits] [cfe-branch] r121539 - in /cfe/branches/Apple/whitney: include/clang/AST/RecordLayout.h lib/AST/ExprConstant.cpp test/CodeGenCXX/global-init.cpp

Daniel Dunbar daniel at zuster.org
Fri Dec 10 13:36:57 PST 2010


Author: ddunbar
Date: Fri Dec 10 15:36:57 2010
New Revision: 121539

URL: http://llvm.org/viewvc/llvm-project?rev=121539&view=rev
Log:
Merge r117868:
--
Author: Anders Carlsson <andersca at mac.com>
Date:   Sun Oct 31 20:41:46 2010 +0000

    Teach the constant expr evaluator about derived-to-base casts when no virtual bases are involved. Fixes PR5974.

Modified:
    cfe/branches/Apple/whitney/include/clang/AST/RecordLayout.h
    cfe/branches/Apple/whitney/lib/AST/ExprConstant.cpp
    cfe/branches/Apple/whitney/test/CodeGenCXX/global-init.cpp

Modified: cfe/branches/Apple/whitney/include/clang/AST/RecordLayout.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/include/clang/AST/RecordLayout.h?rev=121539&r1=121538&r2=121539&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/include/clang/AST/RecordLayout.h (original)
+++ cfe/branches/Apple/whitney/include/clang/AST/RecordLayout.h Fri Dec 10 15:36:57 2010
@@ -16,6 +16,7 @@
 
 #include "llvm/System/DataTypes.h"
 #include "llvm/ADT/DenseMap.h"
+#include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclCXX.h"
 
 namespace clang {

Modified: cfe/branches/Apple/whitney/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/lib/AST/ExprConstant.cpp?rev=121539&r1=121538&r2=121539&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/lib/AST/ExprConstant.cpp (original)
+++ cfe/branches/Apple/whitney/lib/AST/ExprConstant.cpp Fri Dec 10 15:36:57 2010
@@ -568,6 +568,42 @@
   case CK_AnyPointerToBlockPointerCast:
     return Visit(SubExpr);
 
+  case CK_DerivedToBase:
+  case CK_UncheckedDerivedToBase: {
+    LValue BaseLV;
+    if (!EvaluatePointer(E->getSubExpr(), BaseLV, Info))
+      return false;
+
+    // Now figure out the necessary offset to add to the baseLV to get from
+    // the derived class to the base class.
+    uint64_t Offset = 0;
+
+    QualType Ty = E->getSubExpr()->getType();
+    const CXXRecordDecl *DerivedDecl = 
+      Ty->getAs<PointerType>()->getPointeeType()->getAsCXXRecordDecl();
+
+    for (CastExpr::path_const_iterator PathI = E->path_begin(), 
+         PathE = E->path_end(); PathI != PathE; ++PathI) {
+      const CXXBaseSpecifier *Base = *PathI;
+
+      // FIXME: If the base is virtual, we'd need to determine the type of the
+      // most derived class and we don't support that right now.
+      if (Base->isVirtual())
+        return false;
+
+      const CXXRecordDecl *BaseDecl = Base->getType()->getAsCXXRecordDecl();
+      const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(DerivedDecl);
+
+      Offset += Layout.getBaseClassOffset(BaseDecl);
+      DerivedDecl = BaseDecl;
+    }
+
+    Result.Base = BaseLV.getLValueBase();
+    Result.Offset = BaseLV.getLValueOffset() + 
+      CharUnits::fromQuantity(Offset / Info.Ctx.getCharWidth());
+    return true;
+  }
+
   case CK_IntegralToPointer: {
     APValue Value;
     if (!EvaluateIntegerOrLValue(SubExpr, Value, Info))

Modified: cfe/branches/Apple/whitney/test/CodeGenCXX/global-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/Apple/whitney/test/CodeGenCXX/global-init.cpp?rev=121539&r1=121538&r2=121539&view=diff
==============================================================================
--- cfe/branches/Apple/whitney/test/CodeGenCXX/global-init.cpp (original)
+++ cfe/branches/Apple/whitney/test/CodeGenCXX/global-init.cpp Fri Dec 10 15:36:57 2010
@@ -17,6 +17,11 @@
 // It's okay if we ever implement the IR-generation optimization to remove this.
 // CHECK: @_ZN5test3L3varE = internal constant i8* getelementptr inbounds ([7 x i8]* 
 
+// PR6205: The casts should not require global initializers
+// CHECK: @_ZN6PR59741cE = external global %"struct.PR5974::C"
+// CHECK: @_ZN6PR59741aE = global %"struct.PR5974::A"* bitcast (%"struct.PR5974::C"* @_ZN6PR59741cE to %"struct.PR5974::A"*), align 8
+// CHECK: @_ZN6PR59741bE = global %"struct.PR5974::A"* bitcast (i8* getelementptr (%"struct.PR5974::C"* @_ZN6PR59741cE, i32 0, i32 0, i64 4) to %"struct.PR5974::A"*), align 8
+
 // CHECK: call void @_ZN1AC1Ev(%struct.A* @a)
 // CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
 A a;
@@ -64,6 +69,17 @@
   const char *test() { return var; }
 }
 
+namespace PR5974 {
+  struct A { int a; };
+  struct B { int b; };
+  struct C : A, B { int c; };
+
+  extern C c;
+
+  // These should not require global initializers.
+  A* a = &c;
+  B* b = &c;
+}
 // CHECK:      define internal void [[TEST1_Z_INIT:@.*]]()
 // CHECK:        load i32* @_ZN5test1L1yE
 // CHECK-NEXT:   xor





More information about the llvm-branch-commits mailing list