diff options
author | Sebastian Redl <sebastian.redl@getdesigned.at> | 2008-12-03 23:17:54 +0000 |
---|---|---|
committer | Sebastian Redl <sebastian.redl@getdesigned.at> | 2008-12-03 23:17:54 +0000 |
commit | d457589fc69dc7a9c80cd74d317c0b81a35a27c9 (patch) | |
tree | 6dfc10482b5bfc7533ce13259016998d0955842f | |
parent | 39b630fc1cef83d58c6e0f551debb16a4d547abe (diff) |
Fix some type punning errors in SizeOfAlignOf and Typeid AST nodes. This should satisfy compilers and language lawyers alike.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60511 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/Expr.h | 20 | ||||
-rw-r--r-- | include/clang/AST/ExprCXX.h | 17 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 4 | ||||
-rw-r--r-- | lib/AST/ExprCXX.cpp | 4 | ||||
-rw-r--r-- | lib/AST/StmtSerialization.cpp | 2 |
5 files changed, 32 insertions, 15 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 932885eb30..02e581dce4 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -557,15 +557,23 @@ public: class SizeOfAlignOfExpr : public Expr { bool isSizeof : 1; // true if sizeof, false if alignof. bool isType : 1; // true if operand is a type, false if an expression - void *Argument; + union { + void *Ty; + Stmt *Ex; + } Argument; SourceLocation OpLoc, RParenLoc; public: SizeOfAlignOfExpr(bool issizeof, bool istype, void *argument, QualType resultType, SourceLocation op, SourceLocation rp) : - Expr(SizeOfAlignOfExprClass, resultType), - isSizeof(issizeof), isType(istype), Argument(argument), - OpLoc(op), RParenLoc(rp) {} + Expr(SizeOfAlignOfExprClass, resultType), isSizeof(issizeof), + isType(istype), OpLoc(op), RParenLoc(rp) { + if (isType) + Argument.Ty = argument; + else + // argument was an Expr*, so cast it back to that to be safe + Argument.Ex = static_cast<Expr*>(argument); + } virtual void Destroy(ASTContext& C); @@ -573,11 +581,11 @@ public: bool isArgumentType() const { return isType; } QualType getArgumentType() const { assert(isArgumentType() && "calling getArgumentType() when arg is expr"); - return QualType::getFromOpaquePtr(Argument); + return QualType::getFromOpaquePtr(Argument.Ty); } Expr* getArgumentExpr() const { assert(!isArgumentType() && "calling getArgumentExpr() when arg is type"); - return (Expr *)Argument; + return static_cast<Expr*>(Argument.Ex); } /// Gets the argument type, or the type of the argument expression, whichever /// is appropriate. diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 2fb55fb4af..1d0a516eaf 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -193,21 +193,30 @@ public: class CXXTypeidExpr : public Expr { private: bool isTypeOp : 1; - void *Operand; + union { + void *Ty; + Stmt *Ex; + } Operand; SourceRange Range; public: CXXTypeidExpr(bool isTypeOp, void *op, QualType Ty, const SourceRange r) : - Expr(CXXTypeidExprClass, Ty), isTypeOp(isTypeOp), Operand(op), Range(r) {} + Expr(CXXTypeidExprClass, Ty), isTypeOp(isTypeOp), Range(r) { + if (isTypeOp) + Operand.Ty = op; + else + // op was an Expr*, so cast it back to that to be safe + Operand.Ex = static_cast<Stmt*>(op); + } bool isTypeOperand() const { return isTypeOp; } QualType getTypeOperand() const { assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)"); - return QualType::getFromOpaquePtr(Operand); + return QualType::getFromOpaquePtr(Operand.Ty); } Expr* getExprOperand() const { assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)"); - return static_cast<Expr*>(Operand); + return static_cast<Expr*>(Operand.Ex); } virtual SourceRange getSourceRange() const { diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 948dbc2418..e4386eceda 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1314,12 +1314,12 @@ Stmt::child_iterator SizeOfAlignOfExpr::child_begin() { return child_iterator(T); return child_iterator(); } - return child_iterator((Stmt**)&Argument); + return child_iterator(&Argument.Ex); } Stmt::child_iterator SizeOfAlignOfExpr::child_end() { if (isArgumentType()) return child_iterator(); - return child_iterator((Stmt**)&Argument + 1); + return child_iterator(&Argument.Ex + 1); } // ArraySubscriptExpr diff --git a/lib/AST/ExprCXX.cpp b/lib/AST/ExprCXX.cpp index 1bf07c4a63..2d517196be 100644 --- a/lib/AST/ExprCXX.cpp +++ b/lib/AST/ExprCXX.cpp @@ -28,10 +28,10 @@ void CXXConditionDeclExpr::Destroy(ASTContext& C) { // CXXTypeidExpr - has child iterators if the operand is an expression Stmt::child_iterator CXXTypeidExpr::child_begin() { - return isTypeOperand() ? child_iterator() : (Stmt**)&Operand; + return isTypeOperand() ? child_iterator() : &Operand.Ex; } Stmt::child_iterator CXXTypeidExpr::child_end() { - return isTypeOperand() ? child_iterator() : (Stmt**)&Operand+1; + return isTypeOperand() ? child_iterator() : &Operand.Ex+1; } // CXXBoolLiteralExpr diff --git a/lib/AST/StmtSerialization.cpp b/lib/AST/StmtSerialization.cpp index a8602245f3..78a2cbcaa7 100644 --- a/lib/AST/StmtSerialization.cpp +++ b/lib/AST/StmtSerialization.cpp @@ -1394,7 +1394,7 @@ CXXNamedCastExpr::CreateImpl(Deserializer& D, ASTContext& C, StmtClass SC) { void CXXTypeidExpr::EmitImpl(llvm::Serializer& S) const { S.Emit(getType()); - S.Emit(isTypeOperand()); + S.EmitBool(isTypeOperand()); if (isTypeOperand()) { S.Emit(getTypeOperand()); } else { |