Skip to content

Compiler errors without column #9683

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

matthijskooijman
Copy link
Collaborator

Error messages are detected and parsed using a regex. Part of this regex
matches the optional column number.

The code that handled this assumed that a missing column would result in
less elements in the matches array, but a regex always results in one
element per set of parenthesis in the regex, which will be null if no
capture was made for that element.

In practice, this meant that if no column was present in the error
message, a NullPointerException would be raised. Furthermore, gcc 9
seems to have started outputting omitting column numbers (instead of
printing 0) for some errors (such as unterminated #ifdef), which exposed
this problem.

To reproduce, install a core that uses gcc 9, such as Arduino_Core_STM32, select a board from that core and compile any sketch that contains in unterminated ifdef, e.g.:

#ifdef FOO
void setup() { }
void loop() { }

On AVR, this results in:

sketch_jan29a:1:0: error: unterminated #ifdef
 #ifdef FOO
 ^
exit status 1
unterminated #ifdef

On STM32, I get:

    1 | #ifdef FOO
      | 
Using library SrcWrapper at version 1.0.1 in folder: /home/matthijs/.arduino15/packages/STM32/hardware/stm32/1.8.0/libraries/SrcWrapper 
exit status 1
processing.app.debug.RunnerException
	at cc.arduino.Compiler.lambda$callArduinoBuilder$3(Compiler.java:309)
	at processing.app.debug.MessageSiphon.run(MessageSiphon.java:96)
	at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.NullPointerException
	at cc.arduino.Compiler.message(Compiler.java:525)
	at cc.arduino.i18n.I18NAwareMessageConsumer.message(I18NAwareMessageConsumer.java:80)
	at cc.arduino.MessageConsumerOutputStream.flush(MessageConsumerOutputStream.java:71)
	at cc.arduino.MessageConsumerOutputStream.write(MessageConsumerOutputStream.java:54)
	at java.base/java.io.OutputStream.write(OutputStream.java:122)
	at cc.arduino.Compiler.lambda$callArduinoBuilder$3(Compiler.java:307)
	... 2 more

Note the missing error message, only the quoted source lines for the error are present. gcc-9 also changed the way it indicates source lines using a | prefix, but that is handled just fine.

A second problem is that "fatal" would be stripped from error messages. e.g.

matthijs@grubby:~$ cat foo.cpp 
#include <asdf.h>
matthijs@grubby:~$ gcc foo.cpp 
foo.cpp:1:10: fatal error: asdf: No such file or directory
 #include <asdf.h>
          ^~~~~~
compilation terminated.

But compiling the same line in the IDE (using the AVR core) gives:

sketch_jan29a:1:10: error: asdf.h: No such file or directoryAlternatives for asdf.h: []
 #include <asdf.h>
          ^~~~~~~~
compilation terminated.

Note the missing "fatal". There is also some intermixing of stdout and stderr, but that is a separate issue.

This PR fixes both problems by improving the compiler error message parsing. See the commit messages for implementation details.

With this PR, columless error message are shown properly (below with the STM32 core):

sketch_jan29a:1: error: unterminated #ifdef
    1 | #ifdef FOO
      | 

Also, fatal errors are now again shown as such (below uses the AVR core again):

sketch_jan29a:1:10: fatal error: asdf.h: No such file or directory
 #include <asdf.h>
          ^~~~~~~~
compilation terminated.

Error messages are detected and parsed using a regex. Part of this regex
matches the optional column number.

The code that handled this assumed that a missing column would result in
less elements in the matches array, but a regex always results in one
element per set of parenthesis in the regex, which will be null if no
capture was made for that element.

In practice, this meant that if no column was present in the error
message, a NullPointerException would be raised. Furthermore, gcc 9
seems to have started outputting omitting column numbers (instead of
printing 0) for some errors (such as unterminated #ifdef), which exposed
this problem.

This commit fixes this by simply using the fixed match numbers to take
apart the regex match, and by checking for a null column number (all
other captures are non-optional, so no need to check there).
This removes some duplicate code for with and without column number by
building the column number string separately first.
When transforming compiler errors (to make filenames more friendly), it
would match "fatal error" or "error" but then always reconstruct as
"error", modifying the compiler error in a way that is not intended.

This commit fixes that, as well as the previous hardcoding of the
"error: " prefix when rebuilding the error message, by capturing this
entire prefix and simply reproducing it in the resulting error message.
@facchinm
Copy link
Member

Tested, works perfectly, thanks a lot!

@facchinm facchinm merged commit 88fa134 into arduino:master Jan 30, 2020
@cmaglie cmaglie added this to the Release 1.8.12 milestone Feb 6, 2020
@cmaglie cmaglie added Component: IDE The Arduino IDE Type: Bug labels Feb 6, 2020
@matthijskooijman matthijskooijman deleted the compiler-errors-without-column branch March 28, 2020 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants