https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66963
Bug ID: 66963 Summary: __builtin_constant_p and __builtin_choose_expr do not agree on what is a constexpr with -O2 Product: gcc Version: 5.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: nicstange at gmail dot com Target Milestone: --- The first argument to __builtin_choose_expr() must be a constant expression. However, at -O2, the following does not work: int foo (void) { const int a = 0; return __builtin_choose_expr(__builtin_choose_expr(__builtin_constant_p(a + 1), a + 1, 0), 0, 0); } test.c: In function ‘foo’: test.c:4:10: error: first argument to ‘__builtin_choose_expr’ not a constant return __builtin_choose_expr(__builtin_choose_expr(__builtin_constant_p(a + 1), a + 1, 0), ^ Obviously, __builtin_constant_p() recognizes 'a+1' as being constant-foldable and returns nonzero. This makes the inner __builtin_choose_expr() select its second argument, i.e. 'a+1'. The outer __builtin_choose_expr() in turn refuses to accept that 'a+1' as a constant expression for its condition argument because it does not recognize it as a constexpr. As a workaround, you can wrap the 'a+1' in a __builtin_expect() which seems to apply constant-folding in the same way the __builtin_constant_p() does: __builtin_choose_expr(__builtin_choose_expr(__builtin_constant_p(a + 1), __builtin_expect(a + 1, 1), 0), 0, 0); Thus, it looks like constant folding is not applied to __builtin_choose_expr()'s first argument.