[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