[cfe-dev] Clang miscompiles casted bitfields expression
Douglas Gregor
dgregor at apple.com
Thu Jul 2 17:01:47 PDT 2009
On Jul 2, 2009, at 1:09 AM, Abramo Bagnara wrote:
>
> The following typescript show the problem:
>
> $ cat w.c
>
> struct s {
> int v:8;
> };
>
> long long f(struct s *a) {
> return
> ((long long)(a->v)) << 32;
> }
>
> $ ~/eclair/src/parser/dest/bin/clang-cc -ast-dump w.c
> typedef char *__builtin_va_list;
> struct s {
> int v : (IntegerLiteral 0x9933c28 'int' 8)
> ;
> };
> long long f(struct s *a) (CompoundStmt 0x9932c28
> (ReturnStmt 0x9933fc0
> (ImplicitCastExpr 0x9933fa0 'long long'
> (BinaryOperator 0x9933f78 'int' '<<'
> (ImplicitCastExpr 0x99120f8 'int'
> (ParenExpr 0x99120b0 'long long'
> (CStyleCastExpr 0x9912088 'long long'
> (ParenExpr 0x9934e68 'int'
> (MemberExpr 0x9934e40 'int' ->v 0x9933c50
> (DeclRefExpr 0x9933d38 'struct s *' ParmVar='a'
> 0x9933c90))))))
> (IntegerLiteral 0x99120d0 'int' 32)))))
>
> As you see the long long value is casted to int before the left shift
> and this is wrong.
>
> I've tracked down the problem to
>
> Expr *Sema::UsualUnaryConversions(Expr *&Expr)
>
> which calls
>
> QualType isPromotableBitField(Expr *E, ASTContext &Context)
>
> which calls
>
> FieldDecl *Expr::getBitField()
>
> which calls
>
> Expr *Expr::IgnoreParenCasts()
>
> The problem is that the latter goes down in the expression bypassing
> also the CStyleCastExpr then inducing isPromotableBitField to return
> the
> type of the bitfield and not the type of CStyleCastExpr.
Oh, that's not good. We should skip ParenExprs, only.
> The fix should be trivial (and the problem is currently rather
> severe),
> but I want to be sure to not misunderstand something.
Want to submit the patch to fix this? (If not, please file a bug
report so it doesn't get lost)
- Doug
More information about the cfe-dev
mailing list