Erich Plondke <eplondke@xxxxxxxxx> writes: > I would like to combine __builtin_choose_expr with __builtin_constant_p, in > something like this: > > #define SHIFTLEFT(a,b) __builtin_choose_expr(__builtin_constant_p(b), \ > ((a) << (b)), \ > ((a) << (MIN(31,MAX(-31,(b))))) > > I could use this to determine whether I need special behavoir, because I might > be able to assume that constants were never in some "bad range" of values. > > Unfortunately, when I try this, I get: > > file.c:42 error: first argument to __builtin_choose_expr not a constant > > However, according to the documentation, __builtin_constant_p should > return 0 if the compiler cannot prove that the argument expression > is a constant. One would expect that 0 is a constant, and that it should > always be a valid first argument to __builtin_choose_expr. > > Am I doing something wrong? Perhaps we could have > __builtin_constant_constant_p() that would be a valid constant always? Please include a complete test case, and please say which compiler version you are using. I constructed a test case. If I pass an integer as the second argument to SHIFTLEFT, it works correctly. If I do not turn on optimization, it works correctly. If I pass a local variable, and I optimize, it fails. This is the test case which fails with optimization: #define SHIFTLEFT(a,b) __builtin_choose_expr(__builtin_constant_p(b), \ ((a) << (b)), \ ((a) << (MIN(31,MAX(-31,(b)))))) int foo(int a, int b) { return SHIFTLEFT (a, b); } Basically __builtin_choose_expr, as currently implemented, requires the first argument to resolve to a constant during parsing. __builtin_constant_p, as currently implemented, returns a constant during parsing when given an easy case, but in other cases postpones the decision. My first reaction, like yours, is that this is a bug. Please file a complete bug report at http://gcc.gnu.org/bugzilla. Thanks. Ian