On Wed, Nov 18, 2020 at 10:31:43AM -0800, Linus Torvalds wrote: > On Tue, Nov 17, 2020 at 3:22 PM Linus Torvalds > <torvalds@xxxxxxxxxxxxxxxxxxxx> wrote: > > > > Would doing the same unqualify_type() in degenerate() be sufficient? > > Actually, that's a stupid suggestion. Forget I ever mentioned it. > > I should have reacted to Martin Ucker pointing out > > > > lvalue conversion drops qualifers in C. In GCC, this is not > > > implemented correctly as it is unobvervable in standard C > > > (but it using typeof). > > with the notable point that it is unobservable outside of "typeof". > > I'm not actually entirely sure that is true: if you don't drop > qualifiers, it's potentially observable in code generation, in that a > "volatile" that didn't get dropped might perhaps cause unnecessary Yes, I had already added some testcases with volatile because the the rules for const & volatile are different. > memory ops. But from a kernel variable type standpoint where we want > to just drop qualifiers on variables using "typeof()", maybe the > simplest solution would be just special-casing typeof itself, using > something (entirely untested and probably complete garbage) like this: I don't think it's a good idea. The focus now is all about dropping the qualifiers but in code like: const int x; typeof(c) y; don't we want 'y' to also have the type 'const int'? For the moment I'm testing the patch here under. It fixes the qualifier dropping for comma expressions, and same for statement expressions. It also, I think, fixes evaluate_postop() which has the inverse error of dropping qualifiers but shouldn't. I think that all the other cases are covered (but the code is fragile because most qualifier dropping are done implicitly via classify_type() which strip everything). diff --git a/evaluate.c b/evaluate.c index fd84205c7f2c..8599fcee6875 100644 --- a/evaluate.c +++ b/evaluate.c @@ -1028,7 +1028,7 @@ static struct symbol *evaluate_binop(struct expression *expr) static struct symbol *evaluate_comma(struct expression *expr) { - expr->ctype = degenerate(expr->right); + expr->ctype = unqualify_type(degenerate(expr->right)); if (expr->ctype == &null_ctype) expr->ctype = &ptr_ctype; expr->flags &= expr->left->flags & expr->right->flags; @@ -1935,8 +1935,7 @@ static struct symbol *evaluate_postop(struct expression *expr) if (multiply) { evaluate_assign_to(op, op->ctype); expr->op_value = multiply; - expr->ctype = ctype; - return ctype; + return expr->ctype = op->ctype; } expression_error(expr, "bad argument type for ++/--"); @@ -3950,7 +3949,7 @@ struct symbol *evaluate_statement(struct statement *stmt) return NULL; if (stmt->expression->ctype == &null_ctype) stmt->expression = cast_to(stmt->expression, &ptr_ctype); - return degenerate(stmt->expression); + return unqualify_type(degenerate(stmt->expression)); case STMT_COMPOUND: { struct statement *s; -- Luc