[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