[cfe-dev] For Review: C++ Casting Patch
Chris Lattner
clattner at apple.com
Mon Apr 14 23:51:13 PDT 2008
On Apr 6, 2008, at 3:48 AM, Bill Wendling wrote:
> Attached is my latest patch for the C++ casting checks. It
> incorporates all of the feedback from Chris.
Hi Bill, sorry for the delay,
This is getting better, but still has canonical type problems:
+static QualType BuildSubType(QualType Ty, unsigned Depth, ASTContext
&Ctx) {
...
assert(isa<PointerType>(Ty) && "This should be a pointer type!");
+
+ QualType Base = Ty->getAsPointerType()->getPointeeType();
The assert should be Ty->isPointerType(), which is true even if 'Ty'
is a typedef for a pointer. Your regtest should include some
typedefs ;-)
+ if (Base.isConstQualified()) QT.addConst();
+ if (Base.isVolatileQualified()) QT.addVolatile();
+ if (Base.isRestrictQualified()) QT.addRestrict();
You can just use: QualType(QT.getTypePtr(), Base.getCVRQualifiers())
+bool Sema::CastsAwayConstness(QualType CastFrom, QualType CastTo) {
..
+ if (CastTo->isPointerType() && CastFrom->isPointerType()) {
+ QualType From = BuildSubType(CastFrom, K, Context);
+ QualType To = BuildSubType(CastTo, K, Context);
+
+ return CastsAwayConstnessFromPointers(From, To);
Since 'BuildSubType' is O(n) in the pointer depth of its argument,
this means that 'CastsAwayConstness' is O(n^2). Surely there has to
be a better way to evaluate this relation than with 'BuildSubType'?
Also, the name 'BuildSubType' is too generic to be useful.
...
+ if (!isa<PointerType>(To)) break;
...
Should be To->isPointerType()
+ if (CastTyBase.getTypePtr() == ExprTyBase.getTypePtr())
+ return true;
This isn't safe, one might be a typedef for the other. Also, you
should have comments in your methods explaining why you are doing what
you are doing.
+ if (To == From) // {C++ [expr.const.cast] p2} Casting to same type.
+ return To;
Not safe with typedefs.
Action::ExprResult
Sema::ActOnCXXCasts(SourceLocation OpLoc, tok::TokenKind Kind,
...
+ case tok::kw_const_cast:
+ Op = CXXCastExpr::ConstCast;
+ ResultTy = CheckConstCastOperator(OpLoc,
QualType::getFromOpaquePtr(Ty),
+ Exp);
...
+
+ if (ResultTy.isNull()) {
+ delete Exp;
+ return true;
+ }
+
+ return new CXXCastExpr(Op, ResultTy, Exp, OpLoc);
}
To simplify the code, I'd suggest 'new'ing the CastExpr in each case
arm, assigning into an OwningPointer. The ActOnCall implementation
does this to good effect.
-Chris
More information about the cfe-dev
mailing list