From: rfg@netcom.com (Ronald F. Guilmette)
Subject: Re: Standard conformance and GCC 2.3.3
Organization: Netcom Online Communications Services (408-241-9760 login: guest)
Date: Wed, 30 Dec 1992 20:24:05 GMT

I appreciate the efforts of everyone who has taken the time to look over
the problem reports I have posted for GCC 2.3.3.

I'm forced to admit that several of my test cases are themselves buggy,
but perhaps not quite as many as some people (e.g. Norman Diamond) have
claimed.  Still, the discussion of these issues has been enlightening
for me, and (I hope) for other folks as well.

When I made my posting, listing the things I felt that GCC 2.3.3 was not
doing correctly, I probably should have clarified my approach and philosophy
regarding C compiler testing.  This would have avoided a good deal of
misunderstanding.

When testing ANSI C compilers, it is important to be aware of two "escape
hatches" which are built into the ANSI C standard itself, and which can
often make the testing process itself an exercize in futility.  These two
escape hatches are:

	o	An implementation is allowed to issue "diagnostics" even in
		the total absence of violations of the letter or the spirit
		of the standard.  The effect of this rule (on testing) is
		that it is essentially futile to write "positive" test cases
		which attempt to verify that an implementation is "standard
		conforming" by seeing if it "accepts" (presumably without
		issuing diagnostics) a "standard conforming program".  For
		any such test case that you may devise, a standard conforming
		compiler may (at its discression) issue one or more disgnostics
		regardless of the "conformance" of the code in question, and
		the implementation may still be properly considered to be
		"conformant".  Thus, the best a tester (such as myself) can
		do is to write "positive" test cases which (at best) may
		only be claimed to test "quality of implementation" (as
		opposed to standard conformance).  This fact does not deter
		me, and I *have* written a large number of such tests.  I
		would have to agree however with anyone who might claim that
		my posting of the results of any of these "positive" tests
		to the comp.std.c newsgroup may have been inappropriate,
		since "standard conformance" is not at issue when considering
		these results.

		(By the way, I would hasten to note that the "official" U.S.
		government test suite for C compilers also contains a signifi-
		cant number of what I call "positive" tests.  I borrowed the
		term "positive test" from the Ada compiler validation suite.)

	o	An implementation is allowed to define the term "diagnostic"
		in any way it chooses.  Thus, the sudden implosion of the
		video monitor on a microcomputer, workstation, or terminal,
		followed by the splattering of the programmer which high
		velocity shards of broken glass may be considered to be a
		valid "diagnostic" (although a somewhat unfriendly one)
		according the ANSI C standard.  Again, in my testing of C
		compilers, I am forced by practical considerations to use
		a somewhat more restrictive (and more traditional) definition
		of the term "diagnostic", and my results reflect that
		approach.  I trust that readers of comp.std.c will forgive
		me if (for practical reasons) I do not consider compiler
		crashes, implosions of monitors, or solar eclipses to be
		examples of valid "diagnostics" (even though all such events
		might alert me to potential problems ahead).

With all that said, let me now respond in detail to the issues raised by
Normal Diamond with respect to me earlier posting.  In many cases, I'm
forced to agree with Norman, while in others, I must respectfully disagree.

-------------------------------------------------------------------------
In article <C02I8I.58I@jrd.dec.com> diamond@jit.dec.com (Norman Diamond) writes:
+In article <1992Dec30.011211.11409@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
+>-----------------------------------------------------------------------------
+>#1)  GCC [-pedantic-errors] fails to detect the error in the following code
+>void foo () {
+>  extern void bar (int i, ...);
+>  bar (99, 88, 77);
+>}
+>void bar (int i, int j, int k) { }      /* ERROR */
+
+The call is irrelevant.

I agree.  For this case, the behavior is undefined.  I have moved this test
case to my "undefined behavior" pile.

+>-----------------------------------------------------------------------------
+>#2)  GCC [-pedantic-errors] fails to detect the error in the following code
+>unsigned long overflow = LONG_MAX + 3; /* ERROR */
+
+Again I see no violation of a constrant.

The Technical Information Bulletin #1 (RFI #31) issued by x3j11 makes it
clear that it is x3j11's interpretation that this contains a constraint
violation (of the second constraint given in 3.4).

+>-----------------------------------------------------------------------------
+>#3)  GCC incorrectly flags an error on the following standard-conformant code
+>     when the -pedantic-errors option is in effect.
+>typedef int T;
+>void test_1 (int T) { }
+
+Spurious diagnostics are allowed.

Correct.  This is a "quality of implementation" issue.  The code is conformant,
so I believe that most users would prefer *not* to have a diagnostic.

+>-----------------------------------------------------------------------------
+>#4)  On x86 machines, GCC fails to properly implement explicit floating-point
+>     casts of those floating-point expressions which get evaluated using the
+>     (internal) 80-bit floating-point format.
+
+This might well be true, but your example didn't test for it.  You only cast
+a double operand to type double.

This is an interesting point.  The "nominal" type of and expression like
`x*x' (where `x' has type double) is `double' but the standard explicitly
allows the evaluation of such an expression to be performed using some
wider flotaing-point data type.  This is exactly what occurs on x86 machines.
Floating-point expressions are generally evaluated using the FP registers,
and those registers in effect hold type `long double' values.  So on an
x86 machine, the expression `x*x' actually has type `long double'.  Readers
interested in further information on this topic are advised to obtain the
"Floating Point C Extensions" document from x3j11.1, as it goes into far
more detail in describing existing implementations.

+>-----------------------------------------------------------------------------
+>#5)  GCC incorrectly issues an error for the following standard-conformant
+>     code.  (Note that `wchar_t' is the same as type `long int' on i486-svr4.)
+>typedef long int wchar_t;
+>wchar_t array5[4] = L"abcd";
+
+This is a tough call.  ANSI Classic section 4.1.5 says that <stddef.h> defines
+the type wchar_t...

Norman has incorrectly presumed that GCC's error in this case has something
to do with the definition of the type `wchar_t'.  In fact that is entirely
besides the point.  The above code is accepted by GCC 2.3.3 if the explicit
array size is changed from `4' to `5'.  I hope that clarifies what the
actual problem is.

+>-----------------------------------------------------------------------------
+>#6)  The following erroneous code causes GCC to crash with a signal 6.
+>extern volatile struct s evs;
+>void evs_test () { evs; }
+
+The standard doesn't require diagnostics to be in a natural human language :-)

Correct.  As I noted above, exploding video monitors may be considered to
be valid diagnostics according to the ANSI C standard.  Unfortunately, I have
yet to develop a programmatic method (for use in my test suite) to determine
unambiguously whether or not my workstation monitor has exploded.

+>-----------------------------------------------------------------------------
+>#7)  When compiling an empty source file while the -pedantic-errors option
+>     is in effect, GCC will generate an error message for a line number which
+>     does not actually exist in the source file.
+
+I believe that diagnostics are allowed to contain spurious line numbers...

Correct.  This is another "quality of implementation" issue.

+>-----------------------------------------------------------------------------
+>#8)  GCC [-pedantic-errors] fails to issue errors for the following
+>void test_0 (char);
+>void test_0 (c) char c; { }
+
+Again (as in #1) I see no violation of a constraint.

See ANSI section 3.5, third paragraph in the "constraints" section.

+>-----------------------------------------------------------------------------
+>#9)  GCC fails to issue errors in cases where a static function is referenced
+>     but never defined, even when the -pedantic-errors option is used.
+>static void s (); int main () { s (); return 1; }
+
+Again I see no violation of a constraint.

See ANSI section 3.7, second paragraph in the "constraints" section.

+>-----------------------------------------------------------------------------
+>#10)  GCC [-pedantic-errors] fails to issue an error for the following invalid
+>void (*func_ptr) ();
+>int i;
+>void test () { func_ptr = i ? 0 : 0; }         /* ERROR */
+
+The code looks valid to me.  The conditional expression  i ? 0 : 0  is an
+integral constant expression with value 0.

No.  It isn't.  It also doesn't qualify as a null pointer constant.  Thus,
the constraint given in 3.3.16.1 applies to this case.

+>-----------------------------------------------------------------------------
+>#11)  GCC fails to issue errors for the following invalid C code involving
+>      comparison operators, even when the -pedantic-errors option is used.
+[Much editing by N.D.]
+ int b_array_src[3];
+ extern int u_array_src[];
+>int i;
+>void test_relational_operators () {
+>  i = & u_array_src > & b_array_src;            /* ERROR */
+>}
+>int u_array_src[20] = { 0 };    /* complete its type */
+
+Hmm, we agree that GCC failed to conform this time...

Good.

+>-----------------------------------------------------------------------------
+>#12)  GCC fails to issue errors for the following invalid C code involving
+>      the binary `-' operator, even when the -pedantic-errors option is used.
+[Declarations similar to #11.]
+>  i = & u_array_src - & b_array_src;            /* ERROR */
+
+... Again, we agree that GCC failed to conform.

Good.

+>-----------------------------------------------------------------------------
+>#13)  GCC fails to issue errors for the following invalid C code involving
+>      invalid null pointer constants, even when the -pedantic-errors option
+>int (*fp) ();
+>void test () { fp = (void *) (void *) 0; }    /* ERROR */
+
+... we agree that GCC failed.

Good.

+>-----------------------------------------------------------------------------
+>#14)  GCC [-pedantic-errors] fails to issue errors for the following invalid
+[Declarations deleted but all had pointer types, i.e. all scalars -- N.D.]
+>  p_to_func_value = (p_to_func_type) p_to_object_value;         /* ERROR */
+>  p_to_func_value = (p_to_func_type) p_to_incomp1_value;        /* ERROR */
+>  p_to_func_value = (p_to_func_type) p_to_incomp2_value;        /* ERROR */
+
+I see no violation of a constraint.

Quite so.  This was a mistake on my part.  The behavior is undefined for
this case, and I'm moving the test file to my "undefined behavior" pile.

+>-----------------------------------------------------------------------------
+>#15)  GCC [-pedantic-errors] fails to issue errors for the following invalid
+[Declarations deleted but all had pointer types, i.e. all scalars -- N.D.]
+>  p_to_object_value = (p_to_object_type) p_to_func_value;       /* ERROR */
+>  p_to_incomp1_value = (p_to_incomp1_type) p_to_func_value;     /* ERROR */
+>  p_to_incomp2_value = (p_to_incomp2_type) p_to_func_value;     /* ERROR */
+
+Ditto.  [s/function call/arithmetic/.]

Quite so.  This was a mistake on my part.  The behavior is undefined for
this case, and I'm moving the test file to my "undefined behavior" pile.

+>-----------------------------------------------------------------------------
+>#16)  GCC [-pedantic-errors] fails to issue errors for the following invalid
+>static int object_decl_6;
+>static int object_defn_6 = 0;
+>void test () {
+>    extern double object_decl_6;                /* ERROR */
+>    extern double object_defn_6;                /* ERROR */
+>}
+
+As in #1, I see no violation of a constraint.  The behavior is undefined but
+silence is allowed.

Agreed.  I have moved this test case to my "undefined behavior" pile.

+>-----------------------------------------------------------------------------
+>#17)  GCC [-pedantic-errors] fails to issue errors for the following invalid
+>void callee (char c);
+>void foobar () { void callee(); }     /* ERROR */
+>void callee (char c) { }
+
+Ditto.

Agreed.  I have moved this test case to my "undefined behavior" pile.

+>-----------------------------------------------------------------------------
+>#18)  GCC incorrectly issues an error for the following standard-conformant
+>      ANSI C code when the -pedantic-errors option is used.
+>extern const int func_1 ();
+
+Spurious diagnostics are allowed...

Quite so.  This is another "quality of implementation" issue.

+>-----------------------------------------------------------------------------
+>#19)  GCC fails to issue an error for the following pair of incompatible
+>      function declarations, even when the -pedantic-errors option is used.
+>extern const int func_4 ();
+>extern int func_4 ();                   /* ERROR */
+
+For the fourth time, this does not violate a constraint.

In this case Norman, you are wrong.  This violates the third constraint
listed in section 3.5.

+>-----------------------------------------------------------------------------
+>#20)  GCC incorrectly issues errors for the following standard-conformant
+>      ANSI C code when the -pedantic-errors option is used.
+>static enum E1 { red, green, blue};
+>static struct S1 { int member; };
+>static union U2 { int member; };
+>void foobar () {
+>	auto enum E2 { red, green, blue };
+>	auto struct S2 { int member; };
+>	auto union U2 { int member; };
+>}
+
+Spurious diagnostics are allowed...

Agreed.  This is another "quality of implementation" issue.


// Ron ("Loose Cannon") Guilmette    uucp: ...uunet!lupine!segfault!rfg
//
//      "On the one hand I knew that programs could have a compelling
//       and deep logical beauty, on the other hand I was forced to
//       admit that most programs are presented in a way fit for
//       mechanical execution, but even if of any beauty at all,
//       totally unfit for human appreciation."
//                                              -- Edsger W. Dijkstra
-- 

// Ron ("Loose Cannon") Guilmette    uucp: ...uunet!lupine!segfault!rfg
//
//      "On the one hand I knew that programs could have a compelling
//       and deep logical beauty, on the other hand I was forced to
//       admit that most programs are presented in a way fit for
//       mechanical execution, but even if of any beauty at all,
//       totally unfit for human appreciation."
//                                              -- Edsger W. Dijkstra
Newsgroups: comp.std.c,comp.lang.c