On Thu, Nov 24, 2016 at 12:43 AM, Nicolai Stange <nicstange@xxxxxxxxx> wrote: > > I don't think that this would qualify as a constant expression of any > type. > >> How about (void*)(0 + 'a') and (void*)0 + 'a', are they address constant >> or not? > > Strictly speaking, neither of them is. > > Despite of this, we would (hopefully) mark the second case as an address > constant though. > > Reason: this series flags address constants as such because they may be > used as a "constant expression in an initializer", i.e. as initializers > for static storage duration variables. That is good info. Thanks for the clarify. BTW, gcc does not seem to complain about const integer issue on, [(int)(float)0] = 0, // KO [(int)(void*)0] = 0, // KO gcc seems does what make snese rather than stick to the book. In your patch: static struct token *builtin_types_compatible_p_expr(struct token *token, struct expression **tree) { struct expression *expr = alloc_expression( token->pos, EXPR_COMPARE); - expr->flags = Int_const_expr; expr->op = SPECIAL_EQUAL; token = token->next; if (!match_op(token, '(')) I think __builtin_xxx function expand similar to the processor macro. In that sense, we might want to the consider this expression as integer constant express as if the __builtin_xxx call is either 0 or 1. Again, gcc does not complain about: [__builtin_types_compatible_p(typeof(1), int)] = 0, // KO This makes sense, but not according the "strict" rules. >> >> Basically, there are six bits as basic element. One bit per element. >> Integer constant, enum constant, char constant, float constant, >> address constant, >> arithmetic constant. > > + integer constant *expression* > > Take 0 + 0, for example: this is not an integer constant, but an integer > constant *expression* (and an arithmetic constant expression as well). Ah, I see. I change my plan according this. The six basic element define as: Integer constant, enum constant, char constant, float constant, address constant, composite op. The composite op bit get set after binary operation or uniop. The flags can have more than one bit set for the expression. Integer constant expression can be tested as: !(flags & ( Addr | Float) ) && flag Arithmetic constant expression can be tested as: !(flags & Addr) ) && flag Do you see any problem with this internal representation? Chris -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html