Skip to content

Commit

Permalink
__builtin_constant_p: properly test, fix behaviour
Browse files Browse the repository at this point in the history
We previously only compile-time tested what required a run-time check of
assertions, so move this to the "cbmc" regression test suite. Also,
extend it by behaviour that distinguishes it from actual C-standard
specified constant expressions. Finally, fix the behaviour for string
literals.
  • Loading branch information
tautschnig committed Dec 13, 2023
1 parent 8ef7e92 commit 433de81
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 29 deletions.
28 changes: 0 additions & 28 deletions regression/ansi-c/gcc_builtin_constant_p1/main.c

This file was deleted.

45 changes: 45 additions & 0 deletions regression/cbmc/gcc_builtin_constant_p1/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include <assert.h>

enum
{
E1 = 1
} var;

struct whatnot
{
} whatnot_var;

int main()
{
// this is gcc only

#ifdef __GNUC__
assert(__builtin_constant_p("some string"));
assert(__builtin_constant_p(1.0f));
assert(__builtin_constant_p(E1));
assert(!__builtin_constant_p(var));
assert(!__builtin_constant_p(main));
assert(!__builtin_constant_p(whatnot_var));
assert(!__builtin_constant_p(&var));
assert(__builtin_constant_p(__builtin_constant_p(var)));

// The following are not constant expressions in the sense of the C standard
// and GCC wouldn't deem them constant expressions either, but they are
// subject to GCC's constant folding. See also regression test ansi-c/sizeof6.
// Clang's behaviour, however, is somewhat different. See
// https://github.com/llvm/llvm-project/issues/55946 for further examples of
// where they differ.
int j;
# ifndef __clang__
assert(__builtin_constant_p(j * 0));
assert(__builtin_constant_p(j - j));
assert(__builtin_constant_p(j ? 0ll : 0ll));
# endif
assert(__builtin_constant_p(0 ? j : 0ll));

// side-effects are _not_ evaluated
int i = 0;
assert(!__builtin_constant_p(i++));
assert(i == 0);
#endif
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
CORE gcc-only broken-test-c++-front-end
CORE
main.c

^VERIFICATION SUCCESSFUL$
^EXIT=0$
^SIGNAL=0$
--
Expand Down
2 changes: 2 additions & 0 deletions src/ansi-c/c_typecheck_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3682,6 +3682,8 @@ exprt c_typecheck_baset::do_special_functions(
{
is_constant=true;
}
else if(tmp1.id() == ID_string_constant)
is_constant = true;
else
is_constant=tmp1.is_constant();

Expand Down

0 comments on commit 433de81

Please sign in to comment.