[cfe-commits] r92173 - in /cfe/trunk: lib/AST/ExprConstant.cpp test/CodeGenCXX/const-base-cast.cpp
Eli Friedman
eli.friedman at gmail.com
Sat Dec 26 21:43:16 PST 2009
Author: efriedma
Date: Sat Dec 26 23:43:15 2009
New Revision: 92173
URL: http://llvm.org/viewvc/llvm-project?rev=92173&view=rev
Log:
Fix PointerExprEvaluator::VisitCastExpr so it doesn't misfold C++ casts which
it doesn't know how to fold, like derived-to-base casts.
Added:
cfe/trunk/test/CodeGenCXX/const-base-cast.cpp
Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=92173&r1=92172&r2=92173&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sat Dec 26 23:43:15 2009
@@ -222,7 +222,6 @@
APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
APValue VisitDeclRefExpr(DeclRefExpr *E);
- APValue VisitBlockExpr(BlockExpr *E);
APValue VisitPredefinedExpr(PredefinedExpr *E) { return APValue(E, 0); }
APValue VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
APValue VisitMemberExpr(MemberExpr *E);
@@ -270,13 +269,6 @@
return APValue();
}
-APValue LValueExprEvaluator::VisitBlockExpr(BlockExpr *E) {
- if (E->hasBlockDeclRefExprs())
- return APValue();
-
- return APValue(E, 0);
-}
-
APValue LValueExprEvaluator::VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
if (!Info.AnyLValue && !E->isFileScope())
return APValue();
@@ -366,7 +358,7 @@
APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
APValue VisitBinaryOperator(const BinaryOperator *E);
- APValue VisitCastExpr(const CastExpr* E);
+ APValue VisitCastExpr(CastExpr* E);
APValue VisitUnaryExtension(const UnaryOperator *E)
{ return Visit(E->getSubExpr()); }
APValue VisitUnaryAddrOf(const UnaryOperator *E);
@@ -443,23 +435,49 @@
}
-APValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) {
- const Expr* SubExpr = E->getSubExpr();
+APValue PointerExprEvaluator::VisitCastExpr(CastExpr* E) {
+ Expr* SubExpr = E->getSubExpr();
+
+ switch (E->getCastKind()) {
+ default:
+ break;
+
+ case CastExpr::CK_Unknown: {
+ // FIXME: The handling for CK_Unknown is ugly/shouldn't be necessary!
- // Check for pointer->pointer cast
- if (SubExpr->getType()->isPointerType() ||
- SubExpr->getType()->isObjCObjectPointerType() ||
- SubExpr->getType()->isNullPtrType()) {
- APValue Result;
- if (EvaluatePointer(SubExpr, Result, Info))
+ // Check for pointer->pointer cast
+ if (SubExpr->getType()->isPointerType() ||
+ SubExpr->getType()->isObjCObjectPointerType() ||
+ SubExpr->getType()->isNullPtrType() ||
+ SubExpr->getType()->isBlockPointerType())
+ return Visit(SubExpr);
+
+ if (SubExpr->getType()->isIntegralType()) {
+ APValue Result;
+ if (!EvaluateIntegerOrLValue(SubExpr, Result, Info))
+ break;
+
+ if (Result.isInt()) {
+ Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
+ return APValue(0, Result.getInt().getZExtValue());
+ }
+
+ // Cast is of an lvalue, no need to change value.
return Result;
- return APValue();
+ }
+ break;
}
- if (SubExpr->getType()->isIntegralType()) {
+ case CastExpr::CK_NoOp:
+ case CastExpr::CK_BitCast:
+ case CastExpr::CK_AnyPointerToObjCPointerCast:
+ case CastExpr::CK_AnyPointerToBlockPointerCast:
+ return Visit(SubExpr);
+
+ case CastExpr::CK_IntegralToPointer: {
APValue Result;
if (!EvaluateIntegerOrLValue(SubExpr, Result, Info))
- return APValue();
+ break;
if (Result.isInt()) {
Result.getInt().extOrTrunc((unsigned)Info.Ctx.getTypeSize(E->getType()));
@@ -469,14 +487,13 @@
// Cast is of an lvalue, no need to change value.
return Result;
}
-
- if (SubExpr->getType()->isFunctionType() ||
- SubExpr->getType()->isBlockPointerType() ||
- SubExpr->getType()->isArrayType()) {
+ case CastExpr::CK_ArrayToPointerDecay:
+ case CastExpr::CK_FunctionToPointerDecay: {
APValue Result;
if (EvaluateLValue(SubExpr, Result, Info))
return Result;
- return APValue();
+ break;
+ }
}
return APValue();
Added: cfe/trunk/test/CodeGenCXX/const-base-cast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/const-base-cast.cpp?rev=92173&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/const-base-cast.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/const-base-cast.cpp Sat Dec 26 23:43:15 2009
@@ -0,0 +1,11 @@
+// RUN: clang -cc1 -O1 -emit-llvm %s -o - | FileCheck %s
+
+// Check that the following construct, which is similar to one which occurs
+// in Firefox, is not misfolded (folding it correctly would be a bonus, but
+// that doesn't work at the moment, hence the -O1 in the runline).
+struct A { char x; };
+struct B { char y; };
+struct C : A,B {};
+unsigned char x = ((char*)(B*)(C*)0x1000) - (char*)0x1000;
+
+// CHECK: @x = global i8 1
More information about the cfe-commits
mailing list