Bug 23693 – ImportC: Unclear documentation of #line and linemarker support

Status
RESOLVED
Resolution
WONTFIX
Severity
major
Priority
P2
Component
dlang.org
Product
D
Version
D2
Platform
All
OS
Linux
Creation time
2023-02-12T14:49:40Z
Last change time
2023-12-05T10:30:45Z
Keywords
accepts-invalid, ImportC
Assigned to
No Owner
Creator
Iain Buclaw
Depends on
23689
See also
https://issues.dlang.org/show_bug.cgi?id=23689

Comments

Comment #0 by ibuclaw — 2023-02-12T14:49:40Z
When compiling the test with `gcc -std=c11 -fsyntax-only` compilable/testcstuff3.i:7:1: error: stray ‘#’ in program 7 | #line 1050 "cstuff3.c" extra tokens ignored (should warn?) | ^ compilable/testcstuff3.i:7:7: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before numeric constant 7 | #line 1050 "cstuff3.c" extra tokens ignored (should warn?) | ^~~~ compilable/testcstuff3.i:10:1: error: stray ‘#’ in program 10 | #line 1000 | ^ compilable/testcstuff3.i:11:1: error: stray ‘%:’ in program 11 | %:line 1010 | ^~ compilable/testcstuff3.i:13:22: error: invalid flag "2" in line directive 13 | # 1020 "cstuff3.c" 1 2 3 4 | ^ compilable/testcstuff3.i:13:24: warning: extra tokens at end of ## directive 13 | # 1020 "cstuff3.c" 1 2 3 4 | ^ Original test content: ``` /* cpp doesn't like this, so don't run preprocessor on this file */ /********************************/ #line 1050 "cstuff3.c" extra tokens ignored (should warn?) #line 1000 %:line 1010 # 1020 "cstuff3.c" 1 2 3 4 # 1030 struct S21944 { int var; #1040 "cstuff3.c" 3 4 }; _Static_assert(U'\U00011234' == 0x11234, "ok"); // sppn.exe doesn't support U character literals ```
Comment #1 by ibuclaw — 2023-02-16T22:21:34Z
The discrepancy here between GCC and ImportC is that ImportC recognizes and parses `#line` directives. In GCC `#line` is a CPP-only directive, instead replaces them all with gcc-specific linemarkers. The linemarker tests in the testsuite are not representative of real line markers emitted from gcc, hence why they fail.
Comment #2 by bugzilla — 2023-02-20T06:53:08Z
linemarkers are a gcc extension, not a standard: https://gcc.gnu.org/onlinedocs/gcc-11.1.0/cpp/Preprocessor-Output.html Microsoft's preprocessor generates #line linemarkers, too. ImportC has to work with the output of C preprocessors other than gcc's. There's not much I can do about that. I recommend gcc simply not run those tests.
Comment #3 by ibuclaw — 2023-02-20T10:52:51Z
(In reply to Walter Bright from comment #2) > ImportC has to work with the output of C preprocessors other than gcc's. > There's not much I can do about that. I recommend gcc simply not run those > tests. The point of this is to find code that is not valid C. Be it because the standard says it's not supported, or it's a vendor-specific extension of C that we're testing in the wrong way. After all if they reject the way we're testing their own extensions, maybe we should reject them too. The ImportC documentation is pretty scant on actually saying what is accepted. https://dlang.org/spec/importc.html#preprocessor-directives Perhaps obvious enough to close this as wontfix (though I'd prefer to fix the GCC linemarker tests so they are *valid* examples of lines the preprocessor will pipe to ImportC). But not obvious enough that they are accepted even if there's been no preprocessing done on the input file. Maybe a couple examples of what forms of #line directive and linemarker are supported - same as the #pragma paragraph.
Comment #4 by bugzilla — 2023-12-04T07:43:56Z
There are two different things: 1. #line directives described as part of the preprocessing pass, in C11 6.10.4. They were asked for for D, and I didn't see an issue with leaving them in for C. 2. linemarkers The linemarker tests: # 1020 "cstuff3.c" 1 2 3 4 conform to gcc's specification of them: "After the file name comes zero or more flags, which are ‘1’, ‘2’, ‘3’, or ‘4’. If there are multiple flags, spaces separate them." https://gcc.gnu.org/onlinedocs/gcc-11.1.0/cpp/Preprocessor-Output.html gcc does indeed barf on more than one flag, but that's a bug in gcc, according to gcc's spec. Both are documented by referring to the respective documents for them. I don't want to write an equivalent specification that is identical but different in order to avoid copyright issues. And, lastly, the test suite is for testing ImportC, not for testing gcc. Although your work in running them through gcc is valuable and has uncovered problems with ImportC, and I appreciate your efforts in doing this. I'm going to mark this as wontfix.
Comment #5 by ibuclaw — 2023-12-05T10:30:45Z
(In reply to Walter Bright from comment #4) > There are two different things: > > 1. #line directives described as part of the preprocessing pass, in C11 > 6.10.4. They were asked for for D, and I didn't see an issue with leaving > them in for C. > > 2. linemarkers > > The linemarker tests: > > # 1020 "cstuff3.c" 1 2 3 4 > > conform to gcc's specification of them: > > "After the file name comes zero or more flags, which are ‘1’, ‘2’, ‘3’, or > ‘4’. If there are multiple flags, spaces separate them." > > https://gcc.gnu.org/onlinedocs/gcc-11.1.0/cpp/Preprocessor-Output.html > > gcc does indeed barf on more than one flag, but that's a bug in gcc, > according to gcc's spec. > There is no spec on them. Line markers are machine-generated code inserted into the preprocessed source file, human-written tests don't make much sense to be present in the testsuite unless they are the product of copying from a compiler generated `.i` file.