source: tests/eval.cfa @ 748877f

Last change on this file since 748877f was 8f557161, checked in by Michael Brooks <mlbrooks@…>, 17 months ago

Clarify and fix accuracy in eval public API, on reporting "unable to evaluate."

While the eval internals always used the flag pair valid and cfavalid almost correctly, the public interface exposed the outcome as a single flag, and the various interpretations of this flag were a mess.

Old cfacc treated sizeof(whatever) in some contexts as "known to be zero," which is wrong.
The generally correct answer, which new cfacc now uses is, "unknown now, but GCC will see it as a fine constant."
New tests/eval.cfa captures this fact: is runnable and would fail on old cfacc; it passes with new cfacc.

  • Property mode set to 100644
File size: 1.6 KB
RevLine 
[8f557161]1//
2// Cforall Version 1.0.0 Copyright (C) 2020 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// eval.cfa -- tests of static expression evaluation inside cfacc
8//
9// Author           : Michael Brooks
10// Created On       : Tue Jun 13 15:00:00 2023
11// Last Modified By : Michael Brooks
12// Last Modified On : Tue Jun 13 15:00:00 2023
13// Update Count     : 1
14//
15
16// Tests that target specific cases of `eval`, of Common/Eval.h.
17// So logically unit tests, but driven inderctly though the usual rig.
18
19#ifndef __cforall
20int printf(const char *, ...);
21#endif
22
23// A bug found and fixed with eval of sizeof.
24// Driving it through the black-box rig was a matter of reverse engineering.
25// Seen failing on rev 576aad.
26// White-box relevance:
27// - Initializer of `a`, which is `{1, 2, 3}` checks its element expressions
28//   (e.g. `2`) against the type being initialized (`int[bar]`) to see if a
29//   `2` makes sense here.
30// - Understanding this type evaluates the index expression `bar`, whose
31//   value comes from a sizeof expression.  General sizeof expressions are
32//   unknown to cfacc, because C's implementation-specific rules affect
33//   struct layout.
34// - When the bug was observed, this evaluation was returning "known to be 0".
35//   If the array's size were zero, the intializer would be invalid.  So a
36//   buggy cfacc rejects this program.
37// GCC accepts this program.
38void test_sizeof_1() {
39    struct foo { int x; };
40    enum { bar = sizeof(struct foo) };
41    int a[bar] = {1, 2, 3};
42}
43
44int main() {
45    test_sizeof_1();
46    printf("Done\n");
47}
Note: See TracBrowser for help on using the repository browser.